1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/congestion_control/pacing_sender.h"
6
7 namespace net {
8
PacingSender(SendAlgorithmInterface * sender,QuicTime::Delta alarm_granularity,uint32 initial_packet_burst)9 PacingSender::PacingSender(SendAlgorithmInterface* sender,
10 QuicTime::Delta alarm_granularity,
11 uint32 initial_packet_burst)
12 : sender_(sender),
13 alarm_granularity_(alarm_granularity),
14 initial_packet_burst_(initial_packet_burst),
15 burst_tokens_(initial_packet_burst),
16 last_delayed_packet_sent_time_(QuicTime::Zero()),
17 next_packet_send_time_(QuicTime::Zero()),
18 was_last_send_delayed_(false),
19 has_valid_rtt_(false) {
20 }
21
~PacingSender()22 PacingSender::~PacingSender() {}
23
SetFromConfig(const QuicConfig & config,bool is_server)24 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
25 // TODO(ianswett): Consider using the suggested RTT for pacing an initial
26 // response.
27 sender_->SetFromConfig(config, is_server);
28 }
29
OnIncomingQuicCongestionFeedbackFrame(const QuicCongestionFeedbackFrame & feedback,QuicTime feedback_receive_time)30 void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
31 const QuicCongestionFeedbackFrame& feedback,
32 QuicTime feedback_receive_time) {
33 sender_->OnIncomingQuicCongestionFeedbackFrame(
34 feedback, feedback_receive_time);
35 }
36
OnCongestionEvent(bool rtt_updated,QuicByteCount bytes_in_flight,const CongestionVector & acked_packets,const CongestionVector & lost_packets)37 void PacingSender::OnCongestionEvent(bool rtt_updated,
38 QuicByteCount bytes_in_flight,
39 const CongestionVector& acked_packets,
40 const CongestionVector& lost_packets) {
41 if (rtt_updated) {
42 has_valid_rtt_ = true;
43 }
44 sender_->OnCongestionEvent(
45 rtt_updated, bytes_in_flight, acked_packets, lost_packets);
46 }
47
OnPacketSent(QuicTime sent_time,QuicByteCount bytes_in_flight,QuicPacketSequenceNumber sequence_number,QuicByteCount bytes,HasRetransmittableData has_retransmittable_data)48 bool PacingSender::OnPacketSent(
49 QuicTime sent_time,
50 QuicByteCount bytes_in_flight,
51 QuicPacketSequenceNumber sequence_number,
52 QuicByteCount bytes,
53 HasRetransmittableData has_retransmittable_data) {
54 // Only pace data packets once we have an updated RTT.
55 const bool in_flight =
56 sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number,
57 bytes, has_retransmittable_data);
58 if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA || !has_valid_rtt_) {
59 return in_flight;
60 }
61 if (burst_tokens_ > 0) {
62 --burst_tokens_;
63 was_last_send_delayed_ = false;
64 last_delayed_packet_sent_time_ = QuicTime::Zero();
65 next_packet_send_time_ = QuicTime::Zero();
66 return in_flight;
67 }
68 // The next packet should be sent as soon as the current packets has
69 // been transferred. We pace at twice the rate of the underlying
70 // sender's bandwidth estimate during slow start and 1.25x during congestion
71 // avoidance to ensure pacing doesn't prevent us from filling the window.
72 const float kPacingAggression = sender_->InSlowStart() ? 2 : 1.25;
73 QuicTime::Delta delay =
74 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
75 // If the last send was delayed, and the alarm took a long time to get
76 // invoked, allow the connection to make up for lost time.
77 if (was_last_send_delayed_) {
78 next_packet_send_time_ = next_packet_send_time_.Add(delay);
79 // The send was application limited if it takes longer than the
80 // pacing delay between sent packets.
81 const bool application_limited =
82 last_delayed_packet_sent_time_.IsInitialized() &&
83 sent_time > last_delayed_packet_sent_time_.Add(delay);
84 const bool making_up_for_lost_time = next_packet_send_time_ <= sent_time;
85 // As long as we're making up time and not application limited,
86 // continue to consider the packets delayed, allowing the packets to be
87 // sent immediately.
88 if (making_up_for_lost_time && !application_limited) {
89 last_delayed_packet_sent_time_ = sent_time;
90 } else {
91 was_last_send_delayed_ = false;
92 last_delayed_packet_sent_time_ = QuicTime::Zero();
93 }
94 } else {
95 next_packet_send_time_ =
96 QuicTime::Max(next_packet_send_time_.Add(delay),
97 sent_time.Add(delay).Subtract(alarm_granularity_));
98 }
99 return in_flight;
100 }
101
OnRetransmissionTimeout(bool packets_retransmitted)102 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
103 sender_->OnRetransmissionTimeout(packets_retransmitted);
104 }
105
RevertRetransmissionTimeout()106 void PacingSender::RevertRetransmissionTimeout() {
107 sender_->RevertRetransmissionTimeout();
108 }
109
TimeUntilSend(QuicTime now,QuicByteCount bytes_in_flight,HasRetransmittableData has_retransmittable_data) const110 QuicTime::Delta PacingSender::TimeUntilSend(
111 QuicTime now,
112 QuicByteCount bytes_in_flight,
113 HasRetransmittableData has_retransmittable_data) const {
114 QuicTime::Delta time_until_send =
115 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
116 if (!has_valid_rtt_) {
117 // Don't pace if we don't have an updated RTT estimate.
118 return time_until_send;
119 }
120 if (bytes_in_flight == 0) {
121 // Add more burst tokens anytime the connection is entering quiescence.
122 burst_tokens_ = initial_packet_burst_;
123 }
124 if (burst_tokens_ > 0) {
125 // Don't pace if we have burst tokens available.
126 return time_until_send;
127 }
128
129 if (!time_until_send.IsZero()) {
130 DCHECK(time_until_send.IsInfinite());
131 // The underlying sender prevents sending.
132 return time_until_send;
133 }
134
135 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
136 // Don't pace ACK packets, since they do not count against CWND and do not
137 // cause CWND to grow.
138 return QuicTime::Delta::Zero();
139 }
140
141 // If the next send time is within the alarm granularity, send immediately.
142 if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
143 DVLOG(1) << "Delaying packet: "
144 << next_packet_send_time_.Subtract(now).ToMicroseconds();
145 was_last_send_delayed_ = true;
146 return next_packet_send_time_.Subtract(now);
147 }
148
149 DVLOG(1) << "Sending packet now";
150 return QuicTime::Delta::Zero();
151 }
152
BandwidthEstimate() const153 QuicBandwidth PacingSender::BandwidthEstimate() const {
154 return sender_->BandwidthEstimate();
155 }
156
HasReliableBandwidthEstimate() const157 bool PacingSender::HasReliableBandwidthEstimate() const {
158 return sender_->HasReliableBandwidthEstimate();
159 }
160
RetransmissionDelay() const161 QuicTime::Delta PacingSender::RetransmissionDelay() const {
162 return sender_->RetransmissionDelay();
163 }
164
GetCongestionWindow() const165 QuicByteCount PacingSender::GetCongestionWindow() const {
166 return sender_->GetCongestionWindow();
167 }
168
InSlowStart() const169 bool PacingSender::InSlowStart() const {
170 return sender_->InSlowStart();
171 }
172
InRecovery() const173 bool PacingSender::InRecovery() const {
174 return sender_->InRecovery();
175 }
176
GetSlowStartThreshold() const177 QuicByteCount PacingSender::GetSlowStartThreshold() const {
178 return sender_->GetSlowStartThreshold();
179 }
180
GetCongestionControlType() const181 CongestionControlType PacingSender::GetCongestionControlType() const {
182 return sender_->GetCongestionControlType();
183 }
184
185 } // namespace net
186