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 7namespace net { 8 9PacingSender::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 19PacingSender::~PacingSender() {} 20 21void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { 22 sender_->SetFromConfig(config, is_server); 23} 24 25void PacingSender::OnIncomingQuicCongestionFeedbackFrame( 26 const QuicCongestionFeedbackFrame& feedback, 27 QuicTime feedback_receive_time) { 28 sender_->OnIncomingQuicCongestionFeedbackFrame( 29 feedback, feedback_receive_time); 30} 31 32void 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 43bool 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 87void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { 88 sender_->OnRetransmissionTimeout(packets_retransmitted); 89} 90 91QuicTime::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 126QuicBandwidth PacingSender::BandwidthEstimate() const { 127 return sender_->BandwidthEstimate(); 128} 129 130QuicTime::Delta PacingSender::RetransmissionDelay() const { 131 return sender_->RetransmissionDelay(); 132} 133 134QuicByteCount PacingSender::GetCongestionWindow() const { 135 return sender_->GetCongestionWindow(); 136} 137 138} // namespace net 139