summaryrefslogtreecommitdiffstats
path: root/net/quic/congestion_control
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-15 21:06:49 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-15 21:06:49 +0000
commitfb35b0a23a69fd33a5320362d43b9b6e8df40b7d (patch)
tree1fa3f843a77fdc314e14012161a072b742d4858e /net/quic/congestion_control
parent47a7c002213e7008d7a989122acfe182a1114ad4 (diff)
downloadchromium_src-fb35b0a23a69fd33a5320362d43b9b6e8df40b7d.zip
chromium_src-fb35b0a23a69fd33a5320362d43b9b6e8df40b7d.tar.gz
chromium_src-fb35b0a23a69fd33a5320362d43b9b6e8df40b7d.tar.bz2
Land Recent QUIC Changes
Add reordering statistics and min_rtt to QuicConnectionStats. Merge internal change: 64582035 https://codereview.chromium.org/231733008/ Add a slowstart packets lost stat to allow QUIC to track how many packets are lost when exiting slowstart. Merge internal change: 64548567 https://codereview.chromium.org/231833004/ Added hooks to QUIC time wait list manager so that internal server specific code could be separated. Merge internal change: 64500752 https://codereview.chromium.org/231863006/ Cleanup changes found while merging the privacy mode changes into the internal source tree. Merge internal change: 64377731 https://codereview.chromium.org/232433002/ Add test-only MakeAckFrame method to quic_test_utils, and remove the test-only QuicAckFrame constructor which was not using the 2nd argument. Used MakeAckFrame method in chrome specific code also. Merge internal change: 64373111 https://codereview.chromium.org/231863005/ Set the send and receive buffers for the QuicClient and QuicServer to the default receive window for QUIC's TCP Sender. QUIC cleanup to create SetSendBufferSize and SetReceiveBufferSize in QuicSocketUtils. Merge internal change: 64358078, 64380825 https://codereview.chromium.org/232243003/ Added writer() helper method to QuicConnection. Made CreateQuicConnection of QuicDispatcher a virtual method and added helper methods for helper, writer and initial_flow_control_window_bytes. Merge internal change: 64357422 https://codereview.chromium.org/232013005/ When multiple streams have pending writes in QUICSession, bundle them into as few packets as possible rather. Previously the header stream and the body stream were always written in separate packets. Fixed chrome specific unit tests to accept extra ack frame. Merge internal change: 64304809 https://codereview.chromium.org/232013005/ QUIC refactor to use the congestion window directly when calculating the packet sequence number length, instead of calculating the window indirectly. Merge internal change: 64295053 https://codereview.chromium.org/232003003/ Refactor to isolate the PRR logic from the rest of TCPCubicSender. Merge internal change: 64210335 https://codereview.chromium.org/232173002/ R=rch@chromium.org Review URL: https://codereview.chromium.org/232463003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263995 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/congestion_control')
-rw-r--r--net/quic/congestion_control/inter_arrival_sender.cc3
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.cc95
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.h10
3 files changed, 72 insertions, 36 deletions
diff --git a/net/quic/congestion_control/inter_arrival_sender.cc b/net/quic/congestion_control/inter_arrival_sender.cc
index 864db7d..0436c20 100644
--- a/net/quic/congestion_control/inter_arrival_sender.cc
+++ b/net/quic/congestion_control/inter_arrival_sender.cc
@@ -312,7 +312,8 @@ QuicTime::Delta InterArrivalSender::RetransmissionDelay() const {
}
QuicByteCount InterArrivalSender::GetCongestionWindow() const {
- return 0;
+ // Return an estimate based on the bandwidth and rtt.
+ return BandwidthEstimate().ToBytesPerPeriod(rtt_stats_->SmoothedRtt());
}
void InterArrivalSender::EstimateNewBandwidth(QuicTime feedback_receive_time,
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc
index b08e3c6..2753172 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc
@@ -34,6 +34,7 @@ TcpCubicSender::TcpCubicSender(
: hybrid_slow_start_(clock),
cubic_(clock, stats),
rtt_stats_(rtt_stats),
+ stats_(stats),
reno_(reno),
congestion_window_count_(0),
receive_window_(kDefaultReceiveWindow),
@@ -47,6 +48,7 @@ TcpCubicSender::TcpCubicSender(
largest_sent_at_last_cutback_(0),
congestion_window_(kInitialCongestionWindow),
slowstart_threshold_(max_tcp_congestion_window),
+ last_cutback_exited_slowstart_(false),
max_tcp_congestion_window_(max_tcp_congestion_window) {
}
@@ -75,10 +77,12 @@ void TcpCubicSender::OnPacketAcked(
QuicPacketSequenceNumber acked_sequence_number, QuicByteCount acked_bytes) {
DCHECK_GE(bytes_in_flight_, acked_bytes);
bytes_in_flight_ -= acked_bytes;
- prr_delivered_ += acked_bytes;
- ++ack_count_since_loss_;
largest_acked_sequence_number_ = max(acked_sequence_number,
largest_acked_sequence_number_);
+ if (InRecovery()) {
+ PrrOnPacketAcked(acked_bytes);
+ return;
+ }
MaybeIncreaseCwnd(acked_sequence_number);
// TODO(ianswett): Should this even be called when not in slow start?
hybrid_slow_start_.OnPacketAcked(acked_sequence_number, InSlowStart());
@@ -89,22 +93,19 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number,
// TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
// already sent should be treated as a single loss event, since it's expected.
if (sequence_number <= largest_sent_at_last_cutback_) {
+ if (last_cutback_exited_slowstart_) {
+ ++stats_->slowstart_packets_lost;
+ }
DVLOG(1) << "Ignoring loss for largest_missing:" << sequence_number
<< " because it was sent prior to the last CWND cutback.";
return;
}
-
- // Initialize proportional rate reduction(RFC 6937) variables.
- prr_out_ = 0;
- bytes_in_flight_before_loss_ = bytes_in_flight_;
- // Since all losses are triggered by an incoming ack currently, and acks are
- // registered before losses by the SentPacketManager, initialize the variables
- // as though one ack was received directly after the loss. This is too low
- // for stretch acks, but we expect missing packets to be immediately acked.
- // This ensures 1 or 2 packets are immediately able to be sent, depending upon
- // whether we're in PRR or PRR-SSRB mode.
- prr_delivered_ = kMaxPacketSize;
- ack_count_since_loss_ = 1;
+ ++stats_->tcp_loss_events;
+ last_cutback_exited_slowstart_ = InSlowStart();
+ if (InSlowStart()) {
+ ++stats_->slowstart_packets_lost;
+ }
+ PrrOnPacketLost();
// In a normal TCP we would need to know the lowest missing packet to detect
// if we receive 3 missing packets. Here we get a missing packet for which we
@@ -163,24 +164,10 @@ QuicTime::Delta TcpCubicSender::TimeUntilSend(
// tail loss probe (draft-dukkipati-tcpm-tcp-loss-probe-01).
return QuicTime::Delta::Zero();
}
- if (AvailableSendWindow() > 0) {
- // 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 (InRecovery() &&
- prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize < prr_out_) {
- return QuicTime::Delta::Infinite();
- }
- return QuicTime::Delta::Zero();
+ if (InRecovery()) {
+ return PrrTimeUntilSend();
}
- // 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 (InRecovery() &&
- prr_delivered_ * slowstart_threshold_ * kMaxSegmentSize >
- prr_out_ * bytes_in_flight_before_loss_) {
+ if (AvailableSendWindow() > 0) {
return QuicTime::Delta::Zero();
}
return QuicTime::Delta::Infinite();
@@ -236,15 +223,12 @@ bool TcpCubicSender::InRecovery() const {
// represents, but quic has a separate ack for each packet.
void TcpCubicSender::MaybeIncreaseCwnd(
QuicPacketSequenceNumber acked_sequence_number) {
+ LOG_IF(DFATAL, InRecovery()) << "Never increase the CWND during recovery.";
if (!IsCwndLimited()) {
// We don't update the congestion window unless we are close to using the
// window we have available.
return;
}
- if (acked_sequence_number <= largest_sent_at_last_cutback_) {
- // We don't increase the congestion window during recovery.
- return;
- }
if (InSlowStart()) {
// congestion_window_cnt is the number of acks since last change of snd_cwnd
if (congestion_window_ < max_tcp_congestion_window_) {
@@ -297,4 +281,45 @@ void TcpCubicSender::UpdateRtt(QuicTime::Delta rtt) {
}
}
+void TcpCubicSender::PrrOnPacketLost() {
+ prr_out_ = 0;
+ bytes_in_flight_before_loss_ = bytes_in_flight_;
+ // Since all losses are triggered by an incoming ack currently, and acks are
+ // registered before losses by the SentPacketManager, initialize the variables
+ // as though one ack was received directly after the loss. This is too low
+ // for stretch acks, but we expect missing packets to be immediately acked.
+ // This ensures 1 or 2 packets are immediately able to be sent, depending upon
+ // whether we're in PRR or PRR-SSRB mode.
+ prr_delivered_ = kMaxPacketSize;
+ ack_count_since_loss_ = 1;
+}
+
+void TcpCubicSender::PrrOnPacketAcked(QuicByteCount acked_bytes) {
+ prr_delivered_ += acked_bytes;
+ ++ack_count_since_loss_;
+}
+
+QuicTime::Delta TcpCubicSender::PrrTimeUntilSend() {
+ DCHECK(InRecovery());
+ if (AvailableSendWindow() > 0) {
+ // 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();
+}
+
} // namespace net
diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h
index f70511e..14bb9e2 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.h
+++ b/net/quic/congestion_control/tcp_cubic_sender.h
@@ -75,10 +75,16 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
void MaybeIncreaseCwnd(QuicPacketSequenceNumber acked_sequence_number);
bool IsCwndLimited() const;
bool InRecovery() const;
+ // Methods for isolating PRR from the rest of TCP Cubic.
+ void PrrOnPacketLost();
+ void PrrOnPacketAcked(QuicByteCount acked_bytes);
+ QuicTime::Delta PrrTimeUntilSend();
+
HybridSlowStart hybrid_slow_start_;
Cubic cubic_;
const RttStats* rtt_stats_;
+ QuicConnectionStats* stats_;
// Reno provided for testing.
const bool reno_;
@@ -115,6 +121,10 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
// Slow start congestion window in packets, aka ssthresh.
QuicTcpCongestionWindow slowstart_threshold_;
+ // Whether the last loss event caused us to exit slowstart.
+ // Used for stats collection of slowstart_packets_lost
+ bool last_cutback_exited_slowstart_;
+
// Maximum number of outstanding packets for tcp.
QuicTcpCongestionWindow max_tcp_congestion_window_;