Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: net/quic/quic_fec_group.cc

Issue 2011653004: Remove obsolete fields in quic_protocol and their current usage in QUIC. Reorders QuicAckFrame fie… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@122721477
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_fec_group.h ('k') | net/quic/quic_fec_group_interface.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_fec_group.h"
6
7 #include <limits>
8
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11
12 using base::StringPiece;
13 using std::numeric_limits;
14 using std::set;
15
16 namespace net {
17
18 QuicFecGroup::QuicFecGroup(QuicPacketNumber fec_group_number)
19 : QuicFecGroupInterface(),
20 min_protected_packet_(fec_group_number),
21 max_protected_packet_(kInvalidPacketNumber),
22 payload_parity_len_(0),
23 effective_encryption_level_(NUM_ENCRYPTION_LEVELS) {}
24
25 QuicFecGroup::~QuicFecGroup() {}
26
27 bool QuicFecGroup::Update(EncryptionLevel encryption_level,
28 const QuicPacketHeader& header,
29 StringPiece decrypted_payload) {
30 DCHECK_EQ(min_protected_packet_, header.fec_group);
31 DCHECK_NE(kInvalidPacketNumber, header.packet_number);
32 if (ContainsKey(received_packets_, header.packet_number)) {
33 return false;
34 }
35 if (header.packet_number < min_protected_packet_ ||
36 (has_received_fec_packet() &&
37 header.packet_number > max_protected_packet_)) {
38 DLOG(ERROR) << "FEC group does not cover received packet: "
39 << header.packet_number;
40 return false;
41 }
42 if (!UpdateParity(decrypted_payload)) {
43 return false;
44 }
45 received_packets_.insert(header.packet_number);
46 if (encryption_level < effective_encryption_level_) {
47 effective_encryption_level_ = encryption_level;
48 }
49 return true;
50 }
51
52 bool QuicFecGroup::UpdateFec(EncryptionLevel encryption_level,
53 const QuicPacketHeader& header,
54 StringPiece redundancy) {
55 DCHECK_EQ(min_protected_packet_, header.fec_group);
56 DCHECK_NE(kInvalidPacketNumber, header.packet_number);
57 if (has_received_fec_packet()) {
58 return false;
59 }
60 for (QuicPacketNumber packet : received_packets_) {
61 if (packet >= header.packet_number) {
62 DLOG(ERROR) << "FEC group does not cover received packet: " << packet;
63 return false;
64 }
65 }
66 if (!UpdateParity(redundancy)) {
67 return false;
68 }
69 max_protected_packet_ = header.packet_number - 1;
70 if (encryption_level < effective_encryption_level_) {
71 effective_encryption_level_ = encryption_level;
72 }
73 return true;
74 }
75
76 bool QuicFecGroup::CanRevive() const {
77 // We can revive if we're missing exactly 1 packet.
78 return NumMissingPackets() == 1;
79 }
80
81 bool QuicFecGroup::IsFinished() const {
82 // We are finished if we are not missing any packets.
83 return NumMissingPackets() == 0;
84 }
85
86 size_t QuicFecGroup::Revive(QuicPacketHeader* header,
87 char* decrypted_payload,
88 size_t decrypted_payload_len) {
89 if (!CanRevive()) {
90 return 0;
91 }
92
93 // Identify the packet number to be resurrected.
94 QuicPacketNumber missing = kInvalidPacketNumber;
95 for (QuicPacketNumber i = min_protected_packet_; i <= max_protected_packet_;
96 ++i) {
97 // Is this packet missing?
98 if (received_packets_.count(i) == 0) {
99 missing = i;
100 break;
101 }
102 }
103 DCHECK_NE(kInvalidPacketNumber, missing);
104
105 DCHECK_LE(payload_parity_len_, decrypted_payload_len);
106 if (payload_parity_len_ > decrypted_payload_len) {
107 return 0;
108 }
109 for (size_t i = 0; i < payload_parity_len_; ++i) {
110 decrypted_payload[i] = payload_parity_[i];
111 }
112
113 header->packet_number = missing;
114 header->entropy_flag = false; // Unknown entropy.
115
116 received_packets_.insert(missing);
117 return payload_parity_len_;
118 }
119
120 bool QuicFecGroup::IsWaitingForPacketBefore(QuicPacketNumber num) const {
121 // Entire range is larger than the threshold.
122 if (min_protected_packet_ >= num) {
123 return false;
124 }
125
126 // Entire range is smaller than the threshold.
127 if (received_packets_.size() > 0 ? *received_packets_.rbegin() + 1 < num
128 : min_protected_packet_ < num) {
129 return true;
130 }
131
132 // Range spans the threshold so look for a missing packet below the threshold.
133 QuicPacketNumber target = min_protected_packet_;
134 for (QuicPacketNumber packet : received_packets_) {
135 if (target++ != packet) {
136 return true;
137 }
138 if (target >= num) {
139 return false;
140 }
141 }
142
143 // No missing packets below the threshold.
144 return false;
145 }
146
147 bool QuicFecGroup::UpdateParity(StringPiece payload) {
148 DCHECK_GE(kMaxPacketSize, payload.size());
149 if (payload.size() > kMaxPacketSize) {
150 DLOG(ERROR) << "Illegal payload size: " << payload.size();
151 return false;
152 }
153 if (payload_parity_len_ < payload.size()) {
154 payload_parity_len_ = payload.size();
155 }
156 if (received_packets_.empty() && !has_received_fec_packet()) {
157 // Initialize the parity to the value of this payload
158 memcpy(payload_parity_, payload.data(), payload.size());
159 if (payload.size() < kMaxPacketSize) {
160 // TODO(rch): expand as needed.
161 memset(payload_parity_ + payload.size(), 0,
162 kMaxPacketSize - payload.size());
163 }
164 return true;
165 }
166 // Update the parity by XORing in the data (padding with 0s if necessary).
167 XorBuffers(payload.data(), payload.size(), payload_parity_);
168 return true;
169 }
170
171 QuicPacketCount QuicFecGroup::NumMissingPackets() const {
172 if (!has_received_fec_packet()) {
173 return numeric_limits<QuicPacketCount>::max();
174 }
175 return static_cast<QuicPacketCount>(
176 (max_protected_packet_ - min_protected_packet_ + 1) -
177 received_packets_.size());
178 }
179
180 const StringPiece QuicFecGroup::PayloadParity() const {
181 return StringPiece(payload_parity_, payload_parity_len_);
182 }
183
184 QuicPacketCount QuicFecGroup::NumReceivedPackets() const {
185 return received_packets_.size();
186 }
187
188 EncryptionLevel QuicFecGroup::EffectiveEncryptionLevel() const {
189 return effective_encryption_level_;
190 }
191
192 QuicFecGroupNumber QuicFecGroup::FecGroupNumber() const {
193 return min_protected_packet_;
194 }
195
196 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_fec_group.h ('k') | net/quic/quic_fec_group_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698