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

Side by Side Diff: net/quic/core/quic_received_packet_manager.cc

Issue 2515613002: deprecate FLAGS_quic_disable_pre_34 (Closed)
Patch Set: Created 4 years, 1 month 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/core/quic_received_packet_manager.h" 5 #include "net/quic/core/quic_received_packet_manager.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 13 matching lines...) Expand all
24 namespace { 24 namespace {
25 25
26 // The maximum number of packets to ack immediately after a missing packet for 26 // The maximum number of packets to ack immediately after a missing packet for
27 // fast retransmission to kick in at the sender. This limit is created to 27 // fast retransmission to kick in at the sender. This limit is created to
28 // reduce the number of acks sent that have no benefit for fast retransmission. 28 // reduce the number of acks sent that have no benefit for fast retransmission.
29 // Set to the number of nacks needed for fast retransmit plus one for protection 29 // Set to the number of nacks needed for fast retransmit plus one for protection
30 // against an ack loss 30 // against an ack loss
31 const size_t kMaxPacketsAfterNewMissing = 4; 31 const size_t kMaxPacketsAfterNewMissing = 4;
32 } 32 }
33 33
34 QuicReceivedPacketManager::EntropyTracker::EntropyTracker()
35 : packets_entropy_hash_(0), first_gap_(1), largest_observed_(0) {}
36
37 QuicReceivedPacketManager::EntropyTracker::~EntropyTracker() {}
38
39 QuicPacketEntropyHash QuicReceivedPacketManager::EntropyTracker::EntropyHash(
40 QuicPacketNumber packet_number) const {
41 DCHECK_LE(packet_number, largest_observed_);
42 if (packet_number == largest_observed_) {
43 return packets_entropy_hash_;
44 }
45
46 DCHECK_GE(packet_number, first_gap_);
47 DCHECK_EQ(first_gap_ + packets_entropy_.size() - 1, largest_observed_);
48 QuicPacketEntropyHash hash = packets_entropy_hash_;
49 ReceivedEntropyHashes::const_reverse_iterator it = packets_entropy_.rbegin();
50 for (QuicPacketNumber i = 0; i < (largest_observed_ - packet_number);
51 ++i, ++it) {
52 hash ^= it->first;
53 }
54 return hash;
55 }
56
57 void QuicReceivedPacketManager::EntropyTracker::RecordPacketEntropyHash(
58 QuicPacketNumber packet_number,
59 QuicPacketEntropyHash entropy_hash) {
60 if (packet_number < first_gap_) {
61 DVLOG(1) << "Ignoring received packet entropy for packet_number:"
62 << packet_number
63 << " less than largest_peer_packet_number:" << first_gap_;
64 return;
65 }
66 // RecordPacketEntropyHash is only intended to be called once per packet.
67 DCHECK(packet_number > largest_observed_ ||
68 !packets_entropy_[packet_number - first_gap_].second);
69
70 packets_entropy_hash_ ^= entropy_hash;
71
72 // Optimize the typical case of no gaps.
73 if (packet_number == largest_observed_ + 1 && packets_entropy_.empty()) {
74 ++first_gap_;
75 largest_observed_ = packet_number;
76 return;
77 }
78 if (packet_number > largest_observed_) {
79 for (QuicPacketNumber i = 0; i < (packet_number - largest_observed_ - 1);
80 ++i) {
81 packets_entropy_.push_back(std::make_pair(0, false));
82 }
83 packets_entropy_.push_back(std::make_pair(entropy_hash, true));
84 largest_observed_ = packet_number;
85 } else {
86 packets_entropy_[packet_number - first_gap_] =
87 std::make_pair(entropy_hash, true);
88 AdvanceFirstGapAndGarbageCollectEntropyMap();
89 }
90
91 DVLOG(2) << "setting cumulative received entropy hash to: "
92 << static_cast<int>(packets_entropy_hash_)
93 << " updated with packet number " << packet_number
94 << " entropy hash: " << static_cast<int>(entropy_hash);
95 }
96
97 void QuicReceivedPacketManager::EntropyTracker::SetCumulativeEntropyUpTo(
98 QuicPacketNumber packet_number,
99 QuicPacketEntropyHash entropy_hash) {
100 DCHECK_LE(packet_number, largest_observed_);
101 if (packet_number < first_gap_) {
102 DVLOG(1) << "Ignoring set entropy at:" << packet_number
103 << " less than first_gap_:" << first_gap_;
104 return;
105 }
106 while (first_gap_ < packet_number) {
107 ++first_gap_;
108 if (!packets_entropy_.empty()) {
109 packets_entropy_.pop_front();
110 }
111 }
112 // Compute the current entropy by XORing in all entropies received including
113 // and since packet_number.
114 packets_entropy_hash_ = entropy_hash;
115 for (ReceivedEntropyHashes::const_iterator it = packets_entropy_.begin();
116 it != packets_entropy_.end(); ++it) {
117 packets_entropy_hash_ ^= it->first;
118 }
119
120 // Garbage collect entries from the beginning of the map.
121 AdvanceFirstGapAndGarbageCollectEntropyMap();
122 }
123
124 void QuicReceivedPacketManager::EntropyTracker::
125 AdvanceFirstGapAndGarbageCollectEntropyMap() {
126 while (!packets_entropy_.empty() && packets_entropy_.front().second) {
127 ++first_gap_;
128 packets_entropy_.pop_front();
129 }
130 }
131
132 QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats) 34 QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
133 : peer_least_packet_awaiting_ack_(0), 35 : peer_least_packet_awaiting_ack_(0),
134 ack_frame_updated_(false), 36 ack_frame_updated_(false),
135 time_largest_observed_(QuicTime::Zero()), 37 time_largest_observed_(QuicTime::Zero()),
136 stats_(stats) { 38 stats_(stats) {
137 ack_frame_.largest_observed = 0; 39 ack_frame_.largest_observed = 0;
138 ack_frame_.entropy_hash = 0;
139 } 40 }
140 41
141 QuicReceivedPacketManager::~QuicReceivedPacketManager() {} 42 QuicReceivedPacketManager::~QuicReceivedPacketManager() {}
142 43
143 void QuicReceivedPacketManager::RecordPacketReceived( 44 void QuicReceivedPacketManager::RecordPacketReceived(
144 const QuicPacketHeader& header, 45 const QuicPacketHeader& header,
145 QuicTime receipt_time) { 46 QuicTime receipt_time) {
146 QuicPacketNumber packet_number = header.packet_number; 47 QuicPacketNumber packet_number = header.packet_number;
147 DCHECK(IsAwaitingPacket(packet_number)) << " packet_number:" << packet_number; 48 DCHECK(IsAwaitingPacket(packet_number)) << " packet_number:" << packet_number;
148 if (!ack_frame_updated_) { 49 if (!ack_frame_updated_) {
149 ack_frame_.received_packet_times.clear(); 50 ack_frame_.received_packet_times.clear();
150 } 51 }
151 ack_frame_updated_ = true; 52 ack_frame_updated_ = true;
152 if (ack_frame_.missing) { 53 ack_frame_.packets.Add(header.packet_number);
153 // Adds the range of packet numbers from max(largest observed + 1, least
154 // awaiting ack) up to packet_number not including packet_number.
155 ack_frame_.packets.Add(
156 max(ack_frame_.largest_observed + 1, peer_least_packet_awaiting_ack_),
157 packet_number);
158 } else {
159 ack_frame_.packets.Add(header.packet_number);
160 }
161 54
162 if (ack_frame_.largest_observed > packet_number) { 55 if (ack_frame_.largest_observed > packet_number) {
163 if (ack_frame_.missing) {
164 // We've gotten one of the out of order packets - remove it from our
165 // "missing packets" list.
166 DVLOG(1) << "Removing " << packet_number << " from missing list";
167 ack_frame_.packets.Remove(packet_number);
168 }
169
170 // Record how out of order stats. 56 // Record how out of order stats.
171 ++stats_->packets_reordered; 57 ++stats_->packets_reordered;
172 stats_->max_sequence_reordering = 58 stats_->max_sequence_reordering =
173 max(stats_->max_sequence_reordering, 59 max(stats_->max_sequence_reordering,
174 ack_frame_.largest_observed - packet_number); 60 ack_frame_.largest_observed - packet_number);
175 int64_t reordering_time_us = 61 int64_t reordering_time_us =
176 (receipt_time - time_largest_observed_).ToMicroseconds(); 62 (receipt_time - time_largest_observed_).ToMicroseconds();
177 stats_->max_time_reordering_us = 63 stats_->max_time_reordering_us =
178 max(stats_->max_time_reordering_us, reordering_time_us); 64 max(stats_->max_time_reordering_us, reordering_time_us);
179 } 65 }
180 if (packet_number > ack_frame_.largest_observed) { 66 if (packet_number > ack_frame_.largest_observed) {
181 ack_frame_.largest_observed = packet_number; 67 ack_frame_.largest_observed = packet_number;
182 time_largest_observed_ = receipt_time; 68 time_largest_observed_ = receipt_time;
183 } 69 }
184 if (ack_frame_.missing) {
185 entropy_tracker_.RecordPacketEntropyHash(packet_number,
186 header.entropy_hash);
187 }
188 70
189 ack_frame_.received_packet_times.push_back( 71 ack_frame_.received_packet_times.push_back(
190 std::make_pair(packet_number, receipt_time)); 72 std::make_pair(packet_number, receipt_time));
191 } 73 }
192 74
193 bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) { 75 bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
194 if (ack_frame_.missing) {
195 return ack_frame_.packets.Contains(packet_number);
196 }
197 return packet_number < ack_frame_.largest_observed && 76 return packet_number < ack_frame_.largest_observed &&
198 !ack_frame_.packets.Contains(packet_number); 77 !ack_frame_.packets.Contains(packet_number);
199 } 78 }
200 79
201 bool QuicReceivedPacketManager::IsAwaitingPacket( 80 bool QuicReceivedPacketManager::IsAwaitingPacket(
202 QuicPacketNumber packet_number) { 81 QuicPacketNumber packet_number) {
203 return ::net::IsAwaitingPacket(ack_frame_, packet_number, 82 return ::net::IsAwaitingPacket(ack_frame_, packet_number,
204 peer_least_packet_awaiting_ack_); 83 peer_least_packet_awaiting_ack_);
205 } 84 }
206 85
207 namespace { 86 namespace {
208 struct isTooLarge { 87 struct isTooLarge {
209 explicit isTooLarge(QuicPacketNumber n) : largest_observed_(n) {} 88 explicit isTooLarge(QuicPacketNumber n) : largest_observed_(n) {}
210 QuicPacketNumber largest_observed_; 89 QuicPacketNumber largest_observed_;
211 90
212 // Return true if the packet in p is too different from largest_observed_ 91 // Return true if the packet in p is too different from largest_observed_
213 // to express. 92 // to express.
214 bool operator()(const std::pair<QuicPacketNumber, QuicTime>& p) const { 93 bool operator()(const std::pair<QuicPacketNumber, QuicTime>& p) const {
215 return largest_observed_ - p.first >= std::numeric_limits<uint8_t>::max(); 94 return largest_observed_ - p.first >= std::numeric_limits<uint8_t>::max();
216 } 95 }
217 }; 96 };
218 } // namespace 97 } // namespace
219 98
220 const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame( 99 const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame(
221 QuicTime approximate_now) { 100 QuicTime approximate_now) {
222 ack_frame_updated_ = false; 101 ack_frame_updated_ = false;
223 if (ack_frame_.missing) {
224 ack_frame_.entropy_hash = EntropyHash(ack_frame_.largest_observed);
225 }
226
227 if (time_largest_observed_ == QuicTime::Zero()) { 102 if (time_largest_observed_ == QuicTime::Zero()) {
228 // We have received no packets. 103 // We have received no packets.
229 ack_frame_.ack_delay_time = QuicTime::Delta::Infinite(); 104 ack_frame_.ack_delay_time = QuicTime::Delta::Infinite();
230 } else { 105 } else {
231 // Ensure the delta is zero if approximate now is "in the past". 106 // Ensure the delta is zero if approximate now is "in the past".
232 ack_frame_.ack_delay_time = approximate_now < time_largest_observed_ 107 ack_frame_.ack_delay_time = approximate_now < time_largest_observed_
233 ? QuicTime::Delta::Zero() 108 ? QuicTime::Delta::Zero()
234 : approximate_now - time_largest_observed_; 109 : approximate_now - time_largest_observed_;
235 } 110 }
236 111
237 // Clear all packet times if any are too far from largest observed. 112 // Clear all packet times if any are too far from largest observed.
238 // It's expected this is extremely rare. 113 // It's expected this is extremely rare.
239 for (PacketTimeVector::iterator it = ack_frame_.received_packet_times.begin(); 114 for (PacketTimeVector::iterator it = ack_frame_.received_packet_times.begin();
240 it != ack_frame_.received_packet_times.end();) { 115 it != ack_frame_.received_packet_times.end();) {
241 if (ack_frame_.largest_observed - it->first >= 116 if (ack_frame_.largest_observed - it->first >=
242 std::numeric_limits<uint8_t>::max()) { 117 std::numeric_limits<uint8_t>::max()) {
243 it = ack_frame_.received_packet_times.erase(it); 118 it = ack_frame_.received_packet_times.erase(it);
244 } else { 119 } else {
245 ++it; 120 ++it;
246 } 121 }
247 } 122 }
248 123
249 return QuicFrame(&ack_frame_); 124 return QuicFrame(&ack_frame_);
250 } 125 }
251 126
252 QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash(
253 QuicPacketNumber packet_number) const {
254 return entropy_tracker_.EntropyHash(packet_number);
255 }
256
257 bool QuicReceivedPacketManager::DontWaitForPacketsBefore( 127 bool QuicReceivedPacketManager::DontWaitForPacketsBefore(
258 QuicPacketNumber least_unacked) { 128 QuicPacketNumber least_unacked) {
259 peer_least_packet_awaiting_ack_ = least_unacked; 129 peer_least_packet_awaiting_ack_ = least_unacked;
260 return ack_frame_.packets.RemoveUpTo(least_unacked); 130 return ack_frame_.packets.RemoveUpTo(least_unacked);
261 } 131 }
262 132
263 void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer( 133 void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer(
264 const QuicStopWaitingFrame& stop_waiting) { 134 const QuicStopWaitingFrame& stop_waiting) {
265 // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks. 135 // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks.
266 DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked); 136 DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked);
267 if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) { 137 if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) {
268 bool packets_updated = DontWaitForPacketsBefore(stop_waiting.least_unacked); 138 bool packets_updated = DontWaitForPacketsBefore(stop_waiting.least_unacked);
269 if (packets_updated) { 139 if (packets_updated) {
270 if (ack_frame_.missing) {
271 DVLOG(1) << "Updating entropy hashed since we missed packets";
272 // There were some missing packets that we won't ever get now.
273 // Recalculate the received entropy hash.
274 entropy_tracker_.SetCumulativeEntropyUpTo(stop_waiting.least_unacked,
275 stop_waiting.entropy_hash);
276 }
277 // Ack frame gets updated because packets set is updated because of stop 140 // Ack frame gets updated because packets set is updated because of stop
278 // waiting frame. 141 // waiting frame.
279 ack_frame_updated_ = true; 142 ack_frame_updated_ = true;
280 } 143 }
281 } 144 }
282 DCHECK(ack_frame_.packets.Empty() || 145 DCHECK(ack_frame_.packets.Empty() ||
283 ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_); 146 ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_);
284 } 147 }
285 148
286 bool QuicReceivedPacketManager::HasMissingPackets() const { 149 bool QuicReceivedPacketManager::HasMissingPackets() const {
287 if (ack_frame_.missing) {
288 return !ack_frame_.packets.Empty();
289 }
290
291 return ack_frame_.packets.NumIntervals() > 1 || 150 return ack_frame_.packets.NumIntervals() > 1 ||
292 (!ack_frame_.packets.Empty() && 151 (!ack_frame_.packets.Empty() &&
293 ack_frame_.packets.Min() > 152 ack_frame_.packets.Min() >
294 max(QuicPacketNumber(1), peer_least_packet_awaiting_ack_)); 153 max(QuicPacketNumber(1), peer_least_packet_awaiting_ack_));
295 } 154 }
296 155
297 bool QuicReceivedPacketManager::HasNewMissingPackets() const { 156 bool QuicReceivedPacketManager::HasNewMissingPackets() const {
298 if (ack_frame_.missing) {
299 return !ack_frame_.packets.Empty() &&
300 (ack_frame_.largest_observed - ack_frame_.packets.Max()) <=
301 kMaxPacketsAfterNewMissing;
302 }
303
304 return HasMissingPackets() && 157 return HasMissingPackets() &&
305 ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing; 158 ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing;
306 } 159 }
307 160
308 size_t QuicReceivedPacketManager::NumTrackedPackets() const {
309 return entropy_tracker_.size();
310 }
311
312 void QuicReceivedPacketManager::SetVersion(QuicVersion version) {
313 ack_frame_.missing = version <= QUIC_VERSION_33;
314 }
315
316 bool QuicReceivedPacketManager::ack_frame_updated() const { 161 bool QuicReceivedPacketManager::ack_frame_updated() const {
317 return ack_frame_updated_; 162 return ack_frame_updated_;
318 } 163 }
319 164
320 QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const { 165 QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const {
321 return ack_frame_.largest_observed; 166 return ack_frame_.largest_observed;
322 } 167 }
323 168
324 } // namespace net 169 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_received_packet_manager.h ('k') | net/quic/core/quic_received_packet_manager_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698