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.
5 #include "net/quic/congestion_control/pacing_sender.h"
9 PacingSender::PacingSender(SendAlgorithmInterface
* sender
,
10 QuicTime::Delta alarm_granularity
,
11 uint32 initial_packet_burst
)
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) {
22 PacingSender::~PacingSender() {}
24 void PacingSender::SetFromConfig(const QuicConfig
& config
, bool is_server
) {
25 // TODO(ianswett): Consider using the suggested RTT for pacing an initial
27 sender_
->SetFromConfig(config
, is_server
);
30 void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
31 const QuicCongestionFeedbackFrame
& feedback
,
32 QuicTime feedback_receive_time
) {
33 sender_
->OnIncomingQuicCongestionFeedbackFrame(
34 feedback
, feedback_receive_time
);
37 void PacingSender::OnCongestionEvent(bool rtt_updated
,
38 QuicByteCount bytes_in_flight
,
39 const CongestionMap
& acked_packets
,
40 const CongestionMap
& lost_packets
) {
42 has_valid_rtt_
= true;
44 sender_
->OnCongestionEvent(
45 rtt_updated
, bytes_in_flight
, acked_packets
, lost_packets
);
48 bool PacingSender::OnPacketSent(
50 QuicByteCount bytes_in_flight
,
51 QuicPacketSequenceNumber sequence_number
,
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_
) {
61 if (burst_tokens_
> 0) {
63 was_last_send_delayed_
= false;
64 last_delayed_packet_sent_time_
= QuicTime::Zero();
65 next_packet_send_time_
= QuicTime::Zero();
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
88 if (making_up_for_lost_time
&& !application_limited
) {
89 last_delayed_packet_sent_time_
= sent_time
;
91 was_last_send_delayed_
= false;
92 last_delayed_packet_sent_time_
= QuicTime::Zero();
95 next_packet_send_time_
=
96 QuicTime::Max(next_packet_send_time_
.Add(delay
),
97 sent_time
.Add(delay
).Subtract(alarm_granularity_
));
102 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted
) {
103 sender_
->OnRetransmissionTimeout(packets_retransmitted
);
106 void PacingSender::RevertRetransmissionTimeout() {
107 sender_
->RevertRetransmissionTimeout();
110 QuicTime::Delta
PacingSender::TimeUntilSend(
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
;
120 if (bytes_in_flight
== 0) {
121 // Add more burst tokens anytime the connection is entering quiescence.
122 burst_tokens_
= initial_packet_burst_
;
124 if (burst_tokens_
> 0) {
125 // Don't pace if we have burst tokens available.
126 return time_until_send
;
129 if (!time_until_send
.IsZero()) {
130 DCHECK(time_until_send
.IsInfinite());
131 // The underlying sender prevents sending.
132 return time_until_send
;
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();
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
);
149 DVLOG(1) << "Sending packet now";
150 return QuicTime::Delta::Zero();
153 QuicBandwidth
PacingSender::BandwidthEstimate() const {
154 return sender_
->BandwidthEstimate();
157 bool PacingSender::HasReliableBandwidthEstimate() const {
158 return sender_
->HasReliableBandwidthEstimate();
161 QuicTime::Delta
PacingSender::RetransmissionDelay() const {
162 return sender_
->RetransmissionDelay();
165 QuicByteCount
PacingSender::GetCongestionWindow() const {
166 return sender_
->GetCongestionWindow();
169 bool PacingSender::InSlowStart() const {
170 return sender_
->InSlowStart();
173 bool PacingSender::InRecovery() const {
174 return sender_
->InRecovery();
177 QuicByteCount
PacingSender::GetSlowStartThreshold() const {
178 return sender_
->GetSlowStartThreshold();
181 CongestionControlType
PacingSender::GetCongestionControlType() const {
182 return sender_
->GetCongestionControlType();