| Index: net/quic/congestion_control/tcp_cubic_bytes_sender.cc
|
| diff --git a/net/quic/congestion_control/tcp_cubic_bytes_sender.cc b/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
|
| index 7f817ebfb5855ba10f8d275bd6d94f234e89a68f..ef6172a92932f5e4401027ea6d1a2130d03a4dcc 100644
|
| --- a/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
|
| +++ b/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
|
| @@ -52,7 +52,8 @@ TcpCubicBytesSender::TcpCubicBytesSender(
|
| initial_tcp_congestion_window_(initial_tcp_congestion_window *
|
| kDefaultTCPMSS),
|
| initial_max_tcp_congestion_window_(max_congestion_window *
|
| - kDefaultTCPMSS) {}
|
| + kDefaultTCPMSS),
|
| + slow_start_large_reduction_(false) {}
|
|
|
| TcpCubicBytesSender::~TcpCubicBytesSender() {}
|
|
|
| @@ -75,6 +76,11 @@ void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config,
|
| min4_mode_ = true;
|
| min_congestion_window_ = kDefaultTCPMSS;
|
| }
|
| + if (config.HasReceivedConnectionOptions() &&
|
| + ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
|
| + // Slow Start Fast Exit experiment.
|
| + slow_start_large_reduction_ = true;
|
| + }
|
| }
|
| }
|
|
|
| @@ -156,6 +162,12 @@ void TcpCubicBytesSender::OnPacketLost(QuicPacketNumber packet_number,
|
| if (packet_number <= largest_sent_at_last_cutback_) {
|
| if (last_cutback_exited_slowstart_) {
|
| ++stats_->slowstart_packets_lost;
|
| + if (slow_start_large_reduction_) {
|
| + // Reduce congestion window by 1 MSS for every loss.
|
| + congestion_window_ =
|
| + max(congestion_window_ - kDefaultTCPMSS, min_congestion_window_);
|
| + slowstart_threshold_ = congestion_window_;
|
| + }
|
| }
|
| DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
|
| << " because it was sent prior to the last CWND cutback.";
|
| @@ -169,17 +181,21 @@ void TcpCubicBytesSender::OnPacketLost(QuicPacketNumber packet_number,
|
|
|
| prr_.OnPacketLost(bytes_in_flight);
|
|
|
| - if (reno_) {
|
| + // TODO(jri): Separate out all of slow start into a separate class.
|
| + if (slow_start_large_reduction_) {
|
| + DCHECK_LT(kDefaultTCPMSS, congestion_window_);
|
| + congestion_window_ = congestion_window_ - kDefaultTCPMSS;
|
| + } else if (reno_) {
|
| congestion_window_ = congestion_window_ * RenoBeta();
|
| } else {
|
| congestion_window_ =
|
| cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
|
| }
|
| - slowstart_threshold_ = congestion_window_;
|
| // Enforce TCP's minimum congestion window of 2*MSS.
|
| if (congestion_window_ < min_congestion_window_) {
|
| congestion_window_ = min_congestion_window_;
|
| }
|
| + slowstart_threshold_ = congestion_window_;
|
| largest_sent_at_last_cutback_ = largest_sent_packet_number_;
|
| // Reset packet count from congestion avoidance mode. We start counting again
|
| // when we're out of recovery.
|
|
|