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)9 PacingSender::PacingSender(SendAlgorithmInterface* sender,
10 QuicTime::Delta alarm_granularity)
11 : sender_(sender),
12 alarm_granularity_(alarm_granularity),
13 last_delayed_packet_sent_time_(QuicTime::Zero()),
14 next_packet_send_time_(QuicTime::Zero()),
15 was_last_send_delayed_(false),
16 has_valid_rtt_(false) {
17 }
18
~PacingSender()19 PacingSender::~PacingSender() {}
20
SetFromConfig(const QuicConfig & config,bool is_server)21 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
22 sender_->SetFromConfig(config, is_server);
23 }
24
OnIncomingQuicCongestionFeedbackFrame(const QuicCongestionFeedbackFrame & feedback,QuicTime feedback_receive_time)25 void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
26 const QuicCongestionFeedbackFrame& feedback,
27 QuicTime feedback_receive_time) {
28 sender_->OnIncomingQuicCongestionFeedbackFrame(
29 feedback, feedback_receive_time);
30 }
31
OnCongestionEvent(bool rtt_updated,QuicByteCount bytes_in_flight,const CongestionMap & acked_packets,const CongestionMap & lost_packets)32 void PacingSender::OnCongestionEvent(bool rtt_updated,
33 QuicByteCount bytes_in_flight,
34 const CongestionMap& acked_packets,
35 const CongestionMap& lost_packets) {
36 if (rtt_updated) {
37 has_valid_rtt_ = true;
38 }
39 sender_->OnCongestionEvent(
40 rtt_updated, bytes_in_flight, acked_packets, lost_packets);
41 }
42
OnPacketSent(QuicTime sent_time,QuicByteCount bytes_in_flight,QuicPacketSequenceNumber sequence_number,QuicByteCount bytes,HasRetransmittableData has_retransmittable_data)43 bool PacingSender::OnPacketSent(
44 QuicTime sent_time,
45 QuicByteCount bytes_in_flight,
46 QuicPacketSequenceNumber sequence_number,
47 QuicByteCount bytes,
48 HasRetransmittableData has_retransmittable_data) {
49 // Only pace data packets once we have an updated RTT.
50 if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && has_valid_rtt_) {
51 // The next packet should be sent as soon as the current packets has
52 // been transferred. We pace at twice the rate of the underlying
53 // sender's bandwidth estimate to help ensure that pacing doesn't become
54 // a bottleneck.
55 const float kPacingAggression = 2;
56 QuicTime::Delta delay =
57 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
58 // If the last send was delayed, and the alarm took a long time to get
59 // invoked, allow the connection to make up for lost time.
60 if (was_last_send_delayed_) {
61 next_packet_send_time_ = next_packet_send_time_.Add(delay);
62 // The send was application limited if it takes longer than the
63 // pacing delay between sent packets.
64 const bool application_limited =
65 last_delayed_packet_sent_time_.IsInitialized() &&
66 sent_time > last_delayed_packet_sent_time_.Add(delay);
67 const bool making_up_for_lost_time = next_packet_send_time_ <= sent_time;
68 // As long as we're making up time and not application limited,
69 // continue to consider the packets delayed, allowing the packets to be
70 // sent immediately.
71 if (making_up_for_lost_time && !application_limited) {
72 last_delayed_packet_sent_time_ = sent_time;
73 } else {
74 was_last_send_delayed_ = false;
75 last_delayed_packet_sent_time_ = QuicTime::Zero();
76 }
77 } else {
78 next_packet_send_time_ =
79 QuicTime::Max(next_packet_send_time_.Add(delay),
80 sent_time.Add(delay).Subtract(alarm_granularity_));
81 }
82 }
83 return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number,
84 bytes, has_retransmittable_data);
85 }
86
OnRetransmissionTimeout(bool packets_retransmitted)87 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
88 sender_->OnRetransmissionTimeout(packets_retransmitted);
89 }
90
TimeUntilSend(QuicTime now,QuicByteCount bytes_in_flight,HasRetransmittableData has_retransmittable_data) const91 QuicTime::Delta PacingSender::TimeUntilSend(
92 QuicTime now,
93 QuicByteCount bytes_in_flight,
94 HasRetransmittableData has_retransmittable_data) const {
95 QuicTime::Delta time_until_send =
96 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
97 if (!has_valid_rtt_) {
98 // Don't pace if we don't have an updated RTT estimate.
99 return time_until_send;
100 }
101
102 if (!time_until_send.IsZero()) {
103 DCHECK(time_until_send.IsInfinite());
104 // The underlying sender prevents sending.
105 return time_until_send;
106 }
107
108 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
109 // Don't pace ACK packets, since they do not count against CWND and do not
110 // cause CWND to grow.
111 return QuicTime::Delta::Zero();
112 }
113
114 // If the next send time is within the alarm granularity, send immediately.
115 if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
116 DVLOG(1) << "Delaying packet: "
117 << next_packet_send_time_.Subtract(now).ToMicroseconds();
118 was_last_send_delayed_ = true;
119 return next_packet_send_time_.Subtract(now);
120 }
121
122 DVLOG(1) << "Sending packet now";
123 return QuicTime::Delta::Zero();
124 }
125
BandwidthEstimate() const126 QuicBandwidth PacingSender::BandwidthEstimate() const {
127 return sender_->BandwidthEstimate();
128 }
129
RetransmissionDelay() const130 QuicTime::Delta PacingSender::RetransmissionDelay() const {
131 return sender_->RetransmissionDelay();
132 }
133
GetCongestionWindow() const134 QuicByteCount PacingSender::GetCongestionWindow() const {
135 return sender_->GetCongestionWindow();
136 }
137
138 } // namespace net
139