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)
12 alarm_granularity_(alarm_granularity),
13 next_packet_send_time_(QuicTime::Zero()),
14 was_last_send_delayed_(false),
18 PacingSender::~PacingSender() {}
20 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
21 sender_->SetFromConfig(config, is_server);
24 void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
25 const QuicCongestionFeedbackFrame& feedback,
26 QuicTime feedback_receive_time) {
27 sender_->OnIncomingQuicCongestionFeedbackFrame(
28 feedback, feedback_receive_time);
31 void PacingSender::OnPacketAcked(
32 QuicPacketSequenceNumber acked_sequence_number,
33 QuicByteCount acked_bytes) {
34 sender_->OnPacketAcked(acked_sequence_number, acked_bytes);
37 void PacingSender::OnPacketLost(QuicPacketSequenceNumber sequence_number,
38 QuicTime ack_receive_time) {
39 sender_->OnPacketLost(sequence_number, ack_receive_time);
42 bool PacingSender::OnPacketSent(
44 QuicPacketSequenceNumber sequence_number,
46 TransmissionType transmission_type,
47 HasRetransmittableData has_retransmittable_data) {
48 // Only pace data packets once we have an updated RTT.
49 if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && updated_rtt_) {
50 // The next packet should be sent as soon as the current packets has
51 // been transferred. We pace at twice the rate of the underlying
52 // sender's bandwidth estimate to help ensure that pacing doesn't become
54 const float kPacingAggression = 2;
55 QuicTime::Delta delay =
56 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
57 next_packet_send_time_ = next_packet_send_time_.Add(delay);
59 return sender_->OnPacketSent(sent_time, sequence_number, bytes,
60 transmission_type, has_retransmittable_data);
63 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
64 sender_->OnRetransmissionTimeout(packets_retransmitted);
67 void PacingSender::OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
68 QuicByteCount abandoned_bytes) {
69 sender_->OnPacketAbandoned(sequence_number, abandoned_bytes);
72 QuicTime::Delta PacingSender::TimeUntilSend(
74 TransmissionType transmission_type,
75 HasRetransmittableData has_retransmittable_data,
76 IsHandshake handshake) {
77 QuicTime::Delta time_until_send =
78 sender_->TimeUntilSend(now, transmission_type,
79 has_retransmittable_data, handshake);
81 // Don't pace if we don't have an updated RTT estimate.
82 return time_until_send;
85 if (!time_until_send.IsZero()) {
86 DCHECK(time_until_send.IsInfinite());
87 // The underlying sender prevents sending.
88 return time_until_send;
91 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
92 // Don't pace ACK packets, since they do not count against CWND and do not
93 // cause CWND to grow.
94 return QuicTime::Delta::Zero();
97 if (!was_last_send_delayed_ &&
98 (!next_packet_send_time_.IsInitialized() ||
99 now > next_packet_send_time_.Add(alarm_granularity_))) {
100 // An alarm did not go off late, instead the application is "slow"
101 // delivering data. In this case, we restrict the amount of lost time
102 // that we can make up for.
103 next_packet_send_time_ = now.Subtract(alarm_granularity_);
106 // If the end of the epoch is far enough in the future, delay the send.
107 if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
108 was_last_send_delayed_ = true;
109 DVLOG(1) << "Delaying packet: "
110 << next_packet_send_time_.Subtract(now).ToMicroseconds();
111 return next_packet_send_time_.Subtract(now);
114 // Sent it immediately. The epoch end will be adjusted in OnPacketSent.
115 was_last_send_delayed_ = false;
116 DVLOG(1) << "Sending packet now";
117 return QuicTime::Delta::Zero();
120 QuicBandwidth PacingSender::BandwidthEstimate() const {
121 return sender_->BandwidthEstimate();
124 void PacingSender::UpdateRtt(QuicTime::Delta rtt_sample) {
126 sender_->UpdateRtt(rtt_sample);
129 QuicTime::Delta PacingSender::RetransmissionDelay() const {
130 return sender_->RetransmissionDelay();
133 QuicByteCount PacingSender::GetCongestionWindow() const {
134 return sender_->GetCongestionWindow();