Index: net/quic/congestion_control/tcp_cubic_sender.cc |
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc |
index 91b95cf29e85f2d6b692c81575bfc2dacc2f90f9..9ea96aed5f5b171c0c6e60ecb4c9d02b76897f51 100644 |
--- a/net/quic/congestion_control/tcp_cubic_sender.cc |
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc |
@@ -7,6 +7,7 @@ |
#include <algorithm> |
#include "base/metrics/histogram.h" |
+#include "net/quic/congestion_control/prr_sender.h" |
#include "net/quic/congestion_control/rtt_stats.h" |
#include "net/quic/crypto/crypto_protocol.h" |
@@ -19,17 +20,17 @@ namespace { |
// Constants based on TCP defaults. |
// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a |
// fast retransmission. The cwnd after a timeout is still 1. |
-const QuicTcpCongestionWindow kMinimumCongestionWindow = 2; |
+const QuicPacketCount kMinimumCongestionWindow = 2; |
const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; |
const int64 kInitialCongestionWindow = 10; |
const int kMaxBurstLength = 3; |
-}; // namespace |
+} // namespace |
TcpCubicSender::TcpCubicSender( |
const QuicClock* clock, |
const RttStats* rtt_stats, |
bool reno, |
- QuicTcpCongestionWindow max_tcp_congestion_window, |
+ QuicPacketCount max_tcp_congestion_window, |
QuicConnectionStats* stats) |
: hybrid_slow_start_(clock), |
cubic_(clock, stats), |
@@ -38,11 +39,6 @@ TcpCubicSender::TcpCubicSender( |
reno_(reno), |
num_connections_(2), |
congestion_window_count_(0), |
- receive_window_(kDefaultSocketReceiveBuffer), |
- prr_out_(0), |
- prr_delivered_(0), |
- ack_count_since_loss_(0), |
- bytes_in_flight_before_loss_(0), |
largest_sent_sequence_number_(0), |
largest_acked_sequence_number_(0), |
largest_sent_at_last_cutback_(0), |
@@ -72,10 +68,6 @@ void TcpCubicSender::SetFromConfig(const QuicConfig& config, bool is_server) { |
config.ReceivedInitialCongestionWindow()); |
} |
} |
- if (config.HasReceivedSocketReceiveBuffer()) { |
- // Set the initial socket receive buffer size in bytes. |
- receive_window_ = config.ReceivedSocketReceiveBuffer(); |
- } |
} |
void TcpCubicSender::SetNumEmulatedConnections(int num_connections) { |
@@ -83,14 +75,6 @@ void TcpCubicSender::SetNumEmulatedConnections(int num_connections) { |
cubic_.SetNumConnections(num_connections_); |
} |
-void TcpCubicSender::OnIncomingQuicCongestionFeedbackFrame( |
- const QuicCongestionFeedbackFrame& feedback, |
- QuicTime feedback_receive_time) { |
- if (feedback.type == kTCP) { |
- receive_window_ = feedback.tcp.receive_window; |
- } |
-} |
- |
void TcpCubicSender::OnCongestionEvent( |
bool rtt_updated, |
QuicByteCount bytes_in_flight, |
@@ -119,7 +103,8 @@ void TcpCubicSender::OnPacketAcked( |
largest_acked_sequence_number_ = max(acked_sequence_number, |
largest_acked_sequence_number_); |
if (InRecovery()) { |
- PrrOnPacketAcked(acked_bytes); |
+ // PRR is used when in recovery. |
+ prr_.OnPacketAcked(acked_bytes); |
return; |
} |
MaybeIncreaseCwnd(acked_sequence_number, bytes_in_flight); |
@@ -144,7 +129,8 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number, |
if (InSlowStart()) { |
++stats_->slowstart_packets_lost; |
} |
- PrrOnPacketLost(bytes_in_flight); |
+ |
+ prr_.OnPacketLost(bytes_in_flight); |
if (reno_) { |
congestion_window_ = congestion_window_ >> 1; |
@@ -174,8 +160,10 @@ bool TcpCubicSender::OnPacketSent(QuicTime /*sent_time*/, |
if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) { |
return false; |
} |
- |
- prr_out_ += bytes; |
+ if (InRecovery()) { |
+ // PRR is used when in recovery. |
+ prr_.OnPacketSent(bytes); |
+ } |
DCHECK_LT(largest_sent_sequence_number_, sequence_number); |
largest_sent_sequence_number_ = sequence_number; |
hybrid_slow_start_.OnPacketSent(sequence_number); |
@@ -191,19 +179,16 @@ QuicTime::Delta TcpCubicSender::TimeUntilSend( |
return QuicTime::Delta::Zero(); |
} |
if (InRecovery()) { |
- return PrrTimeUntilSend(bytes_in_flight); |
+ // PRR is used when in recovery. |
+ return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, |
+ slowstart_threshold_); |
} |
- if (SendWindow() > bytes_in_flight) { |
+ if (GetCongestionWindow() > bytes_in_flight) { |
return QuicTime::Delta::Zero(); |
} |
return QuicTime::Delta::Infinite(); |
} |
-QuicByteCount TcpCubicSender::SendWindow() const { |
- // What's the current send window in bytes. |
- return min(receive_window_, GetCongestionWindow()); |
-} |
- |
QuicBandwidth TcpCubicSender::PacingRate() const { |
// We pace at twice the rate of the underlying sender's bandwidth estimate |
// during slow start and 1.25x during congestion avoidance to ensure pacing |
@@ -333,46 +318,6 @@ void TcpCubicSender::RevertRetransmissionTimeout() { |
previous_congestion_window_ = 0; |
} |
-void TcpCubicSender::PrrOnPacketLost(QuicByteCount bytes_in_flight) { |
- prr_out_ = 0; |
- bytes_in_flight_before_loss_ = bytes_in_flight; |
- prr_delivered_ = 0; |
- ack_count_since_loss_ = 0; |
-} |
- |
-void TcpCubicSender::PrrOnPacketAcked(QuicByteCount acked_bytes) { |
- prr_delivered_ += acked_bytes; |
- ++ack_count_since_loss_; |
-} |
- |
-QuicTime::Delta TcpCubicSender::PrrTimeUntilSend( |
- QuicByteCount bytes_in_flight) const { |
- DCHECK(InRecovery()); |
- // Return QuicTime::Zero In order to ensure limited transmit always works. |
- if (prr_out_ == 0 || bytes_in_flight < kMaxSegmentSize) { |
- return QuicTime::Delta::Zero(); |
- } |
- if (SendWindow() > bytes_in_flight) { |
- // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead |
- // of sending the entire available window. This prevents burst retransmits |
- // when more packets are lost than the CWND reduction. |
- // limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS |
- if (prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize <= prr_out_) { |
- return QuicTime::Delta::Infinite(); |
- } |
- return QuicTime::Delta::Zero(); |
- } |
- // Implement Proportional Rate Reduction (RFC6937) |
- // Checks a simplified version of the PRR formula that doesn't use division: |
- // AvailableSendWindow = |
- // CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent |
- if (prr_delivered_ * slowstart_threshold_ * kMaxSegmentSize > |
- prr_out_ * bytes_in_flight_before_loss_) { |
- return QuicTime::Delta::Zero(); |
- } |
- return QuicTime::Delta::Infinite(); |
-} |
- |
CongestionControlType TcpCubicSender::GetCongestionControlType() const { |
return reno_ ? kReno : kCubic; |
} |