OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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_bytes_sender.h" | 5 #include "net/quic/congestion_control/tcp_cubic_bytes_sender.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "net/quic/congestion_control/prr_sender.h" | 9 #include "net/quic/congestion_control/prr_sender.h" |
10 #include "net/quic/congestion_control/rtt_stats.h" | 10 #include "net/quic/congestion_control/rtt_stats.h" |
11 #include "net/quic/crypto/crypto_protocol.h" | 11 #include "net/quic/crypto/crypto_protocol.h" |
12 | 12 |
13 using std::max; | 13 using std::max; |
14 using std::min; | 14 using std::min; |
15 | 15 |
16 namespace net { | 16 namespace net { |
17 | 17 |
18 namespace { | 18 namespace { |
19 // Constants based on TCP defaults. | 19 // Constants based on TCP defaults. |
20 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a | 20 // The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a |
21 // fast retransmission. | 21 // fast retransmission. |
22 const QuicByteCount kMinimumCongestionWindow = 2 * kDefaultTCPMSS; | 22 const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS; |
23 const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; | 23 const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; |
24 const int kMaxBurstLength = 3; | 24 const int kMaxBurstLength = 3; |
25 const float kRenoBeta = 0.7f; // Reno backoff factor. | 25 const float kRenoBeta = 0.7f; // Reno backoff factor. |
26 const uint32 kDefaultNumConnections = 2; // N-connection emulation. | 26 const uint32 kDefaultNumConnections = 2; // N-connection emulation. |
27 } // namespace | 27 } // namespace |
28 | 28 |
29 TcpCubicBytesSender::TcpCubicBytesSender( | 29 TcpCubicBytesSender::TcpCubicBytesSender( |
30 const QuicClock* clock, | 30 const QuicClock* clock, |
31 const RttStats* rtt_stats, | 31 const RttStats* rtt_stats, |
32 bool reno, | 32 bool reno, |
33 QuicPacketCount initial_tcp_congestion_window, | 33 QuicPacketCount initial_tcp_congestion_window, |
34 QuicConnectionStats* stats) | 34 QuicConnectionStats* stats) |
35 : hybrid_slow_start_(clock), | 35 : hybrid_slow_start_(clock), |
36 cubic_(clock), | 36 cubic_(clock), |
37 rtt_stats_(rtt_stats), | 37 rtt_stats_(rtt_stats), |
38 stats_(stats), | 38 stats_(stats), |
39 reno_(reno), | 39 reno_(reno), |
40 num_connections_(kDefaultNumConnections), | 40 num_connections_(kDefaultNumConnections), |
41 num_acked_packets_(0), | 41 num_acked_packets_(0), |
42 largest_sent_sequence_number_(0), | 42 largest_sent_sequence_number_(0), |
43 largest_acked_sequence_number_(0), | 43 largest_acked_sequence_number_(0), |
44 largest_sent_at_last_cutback_(0), | 44 largest_sent_at_last_cutback_(0), |
45 congestion_window_(initial_tcp_congestion_window * kMaxSegmentSize), | 45 congestion_window_(initial_tcp_congestion_window * kMaxSegmentSize), |
| 46 min_congestion_window_(kDefaultMinimumCongestionWindow), |
46 slowstart_threshold_(std::numeric_limits<uint64>::max()), | 47 slowstart_threshold_(std::numeric_limits<uint64>::max()), |
47 last_cutback_exited_slowstart_(false), | 48 last_cutback_exited_slowstart_(false), |
48 clock_(clock) { | 49 clock_(clock) { |
49 } | 50 } |
50 | 51 |
51 TcpCubicBytesSender::~TcpCubicBytesSender() { | 52 TcpCubicBytesSender::~TcpCubicBytesSender() { |
52 } | 53 } |
53 | 54 |
54 void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config, | 55 void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config, |
55 Perspective perspective, | 56 Perspective perspective, |
56 bool using_pacing) { | 57 bool using_pacing) { |
57 if (perspective == Perspective::IS_SERVER) { | 58 if (perspective == Perspective::IS_SERVER) { |
58 if (config.HasReceivedConnectionOptions() && | 59 if (config.HasReceivedConnectionOptions() && |
59 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) { | 60 ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) { |
60 // Initial window experiment. | 61 // Initial window experiment. |
61 congestion_window_ = 10 * kMaxSegmentSize; | 62 congestion_window_ = 10 * kMaxSegmentSize; |
62 } | 63 } |
| 64 if (config.HasReceivedConnectionOptions() && |
| 65 ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) { |
| 66 // Min CWND experiment. |
| 67 min_congestion_window_ = kMaxSegmentSize; |
| 68 } |
63 if (using_pacing) { | 69 if (using_pacing) { |
64 // Disable the ack train mode in hystart when pacing is enabled, since it | 70 // Disable the ack train mode in hystart when pacing is enabled, since it |
65 // may be falsely triggered. | 71 // may be falsely triggered. |
66 hybrid_slow_start_.set_ack_train_detection(false); | 72 hybrid_slow_start_.set_ack_train_detection(false); |
67 } | 73 } |
68 } | 74 } |
69 } | 75 } |
70 | 76 |
71 bool TcpCubicBytesSender::ResumeConnectionState( | 77 bool TcpCubicBytesSender::ResumeConnectionState( |
72 const CachedNetworkParameters& cached_network_params) { | 78 const CachedNetworkParameters& cached_network_params) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 prr_.OnPacketLost(bytes_in_flight); | 172 prr_.OnPacketLost(bytes_in_flight); |
167 | 173 |
168 if (reno_) { | 174 if (reno_) { |
169 congestion_window_ = congestion_window_ * RenoBeta(); | 175 congestion_window_ = congestion_window_ * RenoBeta(); |
170 } else { | 176 } else { |
171 congestion_window_ = | 177 congestion_window_ = |
172 cubic_.CongestionWindowAfterPacketLoss(congestion_window_); | 178 cubic_.CongestionWindowAfterPacketLoss(congestion_window_); |
173 } | 179 } |
174 slowstart_threshold_ = congestion_window_; | 180 slowstart_threshold_ = congestion_window_; |
175 // Enforce TCP's minimum congestion window of 2*MSS. | 181 // Enforce TCP's minimum congestion window of 2*MSS. |
176 if (congestion_window_ < kMinimumCongestionWindow) { | 182 if (congestion_window_ < min_congestion_window_) { |
177 congestion_window_ = kMinimumCongestionWindow; | 183 congestion_window_ = min_congestion_window_; |
178 } | 184 } |
179 largest_sent_at_last_cutback_ = largest_sent_sequence_number_; | 185 largest_sent_at_last_cutback_ = largest_sent_sequence_number_; |
180 // Reset packet count from congestion avoidance mode. We start counting again | 186 // Reset packet count from congestion avoidance mode. We start counting again |
181 // when we're out of recovery. | 187 // when we're out of recovery. |
182 num_acked_packets_ = 0; | 188 num_acked_packets_ = 0; |
183 DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_ | 189 DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_ |
184 << " slowstart threshold: " << slowstart_threshold_; | 190 << " slowstart threshold: " << slowstart_threshold_; |
185 } | 191 } |
186 | 192 |
187 bool TcpCubicBytesSender::OnPacketSent( | 193 bool TcpCubicBytesSender::OnPacketSent( |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 } | 335 } |
330 | 336 |
331 void TcpCubicBytesSender::OnRetransmissionTimeout(bool packets_retransmitted) { | 337 void TcpCubicBytesSender::OnRetransmissionTimeout(bool packets_retransmitted) { |
332 largest_sent_at_last_cutback_ = 0; | 338 largest_sent_at_last_cutback_ = 0; |
333 if (!packets_retransmitted) { | 339 if (!packets_retransmitted) { |
334 return; | 340 return; |
335 } | 341 } |
336 cubic_.Reset(); | 342 cubic_.Reset(); |
337 hybrid_slow_start_.Restart(); | 343 hybrid_slow_start_.Restart(); |
338 slowstart_threshold_ = congestion_window_ / 2; | 344 slowstart_threshold_ = congestion_window_ / 2; |
339 congestion_window_ = kMinimumCongestionWindow; | 345 congestion_window_ = min_congestion_window_; |
340 } | 346 } |
341 | 347 |
342 CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const { | 348 CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const { |
343 return reno_ ? kReno : kCubic; | 349 return reno_ ? kReno : kCubic; |
344 } | 350 } |
345 | 351 |
346 } // namespace net | 352 } // namespace net |
OLD | NEW |