Home | History | Annotate | Download | only in congestion_control
      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