OLD | NEW |
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/quic_sent_packet_manager.h" | 5 #include "net/quic/quic_sent_packet_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 37 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
38 static const size_t kDefaultMaxTailLossProbes = 2; | 38 static const size_t kDefaultMaxTailLossProbes = 2; |
39 static const int64 kMinTailLossProbeTimeoutMs = 10; | 39 static const int64 kMinTailLossProbeTimeoutMs = 10; |
40 | 40 |
41 bool HasCryptoHandshake( | 41 bool HasCryptoHandshake( |
42 const QuicUnackedPacketMap::TransmissionInfo& transmission_info) { | 42 const QuicUnackedPacketMap::TransmissionInfo& transmission_info) { |
43 if (transmission_info.retransmittable_frames == NULL) { | 43 if (transmission_info.retransmittable_frames == NULL) { |
44 return false; | 44 return false; |
45 } | 45 } |
46 return transmission_info.retransmittable_frames->HasCryptoHandshake() == | 46 return transmission_info.retransmittable_frames->HasCryptoHandshake() == |
47 IS_HANDSHAKE; | 47 IS_HANDSHAKE; |
48 } | 48 } |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 52 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
53 | 53 |
54 QuicSentPacketManager::QuicSentPacketManager(bool is_server, | 54 QuicSentPacketManager::QuicSentPacketManager(bool is_server, |
55 const QuicClock* clock, | 55 const QuicClock* clock, |
56 QuicConnectionStats* stats, | 56 QuicConnectionStats* stats, |
57 CongestionFeedbackType type, | 57 CongestionFeedbackType type, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 if (largest_observed_acked) { | 133 if (largest_observed_acked) { |
134 // Reset all retransmit counters any time a new packet is acked. | 134 // Reset all retransmit counters any time a new packet is acked. |
135 consecutive_rto_count_ = 0; | 135 consecutive_rto_count_ = 0; |
136 consecutive_tlp_count_ = 0; | 136 consecutive_tlp_count_ = 0; |
137 consecutive_crypto_retransmission_count_ = 0; | 137 consecutive_crypto_retransmission_count_ = 0; |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 void QuicSentPacketManager::DiscardUnackedPacket( | 141 void QuicSentPacketManager::DiscardUnackedPacket( |
142 QuicPacketSequenceNumber sequence_number) { | 142 QuicPacketSequenceNumber sequence_number) { |
143 MarkPacketHandled(sequence_number, QuicTime::Delta::Zero(), | 143 MarkPacketHandled( |
144 NOT_RECEIVED_BY_PEER); | 144 sequence_number, QuicTime::Delta::Zero(), NOT_RECEIVED_BY_PEER); |
145 } | 145 } |
146 | 146 |
147 void QuicSentPacketManager::HandleAckForSentPackets( | 147 void QuicSentPacketManager::HandleAckForSentPackets( |
148 const ReceivedPacketInfo& received_info) { | 148 const ReceivedPacketInfo& received_info) { |
149 // Go through the packets we have not received an ack for and see if this | 149 // Go through the packets we have not received an ack for and see if this |
150 // incoming_ack shows they've been seen by the peer. | 150 // incoming_ack shows they've been seen by the peer. |
151 QuicTime::Delta delta_largest_observed = | 151 QuicTime::Delta delta_largest_observed = |
152 received_info.delta_time_largest_observed; | 152 received_info.delta_time_largest_observed; |
153 QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 153 QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
154 while (it != unacked_packets_.end()) { | 154 while (it != unacked_packets_.end()) { |
155 QuicPacketSequenceNumber sequence_number = it->first; | 155 QuicPacketSequenceNumber sequence_number = it->first; |
156 if (sequence_number > received_info.largest_observed) { | 156 if (sequence_number > received_info.largest_observed) { |
157 // These packets are still in flight. | 157 // These packets are still in flight. |
158 break; | 158 break; |
159 } | 159 } |
160 | 160 |
161 if (IsAwaitingPacket(received_info, sequence_number)) { | 161 if (IsAwaitingPacket(received_info, sequence_number)) { |
162 // Remove any packets not being tracked by the send algorithm, allowing | 162 // Remove any packets not being tracked by the send algorithm, allowing |
163 // the high water mark to be raised if necessary. | 163 // the high water mark to be raised if necessary. |
164 if (QuicUnackedPacketMap::IsSentAndNotPending(it->second)) { | 164 if (QuicUnackedPacketMap::IsSentAndNotPending(it->second)) { |
165 it = MarkPacketHandled(sequence_number, delta_largest_observed, | 165 it = MarkPacketHandled( |
166 NOT_RECEIVED_BY_PEER); | 166 sequence_number, delta_largest_observed, NOT_RECEIVED_BY_PEER); |
167 } else { | 167 } else { |
168 ++it; | 168 ++it; |
169 } | 169 } |
170 continue; | 170 continue; |
171 } | 171 } |
172 | 172 |
173 // Packet was acked, so remove it from our unacked packet list. | 173 // Packet was acked, so remove it from our unacked packet list. |
174 DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; | 174 DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number; |
175 // If data is associated with the most recent transmission of this | 175 // If data is associated with the most recent transmission of this |
176 // packet, then inform the caller. | 176 // packet, then inform the caller. |
177 it = MarkPacketHandled(sequence_number, delta_largest_observed, | 177 it = MarkPacketHandled( |
178 RECEIVED_BY_PEER); | 178 sequence_number, delta_largest_observed, RECEIVED_BY_PEER); |
179 } | 179 } |
180 | 180 |
181 // Discard any retransmittable frames associated with revived packets. | 181 // Discard any retransmittable frames associated with revived packets. |
182 for (SequenceNumberSet::const_iterator revived_it = | 182 for (SequenceNumberSet::const_iterator revived_it = |
183 received_info.revived_packets.begin(); | 183 received_info.revived_packets.begin(); |
184 revived_it != received_info.revived_packets.end(); ++revived_it) { | 184 revived_it != received_info.revived_packets.end(); |
| 185 ++revived_it) { |
185 MarkPacketRevived(*revived_it, delta_largest_observed); | 186 MarkPacketRevived(*revived_it, delta_largest_observed); |
186 } | 187 } |
187 | 188 |
188 // If we have received a truncated ack, then we need to | 189 // If we have received a truncated ack, then we need to |
189 // clear out some previous transmissions to allow the peer | 190 // clear out some previous transmissions to allow the peer |
190 // to actually ACK new packets. | 191 // to actually ACK new packets. |
191 if (received_info.is_truncated) { | 192 if (received_info.is_truncated) { |
192 unacked_packets_.ClearPreviousRetransmissions( | 193 unacked_packets_.ClearPreviousRetransmissions( |
193 received_info.missing_packets.size() / 2); | 194 received_info.missing_packets.size() / 2); |
194 } | 195 } |
195 } | 196 } |
196 | 197 |
197 bool QuicSentPacketManager::HasRetransmittableFrames( | 198 bool QuicSentPacketManager::HasRetransmittableFrames( |
198 QuicPacketSequenceNumber sequence_number) const { | 199 QuicPacketSequenceNumber sequence_number) const { |
199 return unacked_packets_.HasRetransmittableFrames(sequence_number); | 200 return unacked_packets_.HasRetransmittableFrames(sequence_number); |
200 } | 201 } |
201 | 202 |
202 void QuicSentPacketManager::RetransmitUnackedPackets( | 203 void QuicSentPacketManager::RetransmitUnackedPackets( |
203 RetransmissionType retransmission_type) { | 204 RetransmissionType retransmission_type) { |
204 QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); | 205 QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); |
205 while (unacked_it != unacked_packets_.end()) { | 206 while (unacked_it != unacked_packets_.end()) { |
206 const RetransmittableFrames* frames = | 207 const RetransmittableFrames* frames = |
207 unacked_it->second.retransmittable_frames; | 208 unacked_it->second.retransmittable_frames; |
208 // Only mark it as handled if it can't be retransmitted and there are no | 209 // Only mark it as handled if it can't be retransmitted and there are no |
209 // pending retransmissions which would be cleared. | 210 // pending retransmissions which would be cleared. |
210 if (frames == NULL && unacked_it->second.all_transmissions->size() == 1 && | 211 if (frames == NULL && unacked_it->second.all_transmissions->size() == 1 && |
211 retransmission_type == ALL_PACKETS) { | 212 retransmission_type == ALL_PACKETS) { |
212 unacked_it = MarkPacketHandled(unacked_it->first, QuicTime::Delta::Zero(), | 213 unacked_it = MarkPacketHandled( |
213 NOT_RECEIVED_BY_PEER); | 214 unacked_it->first, QuicTime::Delta::Zero(), NOT_RECEIVED_BY_PEER); |
214 continue; | 215 continue; |
215 } | 216 } |
216 // If it had no other transmissions, we handle it above. If it has | 217 // If it had no other transmissions, we handle it above. If it has |
217 // other transmissions, one of them must have retransmittable frames, | 218 // other transmissions, one of them must have retransmittable frames, |
218 // so that gets resolved the same way as other retransmissions. | 219 // so that gets resolved the same way as other retransmissions. |
219 // TODO(ianswett): Consider adding a new retransmission type which removes | 220 // TODO(ianswett): Consider adding a new retransmission type which removes |
220 // all these old packets from unacked and retransmits them as new sequence | 221 // all these old packets from unacked and retransmits them as new sequence |
221 // numbers with no connection to the previous ones. | 222 // numbers with no connection to the previous ones. |
222 if (frames != NULL && (retransmission_type == ALL_PACKETS || | 223 if (frames != NULL && (retransmission_type == ALL_PACKETS || |
223 frames->encryption_level() == ENCRYPTION_INITIAL)) { | 224 frames->encryption_level() == ENCRYPTION_INITIAL)) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 } | 260 } |
260 | 261 |
261 pending_retransmissions_[sequence_number] = transmission_type; | 262 pending_retransmissions_[sequence_number] = transmission_type; |
262 } | 263 } |
263 | 264 |
264 bool QuicSentPacketManager::HasPendingRetransmissions() const { | 265 bool QuicSentPacketManager::HasPendingRetransmissions() const { |
265 return !pending_retransmissions_.empty(); | 266 return !pending_retransmissions_.empty(); |
266 } | 267 } |
267 | 268 |
268 QuicSentPacketManager::PendingRetransmission | 269 QuicSentPacketManager::PendingRetransmission |
269 QuicSentPacketManager::NextPendingRetransmission() { | 270 QuicSentPacketManager::NextPendingRetransmission() { |
270 DCHECK(!pending_retransmissions_.empty()); | 271 DCHECK(!pending_retransmissions_.empty()); |
271 QuicPacketSequenceNumber sequence_number = | 272 QuicPacketSequenceNumber sequence_number = |
272 pending_retransmissions_.begin()->first; | 273 pending_retransmissions_.begin()->first; |
273 TransmissionType transmission_type = pending_retransmissions_.begin()->second; | 274 TransmissionType transmission_type = pending_retransmissions_.begin()->second; |
274 if (unacked_packets_.HasPendingCryptoPackets()) { | 275 if (unacked_packets_.HasPendingCryptoPackets()) { |
275 // Ensure crypto packets are retransmitted before other packets. | 276 // Ensure crypto packets are retransmitted before other packets. |
276 PendingRetransmissionMap::const_iterator it = | 277 PendingRetransmissionMap::const_iterator it = |
277 pending_retransmissions_.begin(); | 278 pending_retransmissions_.begin(); |
278 do { | 279 do { |
279 if (HasCryptoHandshake( | 280 if (HasCryptoHandshake(unacked_packets_.GetTransmissionInfo(it->first))) { |
280 unacked_packets_.GetTransmissionInfo(it->first))) { | |
281 sequence_number = it->first; | 281 sequence_number = it->first; |
282 transmission_type = it->second; | 282 transmission_type = it->second; |
283 break; | 283 break; |
284 } | 284 } |
285 ++it; | 285 ++it; |
286 } while (it != pending_retransmissions_.end()); | 286 } while (it != pending_retransmissions_.end()); |
287 } | 287 } |
288 DCHECK(unacked_packets_.IsUnacked(sequence_number)); | 288 DCHECK(unacked_packets_.IsUnacked(sequence_number)); |
289 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 289 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
290 unacked_packets_.GetTransmissionInfo(sequence_number); | 290 unacked_packets_.GetTransmissionInfo(sequence_number); |
(...skipping 13 matching lines...) Expand all Loading... |
304 } | 304 } |
305 // This packet has been revived at the receiver. If we were going to | 305 // This packet has been revived at the receiver. If we were going to |
306 // retransmit it, do not retransmit it anymore. | 306 // retransmit it, do not retransmit it anymore. |
307 pending_retransmissions_.erase(sequence_number); | 307 pending_retransmissions_.erase(sequence_number); |
308 | 308 |
309 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 309 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
310 unacked_packets_.GetTransmissionInfo(sequence_number); | 310 unacked_packets_.GetTransmissionInfo(sequence_number); |
311 // The AckNotifierManager needs to be notified for revived packets, | 311 // The AckNotifierManager needs to be notified for revived packets, |
312 // since it indicates the packet arrived from the appliction's perspective. | 312 // since it indicates the packet arrived from the appliction's perspective. |
313 if (transmission_info.retransmittable_frames) { | 313 if (transmission_info.retransmittable_frames) { |
314 ack_notifier_manager_.OnPacketAcked( | 314 ack_notifier_manager_.OnPacketAcked(sequence_number, |
315 sequence_number, delta_largest_observed); | 315 delta_largest_observed); |
316 } | 316 } |
317 | 317 |
318 if (!transmission_info.pending) { | 318 if (!transmission_info.pending) { |
319 unacked_packets_.RemovePacket(sequence_number); | 319 unacked_packets_.RemovePacket(sequence_number); |
320 } else { | 320 } else { |
321 unacked_packets_.NeuterPacket(sequence_number); | 321 unacked_packets_.NeuterPacket(sequence_number); |
322 } | 322 } |
323 } | 323 } |
324 | 324 |
325 QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( | 325 QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( |
326 QuicPacketSequenceNumber sequence_number, | 326 QuicPacketSequenceNumber sequence_number, |
327 QuicTime::Delta delta_largest_observed, ReceivedByPeer received_by_peer) { | 327 QuicTime::Delta delta_largest_observed, |
| 328 ReceivedByPeer received_by_peer) { |
328 if (!unacked_packets_.IsUnacked(sequence_number)) { | 329 if (!unacked_packets_.IsUnacked(sequence_number)) { |
329 LOG(DFATAL) << "Packet is not unacked: " << sequence_number; | 330 LOG(DFATAL) << "Packet is not unacked: " << sequence_number; |
330 return unacked_packets_.end(); | 331 return unacked_packets_.end(); |
331 } | 332 } |
332 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 333 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
333 unacked_packets_.GetTransmissionInfo(sequence_number); | 334 unacked_packets_.GetTransmissionInfo(sequence_number); |
334 // If this packet is pending, remove it and inform the send algorithm. | 335 // If this packet is pending, remove it and inform the send algorithm. |
335 if (transmission_info.pending) { | 336 if (transmission_info.pending) { |
336 if (received_by_peer == RECEIVED_BY_PEER) { | 337 if (received_by_peer == RECEIVED_BY_PEER) { |
337 send_algorithm_->OnPacketAcked(sequence_number, | 338 send_algorithm_->OnPacketAcked(sequence_number, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 | 394 |
394 bool QuicSentPacketManager::IsUnacked( | 395 bool QuicSentPacketManager::IsUnacked( |
395 QuicPacketSequenceNumber sequence_number) const { | 396 QuicPacketSequenceNumber sequence_number) const { |
396 return unacked_packets_.IsUnacked(sequence_number); | 397 return unacked_packets_.IsUnacked(sequence_number); |
397 } | 398 } |
398 | 399 |
399 bool QuicSentPacketManager::HasUnackedPackets() const { | 400 bool QuicSentPacketManager::HasUnackedPackets() const { |
400 return unacked_packets_.HasUnackedPackets(); | 401 return unacked_packets_.HasUnackedPackets(); |
401 } | 402 } |
402 | 403 |
403 QuicPacketSequenceNumber | 404 QuicPacketSequenceNumber QuicSentPacketManager::GetLeastUnackedSentPacket() |
404 QuicSentPacketManager::GetLeastUnackedSentPacket() const { | 405 const { |
405 return unacked_packets_.GetLeastUnackedSentPacket(); | 406 return unacked_packets_.GetLeastUnackedSentPacket(); |
406 } | 407 } |
407 | 408 |
408 bool QuicSentPacketManager::OnPacketSent( | 409 bool QuicSentPacketManager::OnPacketSent( |
409 QuicPacketSequenceNumber sequence_number, | 410 QuicPacketSequenceNumber sequence_number, |
410 QuicTime sent_time, | 411 QuicTime sent_time, |
411 QuicByteCount bytes, | 412 QuicByteCount bytes, |
412 TransmissionType transmission_type, | 413 TransmissionType transmission_type, |
413 HasRetransmittableData has_retransmittable_data) { | 414 HasRetransmittableData has_retransmittable_data) { |
414 DCHECK_LT(0u, sequence_number); | 415 DCHECK_LT(0u, sequence_number); |
415 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; | 416 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; |
416 // In rare circumstances, the packet could be serialized, sent, and then acked | 417 // In rare circumstances, the packet could be serialized, sent, and then acked |
417 // before OnPacketSent is called. | 418 // before OnPacketSent is called. |
418 if (!unacked_packets_.IsUnacked(sequence_number)) { | 419 if (!unacked_packets_.IsUnacked(sequence_number)) { |
419 return false; | 420 return false; |
420 } | 421 } |
421 | 422 |
422 // Only track packets as pending that the send algorithm wants us to track. | 423 // Only track packets as pending that the send algorithm wants us to track. |
423 if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, | 424 if (!send_algorithm_->OnPacketSent( |
424 has_retransmittable_data)) { | 425 sent_time, sequence_number, bytes, has_retransmittable_data)) { |
425 unacked_packets_.SetSent(sequence_number, sent_time, bytes, false); | 426 unacked_packets_.SetSent(sequence_number, sent_time, bytes, false); |
426 // Do not reset the retransmission timer, since the packet isn't tracked. | 427 // Do not reset the retransmission timer, since the packet isn't tracked. |
427 return false; | 428 return false; |
428 } | 429 } |
429 | 430 |
430 const bool set_retransmission_timer = !unacked_packets_.HasPendingPackets(); | 431 const bool set_retransmission_timer = !unacked_packets_.HasPendingPackets(); |
431 | 432 |
432 unacked_packets_.SetSent(sequence_number, sent_time, bytes, true); | 433 unacked_packets_.SetSent(sequence_number, sent_time, bytes, true); |
433 | 434 |
434 // Reset the retransmission timer anytime a packet is sent in tail loss probe | 435 // Reset the retransmission timer anytime a packet is sent in tail loss probe |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 } | 467 } |
467 | 468 |
468 void QuicSentPacketManager::RetransmitCryptoPackets() { | 469 void QuicSentPacketManager::RetransmitCryptoPackets() { |
469 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); | 470 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); |
470 // TODO(ianswett): Typical TCP implementations only retransmit 5 times. | 471 // TODO(ianswett): Typical TCP implementations only retransmit 5 times. |
471 consecutive_crypto_retransmission_count_ = | 472 consecutive_crypto_retransmission_count_ = |
472 min(kMaxHandshakeRetransmissionBackoffs, | 473 min(kMaxHandshakeRetransmissionBackoffs, |
473 consecutive_crypto_retransmission_count_ + 1); | 474 consecutive_crypto_retransmission_count_ + 1); |
474 bool packet_retransmitted = false; | 475 bool packet_retransmitted = false; |
475 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 476 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
476 it != unacked_packets_.end(); ++it) { | 477 it != unacked_packets_.end(); |
| 478 ++it) { |
477 QuicPacketSequenceNumber sequence_number = it->first; | 479 QuicPacketSequenceNumber sequence_number = it->first; |
478 const RetransmittableFrames* frames = it->second.retransmittable_frames; | 480 const RetransmittableFrames* frames = it->second.retransmittable_frames; |
479 // Only retransmit frames which are pending, and therefore have been sent. | 481 // Only retransmit frames which are pending, and therefore have been sent. |
480 if (!it->second.pending || frames == NULL || | 482 if (!it->second.pending || frames == NULL || |
481 frames->HasCryptoHandshake() != IS_HANDSHAKE) { | 483 frames->HasCryptoHandshake() != IS_HANDSHAKE) { |
482 continue; | 484 continue; |
483 } | 485 } |
484 packet_retransmitted = true; | 486 packet_retransmitted = true; |
485 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); | 487 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); |
486 // Abandon all the crypto retransmissions now so they're not lost later. | 488 // Abandon all the crypto retransmissions now so they're not lost later. |
487 OnPacketAbandoned(sequence_number); | 489 OnPacketAbandoned(sequence_number); |
488 } | 490 } |
489 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; | 491 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; |
490 } | 492 } |
491 | 493 |
492 void QuicSentPacketManager::RetransmitOldestPacket() { | 494 void QuicSentPacketManager::RetransmitOldestPacket() { |
493 DCHECK_EQ(TLP_MODE, GetRetransmissionMode()); | 495 DCHECK_EQ(TLP_MODE, GetRetransmissionMode()); |
494 ++consecutive_tlp_count_; | 496 ++consecutive_tlp_count_; |
495 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 497 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
496 it != unacked_packets_.end(); ++it) { | 498 it != unacked_packets_.end(); |
| 499 ++it) { |
497 QuicPacketSequenceNumber sequence_number = it->first; | 500 QuicPacketSequenceNumber sequence_number = it->first; |
498 const RetransmittableFrames* frames = it->second.retransmittable_frames; | 501 const RetransmittableFrames* frames = it->second.retransmittable_frames; |
499 // Only retransmit frames which are pending, and therefore have been sent. | 502 // Only retransmit frames which are pending, and therefore have been sent. |
500 if (!it->second.pending || frames == NULL) { | 503 if (!it->second.pending || frames == NULL) { |
501 continue; | 504 continue; |
502 } | 505 } |
503 DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); | 506 DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); |
504 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); | 507 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); |
505 return; | 508 return; |
506 } | 509 } |
507 DLOG(FATAL) | 510 DLOG(FATAL) |
508 << "No retransmittable packets, so RetransmitOldestPacket failed."; | 511 << "No retransmittable packets, so RetransmitOldestPacket failed."; |
509 } | 512 } |
510 | 513 |
511 void QuicSentPacketManager::RetransmitAllPackets() { | 514 void QuicSentPacketManager::RetransmitAllPackets() { |
512 // Abandon all retransmittable packets and packets older than the | 515 // Abandon all retransmittable packets and packets older than the |
513 // retransmission delay. | 516 // retransmission delay. |
514 | 517 |
515 DVLOG(1) << "OnRetransmissionTimeout() fired with " | 518 DVLOG(1) << "OnRetransmissionTimeout() fired with " |
516 << unacked_packets_.GetNumUnackedPackets() << " unacked packets."; | 519 << unacked_packets_.GetNumUnackedPackets() << " unacked packets."; |
517 | 520 |
518 // Request retransmission of all retransmittable packets when the RTO | 521 // Request retransmission of all retransmittable packets when the RTO |
519 // fires, and let the congestion manager decide how many to send | 522 // fires, and let the congestion manager decide how many to send |
520 // immediately and the remaining packets will be queued. | 523 // immediately and the remaining packets will be queued. |
521 // Abandon any non-retransmittable packets that are sufficiently old. | 524 // Abandon any non-retransmittable packets that are sufficiently old. |
522 bool packets_retransmitted = false; | 525 bool packets_retransmitted = false; |
523 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 526 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
524 it != unacked_packets_.end(); ++it) { | 527 it != unacked_packets_.end(); |
| 528 ++it) { |
525 unacked_packets_.SetNotPending(it->first); | 529 unacked_packets_.SetNotPending(it->first); |
526 if (it->second.retransmittable_frames != NULL) { | 530 if (it->second.retransmittable_frames != NULL) { |
527 packets_retransmitted = true; | 531 packets_retransmitted = true; |
528 MarkForRetransmission(it->first, RTO_RETRANSMISSION); | 532 MarkForRetransmission(it->first, RTO_RETRANSMISSION); |
529 } | 533 } |
530 } | 534 } |
531 | 535 |
532 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); | 536 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); |
533 if (packets_retransmitted) { | 537 if (packets_retransmitted) { |
534 ++consecutive_rto_count_; | 538 ++consecutive_rto_count_; |
535 } | 539 } |
536 } | 540 } |
537 | 541 |
538 QuicSentPacketManager::RetransmissionTimeoutMode | 542 QuicSentPacketManager::RetransmissionTimeoutMode |
539 QuicSentPacketManager::GetRetransmissionMode() const { | 543 QuicSentPacketManager::GetRetransmissionMode() const { |
540 DCHECK(unacked_packets_.HasPendingPackets()); | 544 DCHECK(unacked_packets_.HasPendingPackets()); |
541 if (unacked_packets_.HasPendingCryptoPackets()) { | 545 if (unacked_packets_.HasPendingCryptoPackets()) { |
542 return HANDSHAKE_MODE; | 546 return HANDSHAKE_MODE; |
543 } | 547 } |
544 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { | 548 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { |
545 return LOSS_MODE; | 549 return LOSS_MODE; |
546 } | 550 } |
547 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | 551 if (consecutive_tlp_count_ < max_tail_loss_probes_) { |
548 if (unacked_packets_.HasUnackedRetransmittableFrames()) { | 552 if (unacked_packets_.HasUnackedRetransmittableFrames()) { |
549 return TLP_MODE; | 553 return TLP_MODE; |
(...skipping 10 matching lines...) Expand all Loading... |
560 LOG_IF(DFATAL, transmission_info.bytes_sent == 0); | 564 LOG_IF(DFATAL, transmission_info.bytes_sent == 0); |
561 send_algorithm_->OnPacketAbandoned(sequence_number, | 565 send_algorithm_->OnPacketAbandoned(sequence_number, |
562 transmission_info.bytes_sent); | 566 transmission_info.bytes_sent); |
563 unacked_packets_.SetNotPending(sequence_number); | 567 unacked_packets_.SetNotPending(sequence_number); |
564 } | 568 } |
565 } | 569 } |
566 | 570 |
567 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( | 571 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( |
568 const QuicCongestionFeedbackFrame& frame, | 572 const QuicCongestionFeedbackFrame& frame, |
569 const QuicTime& feedback_receive_time) { | 573 const QuicTime& feedback_receive_time) { |
570 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( | 574 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(frame, |
571 frame, feedback_receive_time); | 575 feedback_receive_time); |
572 } | 576 } |
573 | 577 |
574 void QuicSentPacketManager::MaybeRetransmitOnAckFrame( | 578 void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
575 const ReceivedPacketInfo& received_info, | 579 const ReceivedPacketInfo& received_info, |
576 const QuicTime& ack_receive_time) { | 580 const QuicTime& ack_receive_time) { |
577 // Go through all pending packets up to the largest observed and count nacks. | 581 // Go through all pending packets up to the largest observed and count nacks. |
578 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 582 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
579 it != unacked_packets_.end() && | 583 it != unacked_packets_.end() && |
580 it->first <= received_info.largest_observed; ++it) { | 584 it->first <= received_info.largest_observed; |
| 585 ++it) { |
581 if (!it->second.pending) { | 586 if (!it->second.pending) { |
582 continue; | 587 continue; |
583 } | 588 } |
584 QuicPacketSequenceNumber sequence_number = it->first; | 589 QuicPacketSequenceNumber sequence_number = it->first; |
585 DVLOG(1) << "still missing packet " << sequence_number; | 590 DVLOG(1) << "still missing packet " << sequence_number; |
586 // Acks must be handled previously, so ensure it's missing and not acked. | 591 // Acks must be handled previously, so ensure it's missing and not acked. |
587 DCHECK(IsAwaitingPacket(received_info, sequence_number)); | 592 DCHECK(IsAwaitingPacket(received_info, sequence_number)); |
588 | 593 |
589 // Consider it multiple nacks when there is a gap between the missing packet | 594 // Consider it multiple nacks when there is a gap between the missing packet |
590 // and the largest observed, since the purpose of a nack threshold is to | 595 // and the largest observed, since the purpose of a nack threshold is to |
591 // tolerate re-ordering. This handles both StretchAcks and Forward Acks. | 596 // tolerate re-ordering. This handles both StretchAcks and Forward Acks. |
592 // The nack count only increases when the largest observed increases. | 597 // The nack count only increases when the largest observed increases. |
593 size_t min_nacks = received_info.largest_observed - sequence_number; | 598 size_t min_nacks = received_info.largest_observed - sequence_number; |
594 // Truncated acks can nack the largest observed, so set the nack count to 1. | 599 // Truncated acks can nack the largest observed, so set the nack count to 1. |
595 if (min_nacks == 0) { | 600 if (min_nacks == 0) { |
596 min_nacks = 1; | 601 min_nacks = 1; |
597 } | 602 } |
598 unacked_packets_.NackPacket(sequence_number, min_nacks); | 603 unacked_packets_.NackPacket(sequence_number, min_nacks); |
599 } | 604 } |
600 | 605 |
601 InvokeLossDetection(ack_receive_time); | 606 InvokeLossDetection(ack_receive_time); |
602 } | 607 } |
603 | 608 |
604 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { | 609 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
605 SequenceNumberSet lost_packets = | 610 SequenceNumberSet lost_packets = loss_algorithm_->DetectLostPackets( |
606 loss_algorithm_->DetectLostPackets(unacked_packets_, | 611 unacked_packets_, time, largest_observed_, rtt_stats_); |
607 time, | |
608 largest_observed_, | |
609 rtt_stats_); | |
610 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); | 612 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
611 it != lost_packets.end(); ++it) { | 613 it != lost_packets.end(); |
| 614 ++it) { |
612 QuicPacketSequenceNumber sequence_number = *it; | 615 QuicPacketSequenceNumber sequence_number = *it; |
613 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | 616 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it |
614 // should be recorded as a loss to the send algorithm, but not retransmitted | 617 // should be recorded as a loss to the send algorithm, but not retransmitted |
615 // until it's known whether the FEC packet arrived. | 618 // until it's known whether the FEC packet arrived. |
616 ++stats_->packets_lost; | 619 ++stats_->packets_lost; |
617 send_algorithm_->OnPacketLost(sequence_number, time); | 620 send_algorithm_->OnPacketLost(sequence_number, time); |
618 OnPacketAbandoned(sequence_number); | 621 OnPacketAbandoned(sequence_number); |
619 | 622 |
620 if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { | 623 if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { |
621 MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION); | 624 MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 // retransmission timer triggers. Since we do not know the | 672 // retransmission timer triggers. Since we do not know the |
670 // reverse-path one-way delay, we assume equal delays for forward and | 673 // reverse-path one-way delay, we assume equal delays for forward and |
671 // reverse paths, and ensure that the timer is set to less than half | 674 // reverse paths, and ensure that the timer is set to less than half |
672 // of the MinRTO. | 675 // of the MinRTO. |
673 // There may be a value in making this delay adaptive with the help of | 676 // There may be a value in making this delay adaptive with the help of |
674 // the sender and a signaling mechanism -- if the sender uses a | 677 // the sender and a signaling mechanism -- if the sender uses a |
675 // different MinRTO, we may get spurious retransmissions. May not have | 678 // different MinRTO, we may get spurious retransmissions. May not have |
676 // any benefits, but if the delayed ack becomes a significant source | 679 // any benefits, but if the delayed ack becomes a significant source |
677 // of (likely, tail) latency, then consider such a mechanism. | 680 // of (likely, tail) latency, then consider such a mechanism. |
678 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { | 681 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { |
679 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); | 682 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs / 2); |
680 } | 683 } |
681 | 684 |
682 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | 685 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
683 // Don't set the timer if there are no pending packets. | 686 // Don't set the timer if there are no pending packets. |
684 if (!unacked_packets_.HasPendingPackets()) { | 687 if (!unacked_packets_.HasPendingPackets()) { |
685 return QuicTime::Zero(); | 688 return QuicTime::Zero(); |
686 } | 689 } |
687 switch (GetRetransmissionMode()) { | 690 switch (GetRetransmissionMode()) { |
688 case HANDSHAKE_MODE: | 691 case HANDSHAKE_MODE: |
689 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); | 692 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); |
690 case LOSS_MODE: | 693 case LOSS_MODE: |
691 return loss_algorithm_->GetLossTimeout(); | 694 return loss_algorithm_->GetLossTimeout(); |
692 case TLP_MODE: { | 695 case TLP_MODE: { |
693 // TODO(ianswett): When CWND is available, it would be preferable to | 696 // TODO(ianswett): When CWND is available, it would be preferable to |
694 // set the timer based on the earliest retransmittable packet. | 697 // set the timer based on the earliest retransmittable packet. |
695 // Base the updated timer on the send time of the last packet. | 698 // Base the updated timer on the send time of the last packet. |
696 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); | 699 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); |
697 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); | 700 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); |
698 // Ensure the tlp timer never gets set to a time in the past. | 701 // Ensure the tlp timer never gets set to a time in the past. |
699 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); | 702 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); |
700 } | 703 } |
701 case RTO_MODE: { | 704 case RTO_MODE: { |
702 // The RTO is based on the first pending packet. | 705 // The RTO is based on the first pending packet. |
703 const QuicTime sent_time = | 706 const QuicTime sent_time = |
704 unacked_packets_.GetFirstPendingPacketSentTime(); | 707 unacked_packets_.GetFirstPendingPacketSentTime(); |
705 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); | 708 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); |
706 // Always wait at least 1.5 * RTT from now. | 709 // Always wait at least 1.5 * RTT from now. |
707 QuicTime min_timeout = clock_->ApproximateNow().Add( | 710 QuicTime min_timeout = |
708 rtt_stats_.SmoothedRtt().Multiply(1.5)); | 711 clock_->ApproximateNow().Add(rtt_stats_.SmoothedRtt().Multiply(1.5)); |
709 | 712 |
710 return QuicTime::Max(min_timeout, rto_timeout); | 713 return QuicTime::Max(min_timeout, rto_timeout); |
711 } | 714 } |
712 } | 715 } |
713 DCHECK(false); | 716 DCHECK(false); |
714 return QuicTime::Zero(); | 717 return QuicTime::Zero(); |
715 } | 718 } |
716 | 719 |
717 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() | 720 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() |
718 const { | 721 const { |
719 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive | 722 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive |
720 // because crypto handshake messages don't incur a delayed ack time. | 723 // because crypto handshake messages don't incur a delayed ack time. |
721 int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs, | 724 int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs, |
722 1.5 * rtt_stats_.SmoothedRtt().ToMilliseconds()); | 725 1.5 * rtt_stats_.SmoothedRtt().ToMilliseconds()); |
723 return QuicTime::Delta::FromMilliseconds( | 726 return QuicTime::Delta::FromMilliseconds( |
724 delay_ms << consecutive_crypto_retransmission_count_); | 727 delay_ms << consecutive_crypto_retransmission_count_); |
725 } | 728 } |
726 | 729 |
727 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { | 730 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { |
728 QuicTime::Delta srtt = rtt_stats_.SmoothedRtt(); | 731 QuicTime::Delta srtt = rtt_stats_.SmoothedRtt(); |
729 if (!unacked_packets_.HasMultiplePendingPackets()) { | 732 if (!unacked_packets_.HasMultiplePendingPackets()) { |
730 return QuicTime::Delta::Max( | 733 return QuicTime::Delta::Max(srtt.Multiply(1.5).Add(DelayedAckTime()), |
731 srtt.Multiply(1.5).Add(DelayedAckTime()), srtt.Multiply(2)); | 734 srtt.Multiply(2)); |
732 } | 735 } |
733 return QuicTime::Delta::FromMilliseconds( | 736 return QuicTime::Delta::FromMilliseconds( |
734 max(kMinTailLossProbeTimeoutMs, | 737 max(kMinTailLossProbeTimeoutMs, |
735 static_cast<int64>(2 * srtt.ToMilliseconds()))); | 738 static_cast<int64>(2 * srtt.ToMilliseconds()))); |
736 } | 739 } |
737 | 740 |
738 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { | 741 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { |
739 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); | 742 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); |
740 // TODO(rch): This code should move to |send_algorithm_|. | 743 // TODO(rch): This code should move to |send_algorithm_|. |
741 if (retransmission_delay.IsZero()) { | 744 if (retransmission_delay.IsZero()) { |
(...skipping 30 matching lines...) Expand all Loading... |
772 void QuicSentPacketManager::MaybeEnablePacing() { | 775 void QuicSentPacketManager::MaybeEnablePacing() { |
773 if (!FLAGS_enable_quic_pacing) { | 776 if (!FLAGS_enable_quic_pacing) { |
774 return; | 777 return; |
775 } | 778 } |
776 | 779 |
777 if (using_pacing_) { | 780 if (using_pacing_) { |
778 return; | 781 return; |
779 } | 782 } |
780 | 783 |
781 using_pacing_ = true; | 784 using_pacing_ = true; |
782 send_algorithm_.reset( | 785 send_algorithm_.reset(new PacingSender(send_algorithm_.release(), |
783 new PacingSender(send_algorithm_.release(), | 786 QuicTime::Delta::FromMicroseconds(1))); |
784 QuicTime::Delta::FromMicroseconds(1))); | |
785 } | 787 } |
786 | 788 |
787 } // namespace net | 789 } // namespace net |
OLD | NEW |