• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PacingSender(SendAlgorithmInterface * sender,QuicTime::Delta alarm_granularity)9 PacingSender::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 
~PacingSender()19 PacingSender::~PacingSender() {}
20 
SetFromConfig(const QuicConfig & config,bool is_server)21 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
22   sender_->SetFromConfig(config, is_server);
23 }
24 
OnIncomingQuicCongestionFeedbackFrame(const QuicCongestionFeedbackFrame & feedback,QuicTime feedback_receive_time)25 void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
26       const QuicCongestionFeedbackFrame& feedback,
27       QuicTime feedback_receive_time) {
28   sender_->OnIncomingQuicCongestionFeedbackFrame(
29       feedback, feedback_receive_time);
30 }
31 
OnCongestionEvent(bool rtt_updated,QuicByteCount bytes_in_flight,const CongestionMap & acked_packets,const CongestionMap & lost_packets)32 void 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 
OnPacketSent(QuicTime sent_time,QuicByteCount bytes_in_flight,QuicPacketSequenceNumber sequence_number,QuicByteCount bytes,HasRetransmittableData has_retransmittable_data)43 bool 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 
OnRetransmissionTimeout(bool packets_retransmitted)87 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
88   sender_->OnRetransmissionTimeout(packets_retransmitted);
89 }
90 
TimeUntilSend(QuicTime now,QuicByteCount bytes_in_flight,HasRetransmittableData has_retransmittable_data) const91 QuicTime::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 
BandwidthEstimate() const126 QuicBandwidth PacingSender::BandwidthEstimate() const {
127   return sender_->BandwidthEstimate();
128 }
129 
RetransmissionDelay() const130 QuicTime::Delta PacingSender::RetransmissionDelay() const {
131   return sender_->RetransmissionDelay();
132 }
133 
GetCongestionWindow() const134 QuicByteCount PacingSender::GetCongestionWindow() const {
135   return sender_->GetCongestionWindow();
136 }
137 
138 }  // namespace net
139