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/core/quic_sent_packet_manager.h" | 5 #include "net/quic/core/quic_sent_packet_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 static const size_t kMaxRetransmissions = 10; | 31 static const size_t kMaxRetransmissions = 10; |
32 // Maximum number of packets retransmitted upon an RTO. | 32 // Maximum number of packets retransmitted upon an RTO. |
33 static const size_t kMaxRetransmissionsOnTimeout = 2; | 33 static const size_t kMaxRetransmissionsOnTimeout = 2; |
34 // Minimum number of consecutive RTOs before path is considered to be degrading. | 34 // Minimum number of consecutive RTOs before path is considered to be degrading. |
35 const size_t kMinTimeoutsBeforePathDegrading = 2; | 35 const size_t kMinTimeoutsBeforePathDegrading = 2; |
36 | 36 |
37 // Ensure the handshake timer isnt't faster than 10ms. | 37 // Ensure the handshake timer isnt't faster than 10ms. |
38 // This limits the tenth retransmitted packet to 10s after the initial CHLO. | 38 // This limits the tenth retransmitted packet to 10s after the initial CHLO. |
39 static const int64_t kMinHandshakeTimeoutMs = 10; | 39 static const int64_t kMinHandshakeTimeoutMs = 10; |
40 | 40 |
| 41 // Ensure the handshake timer isnt't faster than 25ms. |
| 42 static const int64_t kConservativeMinHandshakeTimeoutMs = kMaxDelayedAckTimeMs; |
| 43 |
41 // Sends up to two tail loss probes before firing an RTO, | 44 // Sends up to two tail loss probes before firing an RTO, |
42 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 45 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
43 static const size_t kDefaultMaxTailLossProbes = 2; | 46 static const size_t kDefaultMaxTailLossProbes = 2; |
44 | 47 |
45 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { | 48 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { |
46 DCHECK(!transmission_info.has_crypto_handshake || | 49 DCHECK(!transmission_info.has_crypto_handshake || |
47 !transmission_info.retransmittable_frames.empty()); | 50 !transmission_info.retransmittable_frames.empty()); |
48 return transmission_info.has_crypto_handshake; | 51 return transmission_info.has_crypto_handshake; |
49 } | 52 } |
50 | 53 |
(...skipping 27 matching lines...) Expand all Loading... |
78 first_rto_transmission_(0), | 81 first_rto_transmission_(0), |
79 consecutive_rto_count_(0), | 82 consecutive_rto_count_(0), |
80 consecutive_tlp_count_(0), | 83 consecutive_tlp_count_(0), |
81 consecutive_crypto_retransmission_count_(0), | 84 consecutive_crypto_retransmission_count_(0), |
82 pending_timer_transmission_count_(0), | 85 pending_timer_transmission_count_(0), |
83 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 86 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
84 enable_half_rtt_tail_loss_probe_(false), | 87 enable_half_rtt_tail_loss_probe_(false), |
85 using_pacing_(false), | 88 using_pacing_(false), |
86 use_new_rto_(false), | 89 use_new_rto_(false), |
87 undo_pending_retransmits_(false), | 90 undo_pending_retransmits_(false), |
| 91 conservative_handshake_retransmits_(false), |
88 largest_newly_acked_(0), | 92 largest_newly_acked_(0), |
89 largest_mtu_acked_(0), | 93 largest_mtu_acked_(0), |
90 handshake_confirmed_(false) { | 94 handshake_confirmed_(false) { |
91 SetSendAlgorithm(congestion_control_type); | 95 SetSendAlgorithm(congestion_control_type); |
92 } | 96 } |
93 | 97 |
94 QuicSentPacketManager::~QuicSentPacketManager() {} | 98 QuicSentPacketManager::~QuicSentPacketManager() {} |
95 | 99 |
96 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 100 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
97 if (config.HasReceivedInitialRoundTripTimeUs() && | 101 if (config.HasReceivedInitialRoundTripTimeUs() && |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) { | 148 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) { |
145 general_loss_algorithm_.SetLossDetectionType(kTime); | 149 general_loss_algorithm_.SetLossDetectionType(kTime); |
146 } | 150 } |
147 if (config.HasReceivedConnectionOptions() && | 151 if (config.HasReceivedConnectionOptions() && |
148 ContainsQuicTag(config.ReceivedConnectionOptions(), kATIM)) { | 152 ContainsQuicTag(config.ReceivedConnectionOptions(), kATIM)) { |
149 general_loss_algorithm_.SetLossDetectionType(kAdaptiveTime); | 153 general_loss_algorithm_.SetLossDetectionType(kAdaptiveTime); |
150 } | 154 } |
151 if (config.HasClientSentConnectionOption(kUNDO, perspective_)) { | 155 if (config.HasClientSentConnectionOption(kUNDO, perspective_)) { |
152 undo_pending_retransmits_ = true; | 156 undo_pending_retransmits_ = true; |
153 } | 157 } |
| 158 if (FLAGS_quic_conservative_handshake_retransmits && |
| 159 config.HasClientSentConnectionOption(kCONH, perspective_)) { |
| 160 conservative_handshake_retransmits_ = true; |
| 161 } |
154 send_algorithm_->SetFromConfig(config, perspective_); | 162 send_algorithm_->SetFromConfig(config, perspective_); |
155 | 163 |
156 if (network_change_visitor_ != nullptr) { | 164 if (network_change_visitor_ != nullptr) { |
157 network_change_visitor_->OnCongestionChange(); | 165 network_change_visitor_->OnCongestionChange(); |
158 } | 166 } |
159 } | 167 } |
160 | 168 |
161 void QuicSentPacketManager::ResumeConnectionState( | 169 void QuicSentPacketManager::ResumeConnectionState( |
162 const CachedNetworkParameters& cached_network_params, | 170 const CachedNetworkParameters& cached_network_params, |
163 bool max_bandwidth_resumption) { | 171 bool max_bandwidth_resumption) { |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 } | 817 } |
810 DCHECK(false); | 818 DCHECK(false); |
811 return QuicTime::Zero(); | 819 return QuicTime::Zero(); |
812 } | 820 } |
813 | 821 |
814 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() | 822 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() |
815 const { | 823 const { |
816 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive | 824 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive |
817 // because crypto handshake messages don't incur a delayed ack time. | 825 // because crypto handshake messages don't incur a delayed ack time. |
818 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); | 826 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); |
| 827 int64_t delay_ms; |
819 if (srtt.IsZero()) { | 828 if (srtt.IsZero()) { |
820 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); | 829 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); |
821 } | 830 } |
822 int64_t delay_ms = max(kMinHandshakeTimeoutMs, | 831 if (conservative_handshake_retransmits_) { |
823 static_cast<int64_t>(1.5 * srtt.ToMilliseconds())); | 832 delay_ms = max(kConservativeMinHandshakeTimeoutMs, |
| 833 static_cast<int64_t>(2 * srtt.ToMilliseconds())); |
| 834 } else { |
| 835 delay_ms = max(kMinHandshakeTimeoutMs, |
| 836 static_cast<int64_t>(1.5 * srtt.ToMilliseconds())); |
| 837 } |
824 return QuicTime::Delta::FromMilliseconds( | 838 return QuicTime::Delta::FromMilliseconds( |
825 delay_ms << consecutive_crypto_retransmission_count_); | 839 delay_ms << consecutive_crypto_retransmission_count_); |
826 } | 840 } |
827 | 841 |
828 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { | 842 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { |
829 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); | 843 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); |
830 if (srtt.IsZero()) { | 844 if (srtt.IsZero()) { |
831 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); | 845 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); |
832 } | 846 } |
833 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) { | 847 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) { |
834 return QuicTime::Delta::FromMilliseconds( | 848 return QuicTime::Delta::FromMilliseconds( |
835 max(kMinTailLossProbeTimeoutMs, | 849 max(kMinTailLossProbeTimeoutMs, |
836 static_cast<int64_t>(0.5 * srtt.ToMilliseconds()))); | 850 static_cast<int64_t>(0.5 * srtt.ToMilliseconds()))); |
837 } | 851 } |
838 if (!unacked_packets_.HasMultipleInFlightPackets()) { | 852 if (!unacked_packets_.HasMultipleInFlightPackets()) { |
839 return std::max(2 * srtt, 1.5 * srtt + QuicTime::Delta::FromMilliseconds( | 853 return std::max(2 * srtt, 1.5 * srtt + QuicTime::Delta::FromMilliseconds( |
840 kMinRetransmissionTimeMs / 2)); | 854 kMinRetransmissionTimeMs / 2)); |
841 } | 855 } |
842 return QuicTime::Delta::FromMilliseconds( | 856 return QuicTime::Delta::FromMilliseconds( |
843 max(kMinTailLossProbeTimeoutMs, | 857 max(kMinTailLossProbeTimeoutMs, |
844 static_cast<int64_t>(2 * srtt.ToMilliseconds()))); | 858 static_cast<int64_t>(2 * srtt.ToMilliseconds()))); |
845 } | 859 } |
846 | 860 |
847 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { | 861 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { |
848 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); | 862 QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero(); |
849 if (retransmission_delay.IsZero()) { | 863 if (rtt_stats_.smoothed_rtt().IsZero()) { |
850 // We are in the initial state, use default timeout values. | 864 // We are in the initial state, use default timeout values. |
851 retransmission_delay = | 865 retransmission_delay = |
852 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 866 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
853 } else if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { | 867 } else { |
854 retransmission_delay = | 868 retransmission_delay = |
855 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); | 869 rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation(); |
| 870 if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { |
| 871 retransmission_delay = |
| 872 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); |
| 873 } |
856 } | 874 } |
857 | 875 |
858 // Calculate exponential back off. | 876 // Calculate exponential back off. |
859 retransmission_delay = | 877 retransmission_delay = |
860 retransmission_delay * | 878 retransmission_delay * |
861 (1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions)); | 879 (1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions)); |
862 | 880 |
863 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { | 881 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { |
864 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); | 882 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); |
865 } | 883 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 // Rtt and cwnd do not need to be reset when the peer address change is | 955 // Rtt and cwnd do not need to be reset when the peer address change is |
938 // considered to be caused by NATs. | 956 // considered to be caused by NATs. |
939 return; | 957 return; |
940 } | 958 } |
941 consecutive_rto_count_ = 0; | 959 consecutive_rto_count_ = 0; |
942 consecutive_tlp_count_ = 0; | 960 consecutive_tlp_count_ = 0; |
943 rtt_stats_.OnConnectionMigration(); | 961 rtt_stats_.OnConnectionMigration(); |
944 send_algorithm_->OnConnectionMigration(); | 962 send_algorithm_->OnConnectionMigration(); |
945 } | 963 } |
946 | 964 |
947 | |
948 void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) { | 965 void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) { |
949 debug_delegate_ = debug_delegate; | 966 debug_delegate_ = debug_delegate; |
950 } | 967 } |
951 | 968 |
952 QuicPacketNumber QuicSentPacketManager::GetLargestObserved(QuicPathId) const { | 969 QuicPacketNumber QuicSentPacketManager::GetLargestObserved(QuicPathId) const { |
953 return unacked_packets_.largest_observed(); | 970 return unacked_packets_.largest_observed(); |
954 } | 971 } |
955 | 972 |
956 QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(QuicPathId) const { | 973 QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(QuicPathId) const { |
957 return unacked_packets_.largest_sent_packet(); | 974 return unacked_packets_.largest_sent_packet(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 | 1006 |
990 void QuicSentPacketManager::RemoveObsoletePackets() { | 1007 void QuicSentPacketManager::RemoveObsoletePackets() { |
991 unacked_packets_.RemoveObsoletePackets(); | 1008 unacked_packets_.RemoveObsoletePackets(); |
992 } | 1009 } |
993 | 1010 |
994 void QuicSentPacketManager::OnApplicationLimited() { | 1011 void QuicSentPacketManager::OnApplicationLimited() { |
995 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); | 1012 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); |
996 } | 1013 } |
997 | 1014 |
998 } // namespace net | 1015 } // namespace net |
OLD | NEW |