1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/quic/congestion_control/pacing_sender.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace net {
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PacingSender::PacingSender(SendAlgorithmInterface* sender,
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           QuicTime::Delta alarm_granularity,
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           uint32 initial_packet_burst)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : sender_(sender),
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      alarm_granularity_(alarm_granularity),
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      initial_packet_burst_(initial_packet_burst),
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      burst_tokens_(initial_packet_burst),
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      last_delayed_packet_sent_time_(QuicTime::Zero()),
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      next_packet_send_time_(QuicTime::Zero()),
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      was_last_send_delayed_(false),
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      has_valid_rtt_(false) {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PacingSender::~PacingSender() {}
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(ianswett): Consider using the suggested RTT for pacing an initial
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // response.
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sender_->SetFromConfig(config, is_server);
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const QuicCongestionFeedbackFrame& feedback,
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      QuicTime feedback_receive_time) {
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sender_->OnIncomingQuicCongestionFeedbackFrame(
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      feedback, feedback_receive_time);
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void PacingSender::OnCongestionEvent(bool rtt_updated,
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     QuicByteCount bytes_in_flight,
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     const CongestionVector& acked_packets,
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     const CongestionVector& lost_packets) {
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (rtt_updated) {
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    has_valid_rtt_ = true;
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  sender_->OnCongestionEvent(
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      rtt_updated, bytes_in_flight, acked_packets, lost_packets);
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool PacingSender::OnPacketSent(
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    QuicTime sent_time,
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    QuicByteCount bytes_in_flight,
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    QuicByteCount bytes,
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HasRetransmittableData has_retransmittable_data) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Only pace data packets once we have an updated RTT.
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const bool in_flight =
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number,
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            bytes, has_retransmittable_data);
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA || !has_valid_rtt_) {
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return in_flight;
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (burst_tokens_ > 0) {
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    --burst_tokens_;
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    was_last_send_delayed_ = false;
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    last_delayed_packet_sent_time_ = QuicTime::Zero();
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    next_packet_send_time_ = QuicTime::Zero();
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return in_flight;
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The next packet should be sent as soon as the current packets has
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // been transferred.  We pace at twice the rate of the underlying
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // sender's bandwidth estimate during slow start and 1.25x during congestion
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // avoidance to ensure pacing doesn't prevent us from filling the window.
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const float kPacingAggression = sender_->InSlowStart() ? 2 : 1.25;
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  QuicTime::Delta delay =
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If the last send was delayed, and the alarm took a long time to get
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // invoked, allow the connection to make up for lost time.
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (was_last_send_delayed_) {
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    next_packet_send_time_ = next_packet_send_time_.Add(delay);
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The send was application limited if it takes longer than the
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // pacing delay between sent packets.
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const bool application_limited =
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        last_delayed_packet_sent_time_.IsInitialized() &&
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        sent_time > last_delayed_packet_sent_time_.Add(delay);
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const bool making_up_for_lost_time = next_packet_send_time_ <= sent_time;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // As long as we're making up time and not application limited,
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // continue to consider the packets delayed, allowing the packets to be
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // sent immediately.
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (making_up_for_lost_time && !application_limited) {
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      last_delayed_packet_sent_time_ = sent_time;
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    } else {
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      was_last_send_delayed_ = false;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      last_delayed_packet_sent_time_ = QuicTime::Zero();
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    next_packet_send_time_ =
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        QuicTime::Max(next_packet_send_time_.Add(delay),
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      sent_time.Add(delay).Subtract(alarm_granularity_));
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return in_flight;
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sender_->OnRetransmissionTimeout(packets_retransmitted);
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PacingSender::RevertRetransmissionTimeout() {
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sender_->RevertRetransmissionTimeout();
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicTime::Delta PacingSender::TimeUntilSend(
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      QuicTime now,
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      QuicByteCount bytes_in_flight,
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      HasRetransmittableData has_retransmittable_data) const {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  QuicTime::Delta time_until_send =
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!has_valid_rtt_) {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Don't pace if we don't have an updated RTT estimate.
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return time_until_send;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (bytes_in_flight == 0) {
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Add more burst tokens anytime the connection is entering quiescence.
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    burst_tokens_ = initial_packet_burst_;
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (burst_tokens_ > 0) {
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Don't pace if we have burst tokens available.
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return time_until_send;
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!time_until_send.IsZero()) {
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(time_until_send.IsInfinite());
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // The underlying sender prevents sending.
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return time_until_send;
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Don't pace ACK packets, since they do not count against CWND and do not
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // cause CWND to grow.
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return QuicTime::Delta::Zero();
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // If the next send time is within the alarm granularity, send immediately.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(1) << "Delaying packet: "
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             << next_packet_send_time_.Subtract(now).ToMicroseconds();
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    was_last_send_delayed_ = true;
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return next_packet_send_time_.Subtract(now);
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << "Sending packet now";
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return QuicTime::Delta::Zero();
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicBandwidth PacingSender::BandwidthEstimate() const {
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return sender_->BandwidthEstimate();
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PacingSender::HasReliableBandwidthEstimate() const {
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return sender_->HasReliableBandwidthEstimate();
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicTime::Delta PacingSender::RetransmissionDelay() const {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return sender_->RetransmissionDelay();
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicByteCount PacingSender::GetCongestionWindow() const {
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return sender_->GetCongestionWindow();
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PacingSender::InSlowStart() const {
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return sender_->InSlowStart();
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PacingSender::InRecovery() const {
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return sender_->InRecovery();
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
177116680a4aac90f2aa7413d9095a592090648e557Ben MurdochQuicByteCount PacingSender::GetSlowStartThreshold() const {
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return sender_->GetSlowStartThreshold();
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)CongestionControlType PacingSender::GetCongestionControlType() const {
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return sender_->GetCongestionControlType();
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace net
186