| 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;
|
| }
|
|
|