| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/congestion_control/tcp_cubic_sender_packets.h" | 5 #include "net/quic/congestion_control/tcp_cubic_sender_packets.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "net/quic/congestion_control/prr_sender.h" | 10 #include "net/quic/congestion_control/prr_sender.h" |
| 11 #include "net/quic/congestion_control/rtt_stats.h" | 11 #include "net/quic/congestion_control/rtt_stats.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_flags.h" | 15 #include "net/quic/quic_flags.h" |
| 16 | 16 |
| 17 using std::max; | 17 using std::max; |
| 18 using std::min; | 18 using std::min; |
| 19 | 19 |
| 20 namespace net { | 20 namespace net { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 // Constants based on TCP defaults. | 23 // Constants based on TCP defaults. |
| 24 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a | 24 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a |
| 25 // fast retransmission. The cwnd after a timeout is still 1. | 25 // fast retransmission. The cwnd after a timeout is still 1. |
| 26 const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS; | 26 const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS; |
| 27 const float kRenoBeta = 0.7f; // Reno backoff factor. | 27 const float kRenoBeta = 0.7f; // Reno backoff factor. |
| 28 const uint32_t kDefaultNumConnections = 2; // N-connection emulation. | 28 const uint32_t kDefaultNumConnections = 2; // N-connection emulation. |
| 29 const float kRateBasedExtraCwnd = 1.5f; // CWND for rate based sending. |
| 29 } // namespace | 30 } // namespace |
| 30 | 31 |
| 31 TcpCubicSenderBase::TcpCubicSenderBase(const QuicClock* clock, | 32 TcpCubicSenderBase::TcpCubicSenderBase(const QuicClock* clock, |
| 32 const RttStats* rtt_stats, | 33 const RttStats* rtt_stats, |
| 33 bool reno, | 34 bool reno, |
| 34 QuicConnectionStats* stats) | 35 QuicConnectionStats* stats) |
| 35 : rtt_stats_(rtt_stats), | 36 : rtt_stats_(rtt_stats), |
| 36 stats_(stats), | 37 stats_(stats), |
| 37 reno_(reno), | 38 reno_(reno), |
| 38 num_connections_(kDefaultNumConnections), | 39 num_connections_(kDefaultNumConnections), |
| 39 largest_sent_packet_number_(0), | 40 largest_sent_packet_number_(0), |
| 40 largest_acked_packet_number_(0), | 41 largest_acked_packet_number_(0), |
| 41 largest_sent_at_last_cutback_(0), | 42 largest_sent_at_last_cutback_(0), |
| 42 min4_mode_(false), | 43 min4_mode_(false), |
| 43 last_cutback_exited_slowstart_(false), | 44 last_cutback_exited_slowstart_(false), |
| 44 slow_start_large_reduction_(false), | 45 slow_start_large_reduction_(false), |
| 46 rate_based_sending_(false), |
| 45 no_prr_(false) {} | 47 no_prr_(false) {} |
| 46 | 48 |
| 47 TcpCubicSenderBase::~TcpCubicSenderBase() {} | 49 TcpCubicSenderBase::~TcpCubicSenderBase() {} |
| 48 | 50 |
| 49 void TcpCubicSenderBase::SetFromConfig(const QuicConfig& config, | 51 void TcpCubicSenderBase::SetFromConfig(const QuicConfig& config, |
| 50 Perspective perspective) { | 52 Perspective perspective) { |
| 51 if (perspective == Perspective::IS_SERVER) { | 53 if (perspective == Perspective::IS_SERVER) { |
| 52 if (config.HasReceivedConnectionOptions() && | 54 if (config.HasReceivedConnectionOptions() && |
| 53 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) { | 55 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) { |
| 54 // Initial window experiment. | 56 // Initial window experiment. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 83 if (config.HasReceivedConnectionOptions() && | 85 if (config.HasReceivedConnectionOptions() && |
| 84 ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) { | 86 ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) { |
| 85 // Slow Start Fast Exit experiment. | 87 // Slow Start Fast Exit experiment. |
| 86 slow_start_large_reduction_ = true; | 88 slow_start_large_reduction_ = true; |
| 87 } | 89 } |
| 88 if (FLAGS_quic_allow_noprr && config.HasReceivedConnectionOptions() && | 90 if (FLAGS_quic_allow_noprr && config.HasReceivedConnectionOptions() && |
| 89 ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) { | 91 ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) { |
| 90 // Use unity pacing instead of PRR. | 92 // Use unity pacing instead of PRR. |
| 91 no_prr_ = true; | 93 no_prr_ = true; |
| 92 } | 94 } |
| 95 if (FLAGS_quic_rate_based_sending && |
| 96 config.HasReceivedConnectionOptions() && |
| 97 ContainsQuicTag(config.ReceivedConnectionOptions(), kRATE)) { |
| 98 // Rate based sending experiment |
| 99 rate_based_sending_ = true; |
| 100 } |
| 93 } | 101 } |
| 94 } | 102 } |
| 95 | 103 |
| 96 void TcpCubicSenderBase::ResumeConnectionState( | 104 void TcpCubicSenderBase::ResumeConnectionState( |
| 97 const CachedNetworkParameters& cached_network_params, | 105 const CachedNetworkParameters& cached_network_params, |
| 98 bool max_bandwidth_resumption) { | 106 bool max_bandwidth_resumption) { |
| 99 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( | 107 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( |
| 100 max_bandwidth_resumption | 108 max_bandwidth_resumption |
| 101 ? cached_network_params.max_bandwidth_estimate_bytes_per_second() | 109 ? cached_network_params.max_bandwidth_estimate_bytes_per_second() |
| 102 : cached_network_params.bandwidth_estimate_bytes_per_second()); | 110 : cached_network_params.bandwidth_estimate_bytes_per_second()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 // PRR is used when in recovery. | 196 // PRR is used when in recovery. |
| 189 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, | 197 return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, |
| 190 GetSlowStartThreshold()); | 198 GetSlowStartThreshold()); |
| 191 } | 199 } |
| 192 if (GetCongestionWindow() > bytes_in_flight) { | 200 if (GetCongestionWindow() > bytes_in_flight) { |
| 193 return QuicTime::Delta::Zero(); | 201 return QuicTime::Delta::Zero(); |
| 194 } | 202 } |
| 195 if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) { | 203 if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) { |
| 196 return QuicTime::Delta::Zero(); | 204 return QuicTime::Delta::Zero(); |
| 197 } | 205 } |
| 206 if (rate_based_sending_ && |
| 207 GetCongestionWindow() * kRateBasedExtraCwnd > bytes_in_flight) { |
| 208 return QuicTime::Delta::Zero(); |
| 209 } |
| 198 return QuicTime::Delta::Infinite(); | 210 return QuicTime::Delta::Infinite(); |
| 199 } | 211 } |
| 200 | 212 |
| 201 QuicBandwidth TcpCubicSenderBase::PacingRate() const { | 213 QuicBandwidth TcpCubicSenderBase::PacingRate( |
| 214 QuicByteCount bytes_in_flight) const { |
| 202 // We pace at twice the rate of the underlying sender's bandwidth estimate | 215 // We pace at twice the rate of the underlying sender's bandwidth estimate |
| 203 // during slow start and 1.25x during congestion avoidance to ensure pacing | 216 // during slow start and 1.25x during congestion avoidance to ensure pacing |
| 204 // doesn't prevent us from filling the window. | 217 // doesn't prevent us from filling the window. |
| 205 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); | 218 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); |
| 206 if (srtt.IsZero()) { | 219 if (srtt.IsZero()) { |
| 207 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us()); | 220 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us()); |
| 208 } | 221 } |
| 209 const QuicBandwidth bandwidth = | 222 const QuicBandwidth bandwidth = |
| 210 QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt); | 223 QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt); |
| 224 if (rate_based_sending_ && bytes_in_flight > GetCongestionWindow()) { |
| 225 // Rate based sending allows sending more than CWND, but reduces the pacing |
| 226 // rate when the bytes in flight is more than the CWND to 75% of bandwidth. |
| 227 return bandwidth.Scale(0.75); |
| 228 } |
| 211 return bandwidth.Scale(InSlowStart() ? 2 | 229 return bandwidth.Scale(InSlowStart() ? 2 |
| 212 : (no_prr_ && InRecovery() ? 1 : 1.25)); | 230 : (no_prr_ && InRecovery() ? 1 : 1.25)); |
| 213 } | 231 } |
| 214 | 232 |
| 215 QuicBandwidth TcpCubicSenderBase::BandwidthEstimate() const { | 233 QuicBandwidth TcpCubicSenderBase::BandwidthEstimate() const { |
| 216 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); | 234 QuicTime::Delta srtt = rtt_stats_->smoothed_rtt(); |
| 217 if (srtt.IsZero()) { | 235 if (srtt.IsZero()) { |
| 218 // If we haven't measured an rtt, the bandwidth estimate is unknown. | 236 // If we haven't measured an rtt, the bandwidth estimate is unknown. |
| 219 return QuicBandwidth::Zero(); | 237 return QuicBandwidth::Zero(); |
| 220 } | 238 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 void TcpCubicSenderBase::OnConnectionMigration() { | 279 void TcpCubicSenderBase::OnConnectionMigration() { |
| 262 hybrid_slow_start_.Restart(); | 280 hybrid_slow_start_.Restart(); |
| 263 prr_ = PrrSender(); | 281 prr_ = PrrSender(); |
| 264 largest_sent_packet_number_ = 0; | 282 largest_sent_packet_number_ = 0; |
| 265 largest_acked_packet_number_ = 0; | 283 largest_acked_packet_number_ = 0; |
| 266 largest_sent_at_last_cutback_ = 0; | 284 largest_sent_at_last_cutback_ = 0; |
| 267 last_cutback_exited_slowstart_ = false; | 285 last_cutback_exited_slowstart_ = false; |
| 268 } | 286 } |
| 269 | 287 |
| 270 } // namespace net | 288 } // namespace net |
| OLD | NEW |