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