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