| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 LossDetectionType loss_type) | 60 LossDetectionType loss_type) |
| 61 : unacked_packets_(), | 61 : unacked_packets_(), |
| 62 is_server_(is_server), | 62 is_server_(is_server), |
| 63 clock_(clock), | 63 clock_(clock), |
| 64 stats_(stats), | 64 stats_(stats), |
| 65 debug_delegate_(NULL), | 65 debug_delegate_(NULL), |
| 66 send_algorithm_( | 66 send_algorithm_( |
| 67 SendAlgorithmInterface::Create(clock, &rtt_stats_, type, stats)), | 67 SendAlgorithmInterface::Create(clock, &rtt_stats_, type, stats)), |
| 68 loss_algorithm_(LossDetectionInterface::Create(loss_type)), | 68 loss_algorithm_(LossDetectionInterface::Create(loss_type)), |
| 69 largest_observed_(0), | 69 largest_observed_(0), |
| 70 first_rto_transmission_(0), |
| 70 consecutive_rto_count_(0), | 71 consecutive_rto_count_(0), |
| 71 consecutive_tlp_count_(0), | 72 consecutive_tlp_count_(0), |
| 72 consecutive_crypto_retransmission_count_(0), | 73 consecutive_crypto_retransmission_count_(0), |
| 73 pending_tlp_transmission_(false), | 74 pending_tlp_transmission_(false), |
| 74 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 75 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
| 75 using_pacing_(false) { | 76 using_pacing_(false) { |
| 76 } | 77 } |
| 77 | 78 |
| 78 QuicSentPacketManager::~QuicSentPacketManager() { | 79 QuicSentPacketManager::~QuicSentPacketManager() { |
| 79 } | 80 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 if (ContainsKey(pending_retransmissions_, sequence_number)) { | 289 if (ContainsKey(pending_retransmissions_, sequence_number)) { |
| 289 return; | 290 return; |
| 290 } | 291 } |
| 291 | 292 |
| 292 pending_retransmissions_[sequence_number] = transmission_type; | 293 pending_retransmissions_[sequence_number] = transmission_type; |
| 293 } | 294 } |
| 294 | 295 |
| 295 void QuicSentPacketManager::RecordSpuriousRetransmissions( | 296 void QuicSentPacketManager::RecordSpuriousRetransmissions( |
| 296 const SequenceNumberSet& all_transmissions, | 297 const SequenceNumberSet& all_transmissions, |
| 297 QuicPacketSequenceNumber acked_sequence_number) { | 298 QuicPacketSequenceNumber acked_sequence_number) { |
| 299 if (acked_sequence_number < first_rto_transmission_) { |
| 300 // Cancel all pending RTO transmissions and restore their in flight status. |
| 301 // Replace SRTT with latest_rtt and increase the variance to prevent |
| 302 // a spurious RTO from happening again. |
| 303 rtt_stats_.ExpireSmoothedMetrics(); |
| 304 for (PendingRetransmissionMap::const_iterator it = |
| 305 pending_retransmissions_.begin(); |
| 306 it != pending_retransmissions_.end(); ++it) { |
| 307 DCHECK_EQ(it->second, RTO_RETRANSMISSION); |
| 308 unacked_packets_.RestoreInFlight(it->first); |
| 309 } |
| 310 pending_retransmissions_.clear(); |
| 311 send_algorithm_->RevertRetransmissionTimeout(); |
| 312 first_rto_transmission_ = 0; |
| 313 ++stats_->spurious_rto_count; |
| 314 } |
| 298 for (SequenceNumberSet::const_iterator | 315 for (SequenceNumberSet::const_iterator |
| 299 it = all_transmissions.upper_bound(acked_sequence_number), | 316 it = all_transmissions.upper_bound(acked_sequence_number), |
| 300 end = all_transmissions.end(); | 317 end = all_transmissions.end(); |
| 301 it != end; | 318 it != end; |
| 302 ++it) { | 319 ++it) { |
| 303 const TransmissionInfo& retransmit_info = | 320 const TransmissionInfo& retransmit_info = |
| 304 unacked_packets_.GetTransmissionInfo(*it); | 321 unacked_packets_.GetTransmissionInfo(*it); |
| 305 | 322 |
| 306 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; | 323 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; |
| 307 ++stats_->packets_spuriously_retransmitted; | 324 ++stats_->packets_spuriously_retransmitted; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 if (frames != NULL) { | 583 if (frames != NULL) { |
| 567 packets_retransmitted = true; | 584 packets_retransmitted = true; |
| 568 MarkForRetransmission(sequence_number, RTO_RETRANSMISSION); | 585 MarkForRetransmission(sequence_number, RTO_RETRANSMISSION); |
| 569 } else { | 586 } else { |
| 570 unacked_packets_.RemoveFromInFlight(sequence_number); | 587 unacked_packets_.RemoveFromInFlight(sequence_number); |
| 571 } | 588 } |
| 572 } | 589 } |
| 573 | 590 |
| 574 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); | 591 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); |
| 575 if (packets_retransmitted) { | 592 if (packets_retransmitted) { |
| 593 if (consecutive_rto_count_ == 0) { |
| 594 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1; |
| 595 } |
| 576 ++consecutive_rto_count_; | 596 ++consecutive_rto_count_; |
| 577 } | 597 } |
| 578 } | 598 } |
| 579 | 599 |
| 580 QuicSentPacketManager::RetransmissionTimeoutMode | 600 QuicSentPacketManager::RetransmissionTimeoutMode |
| 581 QuicSentPacketManager::GetRetransmissionMode() const { | 601 QuicSentPacketManager::GetRetransmissionMode() const { |
| 582 DCHECK(unacked_packets_.HasInFlightPackets()); | 602 DCHECK(unacked_packets_.HasInFlightPackets()); |
| 583 if (unacked_packets_.HasPendingCryptoPackets()) { | 603 if (unacked_packets_.HasPendingCryptoPackets()) { |
| 584 return HANDSHAKE_MODE; | 604 return HANDSHAKE_MODE; |
| 585 } | 605 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 // Base the updated timer on the send time of the last packet. | 718 // Base the updated timer on the send time of the last packet. |
| 699 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); | 719 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); |
| 700 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); | 720 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); |
| 701 // Ensure the TLP timer never gets set to a time in the past. | 721 // Ensure the TLP timer never gets set to a time in the past. |
| 702 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); | 722 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); |
| 703 } | 723 } |
| 704 case RTO_MODE: { | 724 case RTO_MODE: { |
| 705 // The RTO is based on the first outstanding packet. | 725 // The RTO is based on the first outstanding packet. |
| 706 const QuicTime sent_time = | 726 const QuicTime sent_time = |
| 707 unacked_packets_.GetFirstInFlightPacketSentTime(); | 727 unacked_packets_.GetFirstInFlightPacketSentTime(); |
| 708 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); | 728 QuicTime rto_time = sent_time.Add(GetRetransmissionDelay()); |
| 709 // Always wait at least 1.5 * RTT from now. | 729 // Wait for TLP packets to be acked before an RTO fires. |
| 710 QuicTime min_timeout = clock_->ApproximateNow().Add( | 730 QuicTime tlp_time = |
| 711 rtt_stats_.SmoothedRtt().Multiply(1.5)); | 731 unacked_packets_.GetLastPacketSentTime().Add(GetTailLossProbeDelay()); |
| 712 | 732 return QuicTime::Max(tlp_time, rto_time); |
| 713 return QuicTime::Max(min_timeout, rto_timeout); | |
| 714 } | 733 } |
| 715 } | 734 } |
| 716 DCHECK(false); | 735 DCHECK(false); |
| 717 return QuicTime::Zero(); | 736 return QuicTime::Zero(); |
| 718 } | 737 } |
| 719 | 738 |
| 720 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() | 739 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() |
| 721 const { | 740 const { |
| 722 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive | 741 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive |
| 723 // because crypto handshake messages don't incur a delayed ack time. | 742 // because crypto handshake messages don't incur a delayed ack time. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 } | 801 } |
| 783 | 802 |
| 784 // Set up a pacing sender with a 5 millisecond alarm granularity. | 803 // Set up a pacing sender with a 5 millisecond alarm granularity. |
| 785 using_pacing_ = true; | 804 using_pacing_ = true; |
| 786 send_algorithm_.reset( | 805 send_algorithm_.reset( |
| 787 new PacingSender(send_algorithm_.release(), | 806 new PacingSender(send_algorithm_.release(), |
| 788 QuicTime::Delta::FromMilliseconds(5))); | 807 QuicTime::Delta::FromMilliseconds(5))); |
| 789 } | 808 } |
| 790 | 809 |
| 791 } // namespace net | 810 } // namespace net |
| OLD | NEW |