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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "net/quic/congestion_control/pacing_sender.h" | 9 #include "net/quic/congestion_control/pacing_sender.h" |
10 #include "net/quic/crypto/crypto_protocol.h" | 10 #include "net/quic/crypto/crypto_protocol.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 namespace net { | 34 namespace net { |
35 namespace { | 35 namespace { |
36 static const int kDefaultRetransmissionTimeMs = 500; | 36 static const int kDefaultRetransmissionTimeMs = 500; |
37 // TCP RFC calls for 1 second RTO however Linux differs from this default and | 37 // TCP RFC calls for 1 second RTO however Linux differs from this default and |
38 // define the minimum RTO to 200ms, we will use the same until we have data to | 38 // define the minimum RTO to 200ms, we will use the same until we have data to |
39 // support a higher or lower value. | 39 // support a higher or lower value. |
40 static const int kMinRetransmissionTimeMs = 200; | 40 static const int kMinRetransmissionTimeMs = 200; |
41 static const int kMaxRetransmissionTimeMs = 60000; | 41 static const int kMaxRetransmissionTimeMs = 60000; |
42 static const size_t kMaxRetransmissions = 10; | 42 static const size_t kMaxRetransmissions = 10; |
43 | 43 |
44 // TCP retransmits after 3 nacks. | |
45 static const size_t kNumberOfNacksBeforeRetransmission = 3; | |
46 | |
47 // Only exponentially back off the handshake timer 5 times due to a timeout. | 44 // Only exponentially back off the handshake timer 5 times due to a timeout. |
48 static const size_t kMaxHandshakeRetransmissionBackoffs = 5; | 45 static const size_t kMaxHandshakeRetransmissionBackoffs = 5; |
49 static const size_t kMinHandshakeTimeoutMs = 10; | 46 static const size_t kMinHandshakeTimeoutMs = 10; |
50 | 47 |
51 // Sends up to two tail loss probes before firing an RTO, | 48 // Sends up to two tail loss probes before firing an RTO, |
52 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 49 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
53 static const size_t kDefaultMaxTailLossProbes = 2; | 50 static const size_t kDefaultMaxTailLossProbes = 2; |
54 static const int64 kMinTailLossProbeTimeoutMs = 10; | 51 static const int64 kMinTailLossProbeTimeoutMs = 10; |
55 | 52 |
56 bool HasCryptoHandshake( | 53 bool HasCryptoHandshake( |
(...skipping 11 matching lines...) Expand all Loading... |
68 | 65 |
69 QuicSentPacketManager::QuicSentPacketManager(bool is_server, | 66 QuicSentPacketManager::QuicSentPacketManager(bool is_server, |
70 const QuicClock* clock, | 67 const QuicClock* clock, |
71 QuicConnectionStats* stats, | 68 QuicConnectionStats* stats, |
72 CongestionFeedbackType type) | 69 CongestionFeedbackType type) |
73 : unacked_packets_(is_server), | 70 : unacked_packets_(is_server), |
74 is_server_(is_server), | 71 is_server_(is_server), |
75 clock_(clock), | 72 clock_(clock), |
76 stats_(stats), | 73 stats_(stats), |
77 send_algorithm_(SendAlgorithmInterface::Create(clock, type)), | 74 send_algorithm_(SendAlgorithmInterface::Create(clock, type)), |
| 75 loss_algorithm_(LossDetectionInterface::Create()), |
78 rtt_sample_(QuicTime::Delta::Infinite()), | 76 rtt_sample_(QuicTime::Delta::Infinite()), |
| 77 largest_observed_(0), |
79 pending_crypto_packet_count_(0), | 78 pending_crypto_packet_count_(0), |
80 consecutive_rto_count_(0), | 79 consecutive_rto_count_(0), |
81 consecutive_tlp_count_(0), | 80 consecutive_tlp_count_(0), |
82 consecutive_crypto_retransmission_count_(0), | 81 consecutive_crypto_retransmission_count_(0), |
83 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 82 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
84 using_pacing_(false) { | 83 using_pacing_(false) { |
85 } | 84 } |
86 | 85 |
87 QuicSentPacketManager::~QuicSentPacketManager() { | 86 QuicSentPacketManager::~QuicSentPacketManager() { |
88 } | 87 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 unacked_packets_.OnRetransmittedPacket(old_sequence_number, | 133 unacked_packets_.OnRetransmittedPacket(old_sequence_number, |
135 new_sequence_number); | 134 new_sequence_number); |
136 } | 135 } |
137 | 136 |
138 bool QuicSentPacketManager::OnIncomingAck( | 137 bool QuicSentPacketManager::OnIncomingAck( |
139 const ReceivedPacketInfo& received_info, QuicTime ack_receive_time) { | 138 const ReceivedPacketInfo& received_info, QuicTime ack_receive_time) { |
140 // We rely on delta_time_largest_observed to compute an RTT estimate, so | 139 // We rely on delta_time_largest_observed to compute an RTT estimate, so |
141 // we only update rtt when the largest observed gets acked. | 140 // we only update rtt when the largest observed gets acked. |
142 bool largest_observed_acked = | 141 bool largest_observed_acked = |
143 unacked_packets_.IsUnacked(received_info.largest_observed); | 142 unacked_packets_.IsUnacked(received_info.largest_observed); |
| 143 largest_observed_ = received_info.largest_observed; |
144 MaybeUpdateRTT(received_info, ack_receive_time); | 144 MaybeUpdateRTT(received_info, ack_receive_time); |
145 HandleAckForSentPackets(received_info); | 145 HandleAckForSentPackets(received_info); |
146 MaybeRetransmitOnAckFrame(received_info, ack_receive_time); | 146 MaybeRetransmitOnAckFrame(received_info, ack_receive_time); |
147 | 147 |
148 // Anytime we are making forward progress and have a new RTT estimate, reset | 148 // Anytime we are making forward progress and have a new RTT estimate, reset |
149 // the backoff counters. | 149 // the backoff counters. |
150 if (largest_observed_acked) { | 150 if (largest_observed_acked) { |
151 // Reset all retransmit counters any time a new packet is acked. | 151 // Reset all retransmit counters any time a new packet is acked. |
152 consecutive_rto_count_ = 0; | 152 consecutive_rto_count_ = 0; |
153 consecutive_tlp_count_ = 0; | 153 consecutive_tlp_count_ = 0; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 send_algorithm_->OnPacketAcked(sequence_number, | 298 send_algorithm_->OnPacketAcked(sequence_number, |
299 transmission_info.bytes_sent); | 299 transmission_info.bytes_sent); |
300 } else { | 300 } else { |
301 // It's been abandoned. | 301 // It's been abandoned. |
302 send_algorithm_->OnPacketAbandoned(sequence_number, | 302 send_algorithm_->OnPacketAbandoned(sequence_number, |
303 transmission_info.bytes_sent); | 303 transmission_info.bytes_sent); |
304 } | 304 } |
305 unacked_packets_.SetNotPending(sequence_number); | 305 unacked_packets_.SetNotPending(sequence_number); |
306 } | 306 } |
307 | 307 |
308 | |
309 SequenceNumberSet all_transmissions = *transmission_info.all_transmissions; | 308 SequenceNumberSet all_transmissions = *transmission_info.all_transmissions; |
310 SequenceNumberSet::reverse_iterator all_transmissions_it = | 309 SequenceNumberSet::reverse_iterator all_transmissions_it = |
311 all_transmissions.rbegin(); | 310 all_transmissions.rbegin(); |
312 QuicPacketSequenceNumber newest_transmission = *all_transmissions_it; | 311 QuicPacketSequenceNumber newest_transmission = *all_transmissions_it; |
313 if (newest_transmission != sequence_number) { | 312 if (newest_transmission != sequence_number) { |
314 ++stats_->packets_spuriously_retransmitted; | 313 ++stats_->packets_spuriously_retransmitted; |
315 } | 314 } |
316 | 315 |
317 bool has_cryto_handshake = HasCryptoHandshake( | 316 bool has_cryto_handshake = HasCryptoHandshake( |
318 unacked_packets_.GetTransmissionInfo(newest_transmission)); | 317 unacked_packets_.GetTransmissionInfo(newest_transmission)); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( | 520 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( |
522 const QuicCongestionFeedbackFrame& frame, | 521 const QuicCongestionFeedbackFrame& frame, |
523 const QuicTime& feedback_receive_time) { | 522 const QuicTime& feedback_receive_time) { |
524 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( | 523 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( |
525 frame, feedback_receive_time); | 524 frame, feedback_receive_time); |
526 } | 525 } |
527 | 526 |
528 void QuicSentPacketManager::MaybeRetransmitOnAckFrame( | 527 void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
529 const ReceivedPacketInfo& received_info, | 528 const ReceivedPacketInfo& received_info, |
530 const QuicTime& ack_receive_time) { | 529 const QuicTime& ack_receive_time) { |
531 // Go through all pending packets up to the largest observed and see if any | 530 // Go through all pending packets up to the largest observed and count nacks. |
532 // need to be retransmitted or lost. | |
533 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 531 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
534 it != unacked_packets_.end() && | 532 it != unacked_packets_.end() && |
535 it->first <= received_info.largest_observed; ++it) { | 533 it->first <= received_info.largest_observed; ++it) { |
536 if (!it->second.pending) { | 534 if (!it->second.pending) { |
537 continue; | 535 continue; |
538 } | 536 } |
539 QuicPacketSequenceNumber sequence_number = it->first; | 537 QuicPacketSequenceNumber sequence_number = it->first; |
540 DVLOG(1) << "still missing packet " << sequence_number; | 538 DVLOG(1) << "still missing packet " << sequence_number; |
541 // Acks must be handled previously, so ensure it's missing and not acked. | 539 // Acks must be handled previously, so ensure it's missing and not acked. |
542 DCHECK(IsAwaitingPacket(received_info, sequence_number)); | 540 DCHECK(IsAwaitingPacket(received_info, sequence_number)); |
543 | 541 |
544 // Consider it multiple nacks when there is a gap between the missing packet | 542 // Consider it multiple nacks when there is a gap between the missing packet |
545 // and the largest observed, since the purpose of a nack threshold is to | 543 // and the largest observed, since the purpose of a nack threshold is to |
546 // tolerate re-ordering. This handles both StretchAcks and Forward Acks. | 544 // tolerate re-ordering. This handles both StretchAcks and Forward Acks. |
547 // TODO(ianswett): This relies heavily on sequential reception of packets, | |
548 // and makes an assumption that the congestion control uses TCP style nacks. | |
549 size_t min_nacks = received_info.largest_observed - sequence_number; | 545 size_t min_nacks = received_info.largest_observed - sequence_number; |
550 unacked_packets_.NackPacket(sequence_number, min_nacks); | 546 unacked_packets_.NackPacket(sequence_number, min_nacks); |
551 } | 547 } |
552 | 548 |
| 549 InvokeLossDetection(ack_receive_time); |
| 550 } |
| 551 |
| 552 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
553 SequenceNumberSet lost_packets = | 553 SequenceNumberSet lost_packets = |
554 DetectLostPackets(unacked_packets_, | 554 loss_algorithm_->DetectLostPackets(unacked_packets_, |
555 ack_receive_time, | 555 time, |
556 received_info.largest_observed); | 556 largest_observed_, |
| 557 send_algorithm_->SmoothedRtt()); |
557 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); | 558 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
558 it != lost_packets.end(); ++it) { | 559 it != lost_packets.end(); ++it) { |
559 QuicPacketSequenceNumber sequence_number = *it; | 560 QuicPacketSequenceNumber sequence_number = *it; |
560 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | 561 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it |
561 // should be recorded as a loss to the send algorithm, but not retransmitted | 562 // should be recorded as a loss to the send algorithm, but not retransmitted |
562 // until it's known whether the FEC packet arrived. | 563 // until it's known whether the FEC packet arrived. |
563 ++stats_->packets_lost; | 564 ++stats_->packets_lost; |
564 send_algorithm_->OnPacketLost(sequence_number, ack_receive_time); | 565 send_algorithm_->OnPacketLost(sequence_number, time); |
565 OnPacketAbandoned(sequence_number); | 566 OnPacketAbandoned(sequence_number); |
566 | 567 |
567 if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { | 568 if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { |
568 MarkForRetransmission(sequence_number, NACK_RETRANSMISSION); | 569 MarkForRetransmission(sequence_number, NACK_RETRANSMISSION); |
569 } else { | 570 } else { |
570 // Since we will not retransmit this, we need to remove it from | 571 // Since we will not retransmit this, we need to remove it from |
571 // unacked_packets_. This is either the current transmission of | 572 // unacked_packets_. This is either the current transmission of |
572 // a packet whose previous transmission has been acked, or it | 573 // a packet whose previous transmission has been acked, or it |
573 // is a packet that has been TLP retransmitted. | 574 // is a packet that has been TLP retransmitted. |
574 unacked_packets_.RemovePacket(sequence_number); | 575 unacked_packets_.RemovePacket(sequence_number); |
575 } | 576 } |
576 } | 577 } |
577 } | 578 } |
578 | 579 |
579 // static | |
580 SequenceNumberSet QuicSentPacketManager::DetectLostPackets( | |
581 const QuicUnackedPacketMap& unacked_packets, | |
582 const QuicTime& time, | |
583 QuicPacketSequenceNumber largest_observed) { | |
584 SequenceNumberSet lost_packets; | |
585 | |
586 for (QuicUnackedPacketMap::const_iterator it = unacked_packets.begin(); | |
587 it != unacked_packets.end() && it->first <= largest_observed; ++it) { | |
588 if (!it->second.pending) { | |
589 continue; | |
590 } | |
591 size_t num_nacks_needed = kNumberOfNacksBeforeRetransmission; | |
592 // Check for early retransmit(RFC5827) when the last packet gets acked and | |
593 // the there are fewer than 4 pending packets. | |
594 // TODO(ianswett): Set a retransmission timer instead of losing the packet | |
595 // and retransmitting immediately. Also consider only invoking OnPacketLost | |
596 // and OnPacketAbandoned when they're actually retransmitted in case they | |
597 // arrive while queued for retransmission. | |
598 if (it->second.retransmittable_frames && | |
599 unacked_packets.largest_sent_packet() == largest_observed) { | |
600 num_nacks_needed = largest_observed - it->first; | |
601 } | |
602 | |
603 if (it->second.nack_count < num_nacks_needed) { | |
604 continue; | |
605 } | |
606 | |
607 lost_packets.insert(it->first); | |
608 } | |
609 | |
610 return lost_packets; | |
611 } | |
612 | |
613 void QuicSentPacketManager::MaybeUpdateRTT( | 580 void QuicSentPacketManager::MaybeUpdateRTT( |
614 const ReceivedPacketInfo& received_info, | 581 const ReceivedPacketInfo& received_info, |
615 const QuicTime& ack_receive_time) { | 582 const QuicTime& ack_receive_time) { |
616 if (!unacked_packets_.IsUnacked(received_info.largest_observed)) { | 583 if (!unacked_packets_.IsUnacked(received_info.largest_observed)) { |
617 return; | 584 return; |
618 } | 585 } |
619 // We calculate the RTT based on the highest ACKed sequence number, the lower | 586 // We calculate the RTT based on the highest ACKed sequence number, the lower |
620 // sequence numbers will include the ACK aggregation delay. | 587 // sequence numbers will include the ACK aggregation delay. |
621 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 588 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
622 unacked_packets_.GetTransmissionInfo(received_info.largest_observed); | 589 unacked_packets_.GetTransmissionInfo(received_info.largest_observed); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 return; | 731 return; |
765 } | 732 } |
766 | 733 |
767 using_pacing_ = true; | 734 using_pacing_ = true; |
768 send_algorithm_.reset( | 735 send_algorithm_.reset( |
769 new PacingSender(send_algorithm_.release(), | 736 new PacingSender(send_algorithm_.release(), |
770 QuicTime::Delta::FromMicroseconds(1))); | 737 QuicTime::Delta::FromMicroseconds(1))); |
771 } | 738 } |
772 | 739 |
773 } // namespace net | 740 } // namespace net |
OLD | NEW |