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 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 22 PacingSender::~PacingSender() {} 23 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 30 void PacingSender::OnIncomingQuicCongestionFeedbackFrame( 31 const QuicCongestionFeedbackFrame& feedback, 32 QuicTime feedback_receive_time) { 33 sender_->OnIncomingQuicCongestionFeedbackFrame( 34 feedback, feedback_receive_time); 35 } 36 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 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 102 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { 103 sender_->OnRetransmissionTimeout(packets_retransmitted); 104 } 105 106 void PacingSender::RevertRetransmissionTimeout() { 107 sender_->RevertRetransmissionTimeout(); 108 } 109 110 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 153 QuicBandwidth PacingSender::BandwidthEstimate() const { 154 return sender_->BandwidthEstimate(); 155 } 156 157 bool PacingSender::HasReliableBandwidthEstimate() const { 158 return sender_->HasReliableBandwidthEstimate(); 159 } 160 161 QuicTime::Delta PacingSender::RetransmissionDelay() const { 162 return sender_->RetransmissionDelay(); 163 } 164 165 QuicByteCount PacingSender::GetCongestionWindow() const { 166 return sender_->GetCongestionWindow(); 167 } 168 169 bool PacingSender::InSlowStart() const { 170 return sender_->InSlowStart(); 171 } 172 173 bool PacingSender::InRecovery() const { 174 return sender_->InRecovery(); 175 } 176 177 QuicByteCount PacingSender::GetSlowStartThreshold() const { 178 return sender_->GetSlowStartThreshold(); 179 } 180 181 CongestionControlType PacingSender::GetCongestionControlType() const { 182 return sender_->GetCongestionControlType(); 183 } 184 185 } // namespace net 186