| 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" |
| 11 #include "net/quic/congestion_control/pacing_sender.h" | 11 #include "net/quic/congestion_control/pacing_sender.h" |
| 12 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
| 13 #include "net/quic/proto/cached_network_parameters.pb.h" | 13 #include "net/quic/proto/cached_network_parameters.pb.h" |
| 14 #include "net/quic/quic_bug_tracker.h" | 14 #include "net/quic/quic_bug_tracker.h" |
| 15 #include "net/quic/quic_connection_stats.h" | 15 #include "net/quic/quic_connection_stats.h" |
| 16 #include "net/quic/quic_flags.h" | 16 #include "net/quic/quic_flags.h" |
| 17 #include "net/quic/quic_utils_chromium.h" | 17 #include "net/quic/quic_utils_chromium.h" |
| 18 | 18 |
| 19 using std::max; | 19 using std::max; |
| 20 using std::min; | 20 using std::min; |
| 21 using std::pair; |
| 21 | 22 |
| 22 namespace net { | 23 namespace net { |
| 23 | 24 |
| 24 // The length of the recent min rtt window in seconds. Windowing is disabled for | 25 // The length of the recent min rtt window in seconds. Windowing is disabled for |
| 25 // values less than or equal to 0. | 26 // values less than or equal to 0. |
| 26 int32_t FLAGS_quic_recent_min_rtt_window_s = 60; | 27 int32_t FLAGS_quic_recent_min_rtt_window_s = 60; |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 static const int64_t kDefaultRetransmissionTimeMs = 500; | 30 static const int64_t kDefaultRetransmissionTimeMs = 500; |
| 30 // TCP RFC calls for 1 second RTO however Linux differs from this default and | 31 // TCP RFC calls for 1 second RTO however Linux differs from this default and |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 least_packet_awaited_by_peer_(1), | 90 least_packet_awaited_by_peer_(1), |
| 90 first_rto_transmission_(0), | 91 first_rto_transmission_(0), |
| 91 consecutive_rto_count_(0), | 92 consecutive_rto_count_(0), |
| 92 consecutive_tlp_count_(0), | 93 consecutive_tlp_count_(0), |
| 93 consecutive_crypto_retransmission_count_(0), | 94 consecutive_crypto_retransmission_count_(0), |
| 94 pending_timer_transmission_count_(0), | 95 pending_timer_transmission_count_(0), |
| 95 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 96 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
| 96 enable_half_rtt_tail_loss_probe_(false), | 97 enable_half_rtt_tail_loss_probe_(false), |
| 97 using_pacing_(false), | 98 using_pacing_(false), |
| 98 use_new_rto_(false), | 99 use_new_rto_(false), |
| 99 handshake_confirmed_(false), | 100 handshake_confirmed_(false) {} |
| 100 use_general_loss_algorithm_(FLAGS_quic_general_loss_algorithm) {} | |
| 101 | 101 |
| 102 QuicSentPacketManager::~QuicSentPacketManager() {} | 102 QuicSentPacketManager::~QuicSentPacketManager() {} |
| 103 | 103 |
| 104 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 104 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
| 105 if (config.HasReceivedInitialRoundTripTimeUs() && | 105 if (config.HasReceivedInitialRoundTripTimeUs() && |
| 106 config.ReceivedInitialRoundTripTimeUs() > 0) { | 106 config.ReceivedInitialRoundTripTimeUs() > 0) { |
| 107 rtt_stats_.set_initial_rtt_us( | 107 rtt_stats_.set_initial_rtt_us( |
| 108 max(kMinInitialRoundTripTimeUs, | 108 max(kMinInitialRoundTripTimeUs, |
| 109 min(kMaxInitialRoundTripTimeUs, | 109 min(kMaxInitialRoundTripTimeUs, |
| 110 config.ReceivedInitialRoundTripTimeUs()))); | 110 config.ReceivedInitialRoundTripTimeUs()))); |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 } | 713 } |
| 714 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | 714 if (consecutive_tlp_count_ < max_tail_loss_probes_) { |
| 715 if (unacked_packets_.HasUnackedRetransmittableFrames()) { | 715 if (unacked_packets_.HasUnackedRetransmittableFrames()) { |
| 716 return TLP_MODE; | 716 return TLP_MODE; |
| 717 } | 717 } |
| 718 } | 718 } |
| 719 return RTO_MODE; | 719 return RTO_MODE; |
| 720 } | 720 } |
| 721 | 721 |
| 722 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { | 722 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
| 723 if (use_general_loss_algorithm_) { | 723 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_, |
| 724 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_, | 724 &packets_lost_); |
| 725 &packets_lost_); | 725 for (const pair<QuicPacketNumber, QuicByteCount>& pair : packets_lost_) { |
| 726 for (const std::pair<QuicPacketNumber, QuicByteCount>& pair : | 726 ++stats_->packets_lost; |
| 727 packets_lost_) { | 727 if (FLAGS_quic_log_loss_event && debug_delegate_ != nullptr) { |
| 728 ++stats_->packets_lost; | 728 debug_delegate_->OnPacketLoss(pair.first, LOSS_RETRANSMISSION, time); |
| 729 if (FLAGS_quic_log_loss_event && debug_delegate_ != nullptr) { | 729 } |
| 730 debug_delegate_->OnPacketLoss(pair.first, LOSS_RETRANSMISSION, time); | |
| 731 } | |
| 732 | 730 |
| 733 // TODO(ianswett): This could be optimized. | 731 // TODO(ianswett): This could be optimized. |
| 734 if (unacked_packets_.HasRetransmittableFrames(pair.first)) { | 732 if (unacked_packets_.HasRetransmittableFrames(pair.first)) { |
| 735 MarkForRetransmission(pair.first, LOSS_RETRANSMISSION); | 733 MarkForRetransmission(pair.first, LOSS_RETRANSMISSION); |
| 736 } else { | |
| 737 // Since we will not retransmit this, we need to remove it from | |
| 738 // unacked_packets_. This is either the current transmission of | |
| 739 // a packet whose previous transmission has been acked, a packet that | |
| 740 // has been TLP retransmitted, or an FEC packet. | |
| 741 unacked_packets_.RemoveFromInFlight(pair.first); | |
| 742 } | |
| 743 } | |
| 744 return; | |
| 745 } | |
| 746 PacketNumberSet lost_packets = loss_algorithm_->DetectLostPackets( | |
| 747 unacked_packets_, time, unacked_packets_.largest_observed(), rtt_stats_); | |
| 748 for (PacketNumberSet::const_iterator it = lost_packets.begin(); | |
| 749 it != lost_packets.end(); ++it) { | |
| 750 QuicPacketNumber packet_number = *it; | |
| 751 const TransmissionInfo& transmission_info = | |
| 752 unacked_packets_.GetTransmissionInfo(packet_number); | |
| 753 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | |
| 754 // should be recorded as a loss to the send algorithm, but not retransmitted | |
| 755 // until it's known whether the FEC packet arrived. | |
| 756 ++stats_->packets_lost; | |
| 757 packets_lost_.push_back( | |
| 758 std::make_pair(packet_number, transmission_info.bytes_sent)); | |
| 759 DVLOG(1) << ENDPOINT << "Lost packet " << packet_number; | |
| 760 | |
| 761 if (!transmission_info.retransmittable_frames.empty()) { | |
| 762 MarkForRetransmission(packet_number, LOSS_RETRANSMISSION); | |
| 763 } else { | 734 } else { |
| 764 // Since we will not retransmit this, we need to remove it from | 735 // Since we will not retransmit this, we need to remove it from |
| 765 // unacked_packets_. This is either the current transmission of | 736 // unacked_packets_. This is either the current transmission of |
| 766 // a packet whose previous transmission has been acked, a packet that has | 737 // a packet whose previous transmission has been acked, a packet that |
| 767 // been TLP retransmitted, or an FEC packet. | 738 // has been TLP retransmitted, or an FEC packet. |
| 768 unacked_packets_.RemoveFromInFlight(packet_number); | 739 unacked_packets_.RemoveFromInFlight(pair.first); |
| 769 } | 740 } |
| 770 } | 741 } |
| 771 } | 742 } |
| 772 | 743 |
| 773 bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame, | 744 bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame, |
| 774 const QuicTime& ack_receive_time) { | 745 const QuicTime& ack_receive_time) { |
| 775 // We rely on ack_delay_time to compute an RTT estimate, so we | 746 // We rely on ack_delay_time to compute an RTT estimate, so we |
| 776 // only update rtt when the largest observed gets acked. | 747 // only update rtt when the largest observed gets acked. |
| 777 // NOTE: If ack is a truncated ack, then the largest observed is in fact | 748 // NOTE: If ack is a truncated ack, then the largest observed is in fact |
| 778 // unacked, and may cause an RTT sample to be taken. | 749 // unacked, and may cause an RTT sample to be taken. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( | 975 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( |
| 1005 QuicPacketNumber packet_number) { | 976 QuicPacketNumber packet_number) { |
| 1006 return unacked_packets_.GetMutableTransmissionInfo(packet_number); | 977 return unacked_packets_.GetMutableTransmissionInfo(packet_number); |
| 1007 } | 978 } |
| 1008 | 979 |
| 1009 void QuicSentPacketManager::RemoveObsoletePackets() { | 980 void QuicSentPacketManager::RemoveObsoletePackets() { |
| 1010 unacked_packets_.RemoveObsoletePackets(); | 981 unacked_packets_.RemoveObsoletePackets(); |
| 1011 } | 982 } |
| 1012 | 983 |
| 1013 } // namespace net | 984 } // namespace net |
| OLD | NEW |