OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/quic_unacked_packet_map.h" | 5 #include "net/quic/quic_unacked_packet_map.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "net/quic/quic_connection_stats.h" | 9 #include "net/quic/quic_connection_stats.h" |
10 #include "net/quic/quic_utils_chromium.h" | 10 #include "net/quic/quic_utils_chromium.h" |
11 | 11 |
12 using std::max; | 12 using std::max; |
13 | 13 |
14 namespace net { | 14 namespace net { |
15 | 15 |
16 QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo() | 16 QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo() |
17 : retransmittable_frames(NULL), | 17 : retransmittable_frames(NULL), |
18 sequence_number_length(PACKET_1BYTE_SEQUENCE_NUMBER), | 18 sequence_number_length(PACKET_1BYTE_SEQUENCE_NUMBER), |
19 sent_time(QuicTime::Zero()), | 19 sent_time(QuicTime::Zero()), |
20 bytes_sent(0), | 20 bytes_sent(0), |
21 nack_count(0), | 21 nack_count(0), |
22 all_transmissions(NULL), | 22 all_transmissions(NULL), |
23 pending(false) { } | 23 pending(false) { |
| 24 } |
24 | 25 |
25 QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo( | 26 QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo( |
26 RetransmittableFrames* retransmittable_frames, | 27 RetransmittableFrames* retransmittable_frames, |
27 QuicPacketSequenceNumber sequence_number, | 28 QuicPacketSequenceNumber sequence_number, |
28 QuicSequenceNumberLength sequence_number_length) | 29 QuicSequenceNumberLength sequence_number_length) |
29 : retransmittable_frames(retransmittable_frames), | 30 : retransmittable_frames(retransmittable_frames), |
30 sequence_number_length(sequence_number_length), | 31 sequence_number_length(sequence_number_length), |
31 sent_time(QuicTime::Zero()), | 32 sent_time(QuicTime::Zero()), |
32 bytes_sent(0), | 33 bytes_sent(0), |
33 nack_count(0), | 34 nack_count(0), |
(...skipping 18 matching lines...) Expand all Loading... |
52 } | 53 } |
53 | 54 |
54 QuicUnackedPacketMap::QuicUnackedPacketMap() | 55 QuicUnackedPacketMap::QuicUnackedPacketMap() |
55 : largest_sent_packet_(0), | 56 : largest_sent_packet_(0), |
56 bytes_in_flight_(0), | 57 bytes_in_flight_(0), |
57 pending_crypto_packet_count_(0) { | 58 pending_crypto_packet_count_(0) { |
58 } | 59 } |
59 | 60 |
60 QuicUnackedPacketMap::~QuicUnackedPacketMap() { | 61 QuicUnackedPacketMap::~QuicUnackedPacketMap() { |
61 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); | 62 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); |
62 it != unacked_packets_.end(); ++it) { | 63 it != unacked_packets_.end(); |
| 64 ++it) { |
63 delete it->second.retransmittable_frames; | 65 delete it->second.retransmittable_frames; |
64 // Only delete all_transmissions once, for the newest packet. | 66 // Only delete all_transmissions once, for the newest packet. |
65 if (it->first == *it->second.all_transmissions->rbegin()) { | 67 if (it->first == *it->second.all_transmissions->rbegin()) { |
66 delete it->second.all_transmissions; | 68 delete it->second.all_transmissions; |
67 } | 69 } |
68 } | 70 } |
69 } | 71 } |
70 | 72 |
71 // TODO(ianswett): Combine this method with OnPacketSent once packets are always | 73 // TODO(ianswett): Combine this method with OnPacketSent once packets are always |
72 // sent in order and the connection tracks RetransmittableFrames for longer. | 74 // sent in order and the connection tracks RetransmittableFrames for longer. |
73 void QuicUnackedPacketMap::AddPacket( | 75 void QuicUnackedPacketMap::AddPacket( |
74 const SerializedPacket& serialized_packet) { | 76 const SerializedPacket& serialized_packet) { |
75 if (!unacked_packets_.empty()) { | 77 if (!unacked_packets_.empty()) { |
76 bool is_old_packet = unacked_packets_.rbegin()->first >= | 78 bool is_old_packet = |
77 serialized_packet.sequence_number; | 79 unacked_packets_.rbegin()->first >= serialized_packet.sequence_number; |
78 LOG_IF(DFATAL, is_old_packet) << "Old packet serialized: " | 80 LOG_IF(DFATAL, is_old_packet) |
79 << serialized_packet.sequence_number | 81 << "Old packet serialized: " << serialized_packet.sequence_number |
80 << " vs: " | 82 << " vs: " << unacked_packets_.rbegin()->first; |
81 << unacked_packets_.rbegin()->first; | |
82 } | 83 } |
83 | 84 |
84 unacked_packets_[serialized_packet.sequence_number] = | 85 unacked_packets_[serialized_packet.sequence_number] = |
85 TransmissionInfo(serialized_packet.retransmittable_frames, | 86 TransmissionInfo(serialized_packet.retransmittable_frames, |
86 serialized_packet.sequence_number, | 87 serialized_packet.sequence_number, |
87 serialized_packet.sequence_number_length); | 88 serialized_packet.sequence_number_length); |
88 if (serialized_packet.retransmittable_frames != NULL && | 89 if (serialized_packet.retransmittable_frames != NULL && |
89 serialized_packet.retransmittable_frames->HasCryptoHandshake() | 90 serialized_packet.retransmittable_frames->HasCryptoHandshake() == |
90 == IS_HANDSHAKE) { | 91 IS_HANDSHAKE) { |
91 ++pending_crypto_packet_count_; | 92 ++pending_crypto_packet_count_; |
92 } | 93 } |
93 } | 94 } |
94 | 95 |
95 void QuicUnackedPacketMap::OnRetransmittedPacket( | 96 void QuicUnackedPacketMap::OnRetransmittedPacket( |
96 QuicPacketSequenceNumber old_sequence_number, | 97 QuicPacketSequenceNumber old_sequence_number, |
97 QuicPacketSequenceNumber new_sequence_number) { | 98 QuicPacketSequenceNumber new_sequence_number) { |
98 DCHECK(ContainsKey(unacked_packets_, old_sequence_number)); | 99 DCHECK(ContainsKey(unacked_packets_, old_sequence_number)); |
99 DCHECK(unacked_packets_.empty() || | 100 DCHECK(unacked_packets_.empty() || |
100 unacked_packets_.rbegin()->first < new_sequence_number); | 101 unacked_packets_.rbegin()->first < new_sequence_number); |
101 | 102 |
102 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. | 103 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. |
103 TransmissionInfo* transmission_info = | 104 TransmissionInfo* transmission_info = |
104 FindOrNull(unacked_packets_, old_sequence_number); | 105 FindOrNull(unacked_packets_, old_sequence_number); |
105 RetransmittableFrames* frames = transmission_info->retransmittable_frames; | 106 RetransmittableFrames* frames = transmission_info->retransmittable_frames; |
106 LOG_IF(DFATAL, frames == NULL) << "Attempt to retransmit packet with no " | 107 LOG_IF(DFATAL, frames == NULL) |
107 << "retransmittable frames: " | 108 << "Attempt to retransmit packet with no " |
108 << old_sequence_number; | 109 << "retransmittable frames: " << old_sequence_number; |
109 | 110 |
110 // We keep the old packet in the unacked packet list until it, or one of | 111 // We keep the old packet in the unacked packet list until it, or one of |
111 // the retransmissions of it are acked. | 112 // the retransmissions of it are acked. |
112 transmission_info->retransmittable_frames = NULL; | 113 transmission_info->retransmittable_frames = NULL; |
113 unacked_packets_[new_sequence_number] = | 114 unacked_packets_[new_sequence_number] = |
114 TransmissionInfo(frames, | 115 TransmissionInfo(frames, |
115 new_sequence_number, | 116 new_sequence_number, |
116 transmission_info->sequence_number_length, | 117 transmission_info->sequence_number_length, |
117 transmission_info->all_transmissions); | 118 transmission_info->all_transmissions); |
118 } | 119 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 if (it == unacked_packets_.end()) { | 164 if (it == unacked_packets_.end()) { |
164 LOG(DFATAL) << "packet is not unacked: " << sequence_number; | 165 LOG(DFATAL) << "packet is not unacked: " << sequence_number; |
165 return; | 166 return; |
166 } | 167 } |
167 const TransmissionInfo& transmission_info = it->second; | 168 const TransmissionInfo& transmission_info = it->second; |
168 transmission_info.all_transmissions->erase(sequence_number); | 169 transmission_info.all_transmissions->erase(sequence_number); |
169 if (transmission_info.all_transmissions->empty()) { | 170 if (transmission_info.all_transmissions->empty()) { |
170 delete transmission_info.all_transmissions; | 171 delete transmission_info.all_transmissions; |
171 } | 172 } |
172 if (transmission_info.retransmittable_frames != NULL) { | 173 if (transmission_info.retransmittable_frames != NULL) { |
173 if (transmission_info.retransmittable_frames->HasCryptoHandshake() | 174 if (transmission_info.retransmittable_frames->HasCryptoHandshake() == |
174 == IS_HANDSHAKE) { | 175 IS_HANDSHAKE) { |
175 --pending_crypto_packet_count_; | 176 --pending_crypto_packet_count_; |
176 } | 177 } |
177 delete transmission_info.retransmittable_frames; | 178 delete transmission_info.retransmittable_frames; |
178 } | 179 } |
179 unacked_packets_.erase(it); | 180 unacked_packets_.erase(it); |
180 } | 181 } |
181 | 182 |
182 void QuicUnackedPacketMap::NeuterPacket( | 183 void QuicUnackedPacketMap::NeuterPacket( |
183 QuicPacketSequenceNumber sequence_number) { | 184 QuicPacketSequenceNumber sequence_number) { |
184 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 185 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
185 if (it == unacked_packets_.end()) { | 186 if (it == unacked_packets_.end()) { |
186 LOG(DFATAL) << "packet is not unacked: " << sequence_number; | 187 LOG(DFATAL) << "packet is not unacked: " << sequence_number; |
187 return; | 188 return; |
188 } | 189 } |
189 TransmissionInfo* transmission_info = &it->second; | 190 TransmissionInfo* transmission_info = &it->second; |
190 if (transmission_info->all_transmissions->size() > 1) { | 191 if (transmission_info->all_transmissions->size() > 1) { |
191 transmission_info->all_transmissions->erase(sequence_number); | 192 transmission_info->all_transmissions->erase(sequence_number); |
192 transmission_info->all_transmissions = new SequenceNumberSet(); | 193 transmission_info->all_transmissions = new SequenceNumberSet(); |
193 transmission_info->all_transmissions->insert(sequence_number); | 194 transmission_info->all_transmissions->insert(sequence_number); |
194 } | 195 } |
195 if (transmission_info->retransmittable_frames != NULL) { | 196 if (transmission_info->retransmittable_frames != NULL) { |
196 if (transmission_info->retransmittable_frames->HasCryptoHandshake() | 197 if (transmission_info->retransmittable_frames->HasCryptoHandshake() == |
197 == IS_HANDSHAKE) { | 198 IS_HANDSHAKE) { |
198 --pending_crypto_packet_count_; | 199 --pending_crypto_packet_count_; |
199 } | 200 } |
200 delete transmission_info->retransmittable_frames; | 201 delete transmission_info->retransmittable_frames; |
201 transmission_info->retransmittable_frames = NULL; | 202 transmission_info->retransmittable_frames = NULL; |
202 } | 203 } |
203 } | 204 } |
204 | 205 |
205 // static | 206 // static |
206 bool QuicUnackedPacketMap::IsSentAndNotPending( | 207 bool QuicUnackedPacketMap::IsSentAndNotPending( |
207 const TransmissionInfo& transmission_info) { | 208 const TransmissionInfo& transmission_info) { |
208 return !transmission_info.pending && | 209 return !transmission_info.pending && |
209 transmission_info.sent_time != QuicTime::Zero() && | 210 transmission_info.sent_time != QuicTime::Zero() && |
210 transmission_info.bytes_sent == 0; | 211 transmission_info.bytes_sent == 0; |
211 } | 212 } |
212 | 213 |
213 bool QuicUnackedPacketMap::IsUnacked( | 214 bool QuicUnackedPacketMap::IsUnacked( |
214 QuicPacketSequenceNumber sequence_number) const { | 215 QuicPacketSequenceNumber sequence_number) const { |
215 return ContainsKey(unacked_packets_, sequence_number); | 216 return ContainsKey(unacked_packets_, sequence_number); |
216 } | 217 } |
217 | 218 |
218 bool QuicUnackedPacketMap::IsPending( | 219 bool QuicUnackedPacketMap::IsPending( |
219 QuicPacketSequenceNumber sequence_number) const { | 220 QuicPacketSequenceNumber sequence_number) const { |
220 const TransmissionInfo* transmission_info = | 221 const TransmissionInfo* transmission_info = |
(...skipping 14 matching lines...) Expand all Loading... |
235 bytes_in_flight_ -= it->second.bytes_sent; | 236 bytes_in_flight_ -= it->second.bytes_sent; |
236 it->second.pending = false; | 237 it->second.pending = false; |
237 } | 238 } |
238 } | 239 } |
239 | 240 |
240 bool QuicUnackedPacketMap::HasUnackedPackets() const { | 241 bool QuicUnackedPacketMap::HasUnackedPackets() const { |
241 return !unacked_packets_.empty(); | 242 return !unacked_packets_.empty(); |
242 } | 243 } |
243 | 244 |
244 bool QuicUnackedPacketMap::HasPendingPackets() const { | 245 bool QuicUnackedPacketMap::HasPendingPackets() const { |
245 for (UnackedPacketMap::const_reverse_iterator it = | 246 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
246 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { | 247 it != unacked_packets_.rend(); |
| 248 ++it) { |
247 if (it->second.pending) { | 249 if (it->second.pending) { |
248 return true; | 250 return true; |
249 } | 251 } |
250 } | 252 } |
251 return false; | 253 return false; |
252 } | 254 } |
253 | 255 |
254 const QuicUnackedPacketMap::TransmissionInfo& | 256 const QuicUnackedPacketMap::TransmissionInfo& |
255 QuicUnackedPacketMap::GetTransmissionInfo( | 257 QuicUnackedPacketMap::GetTransmissionInfo( |
256 QuicPacketSequenceNumber sequence_number) const { | 258 QuicPacketSequenceNumber sequence_number) const { |
257 return unacked_packets_.find(sequence_number)->second; | 259 return unacked_packets_.find(sequence_number)->second; |
258 } | 260 } |
259 | 261 |
260 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { | 262 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { |
261 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); | 263 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
262 while (it != unacked_packets_.rend()) { | 264 while (it != unacked_packets_.rend()) { |
263 if (it->second.pending) { | 265 if (it->second.pending) { |
264 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) | 266 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) |
265 << "Sent time can never be zero for a pending packet."; | 267 << "Sent time can never be zero for a pending packet."; |
266 return it->second.sent_time; | 268 return it->second.sent_time; |
(...skipping 17 matching lines...) Expand all Loading... |
284 return it->second.sent_time; | 286 return it->second.sent_time; |
285 } | 287 } |
286 | 288 |
287 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { | 289 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { |
288 return unacked_packets_.size(); | 290 return unacked_packets_.size(); |
289 } | 291 } |
290 | 292 |
291 bool QuicUnackedPacketMap::HasMultiplePendingPackets() const { | 293 bool QuicUnackedPacketMap::HasMultiplePendingPackets() const { |
292 size_t num_pending = 0; | 294 size_t num_pending = 0; |
293 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); | 295 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
294 it != unacked_packets_.rend(); ++it) { | 296 it != unacked_packets_.rend(); |
| 297 ++it) { |
295 if (it->second.pending) { | 298 if (it->second.pending) { |
296 ++num_pending; | 299 ++num_pending; |
297 } | 300 } |
298 if (num_pending > 1) { | 301 if (num_pending > 1) { |
299 return true; | 302 return true; |
300 } | 303 } |
301 } | 304 } |
302 return false; | 305 return false; |
303 } | 306 } |
304 | 307 |
305 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { | 308 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { |
306 return pending_crypto_packet_count_ > 0; | 309 return pending_crypto_packet_count_ > 0; |
307 } | 310 } |
308 | 311 |
309 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { | 312 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { |
310 for (UnackedPacketMap::const_reverse_iterator it = | 313 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
311 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { | 314 it != unacked_packets_.rend(); |
| 315 ++it) { |
312 if (it->second.pending && it->second.retransmittable_frames) { | 316 if (it->second.pending && it->second.retransmittable_frames) { |
313 return true; | 317 return true; |
314 } | 318 } |
315 } | 319 } |
316 return false; | 320 return false; |
317 } | 321 } |
318 | 322 |
319 size_t QuicUnackedPacketMap::GetNumRetransmittablePackets() const { | 323 size_t QuicUnackedPacketMap::GetNumRetransmittablePackets() const { |
320 size_t num_unacked_packets = 0; | 324 size_t num_unacked_packets = 0; |
321 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 325 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
322 it != unacked_packets_.end(); ++it) { | 326 it != unacked_packets_.end(); |
| 327 ++it) { |
323 if (it->second.retransmittable_frames != NULL) { | 328 if (it->second.retransmittable_frames != NULL) { |
324 ++num_unacked_packets; | 329 ++num_unacked_packets; |
325 } | 330 } |
326 } | 331 } |
327 return num_unacked_packets; | 332 return num_unacked_packets; |
328 } | 333 } |
329 | 334 |
330 QuicPacketSequenceNumber | 335 QuicPacketSequenceNumber QuicUnackedPacketMap::GetLeastUnackedSentPacket() |
331 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { | 336 const { |
332 if (unacked_packets_.empty()) { | 337 if (unacked_packets_.empty()) { |
333 // If there are no unacked packets, return 0. | 338 // If there are no unacked packets, return 0. |
334 return 0; | 339 return 0; |
335 } | 340 } |
336 | 341 |
337 return unacked_packets_.begin()->first; | 342 return unacked_packets_.begin()->first; |
338 } | 343 } |
339 | 344 |
340 SequenceNumberSet QuicUnackedPacketMap::GetUnackedPackets() const { | 345 SequenceNumberSet QuicUnackedPacketMap::GetUnackedPackets() const { |
341 SequenceNumberSet unacked_packets; | 346 SequenceNumberSet unacked_packets; |
342 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 347 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
343 it != unacked_packets_.end(); ++it) { | 348 it != unacked_packets_.end(); |
| 349 ++it) { |
344 unacked_packets.insert(it->first); | 350 unacked_packets.insert(it->first); |
345 } | 351 } |
346 return unacked_packets; | 352 return unacked_packets; |
347 } | 353 } |
348 | 354 |
349 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, | 355 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, |
350 QuicTime sent_time, | 356 QuicTime sent_time, |
351 QuicByteCount bytes_sent, | 357 QuicByteCount bytes_sent, |
352 bool set_pending) { | 358 bool set_pending) { |
353 DCHECK_LT(0u, sequence_number); | 359 DCHECK_LT(0u, sequence_number); |
354 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 360 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
355 if (it == unacked_packets_.end()) { | 361 if (it == unacked_packets_.end()) { |
356 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " | 362 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " |
357 << sequence_number; | 363 << sequence_number; |
358 return; | 364 return; |
359 } | 365 } |
360 DCHECK(!it->second.pending); | 366 DCHECK(!it->second.pending); |
361 | 367 |
362 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); | 368 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); |
363 it->second.sent_time = sent_time; | 369 it->second.sent_time = sent_time; |
364 if (set_pending) { | 370 if (set_pending) { |
365 bytes_in_flight_ += bytes_sent; | 371 bytes_in_flight_ += bytes_sent; |
366 it->second.bytes_sent = bytes_sent; | 372 it->second.bytes_sent = bytes_sent; |
367 it->second.pending = true; | 373 it->second.pending = true; |
368 } | 374 } |
369 } | 375 } |
370 | 376 |
371 } // namespace net | 377 } // namespace net |
OLD | NEW |