Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / net / quic / congestion_control / pacing_sender.cc
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     : sender_(sender),
12       alarm_granularity_(alarm_granularity),
13       next_packet_send_time_(QuicTime::Zero()),
14       was_last_send_delayed_(false),
15       has_valid_rtt_(false) {
16 }
17
18 PacingSender::~PacingSender() {}
19
20 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
21   sender_->SetFromConfig(config, is_server);
22 }
23
24 void PacingSender::OnIncomingQuicCongestionFeedbackFrame(
25       const QuicCongestionFeedbackFrame& feedback,
26       QuicTime feedback_receive_time) {
27   sender_->OnIncomingQuicCongestionFeedbackFrame(
28       feedback, feedback_receive_time);
29 }
30
31 void PacingSender::OnCongestionEvent(bool rtt_updated,
32                                      QuicByteCount bytes_in_flight,
33                                      const CongestionMap& acked_packets,
34                                      const CongestionMap& lost_packets) {
35   if (rtt_updated) {
36     has_valid_rtt_ = true;
37   }
38   sender_->OnCongestionEvent(
39       rtt_updated, bytes_in_flight, acked_packets, lost_packets);
40 }
41
42 bool PacingSender::OnPacketSent(
43     QuicTime sent_time,
44     QuicByteCount bytes_in_flight,
45     QuicPacketSequenceNumber sequence_number,
46     QuicByteCount bytes,
47     HasRetransmittableData has_retransmittable_data) {
48   // Only pace data packets once we have an updated RTT.
49   if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && has_valid_rtt_) {
50     // The next packet should be sent as soon as the current packets has
51     // been transferred.  We pace at twice the rate of the underlying
52     // sender's bandwidth estimate to help ensure that pacing doesn't become
53     // a bottleneck.
54     const float kPacingAggression = 2;
55     QuicTime::Delta delay =
56         BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
57     next_packet_send_time_ = next_packet_send_time_.Add(delay);
58   }
59   return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number,
60                                bytes, has_retransmittable_data);
61 }
62
63 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
64   sender_->OnRetransmissionTimeout(packets_retransmitted);
65 }
66
67 QuicTime::Delta PacingSender::TimeUntilSend(
68       QuicTime now,
69       QuicByteCount bytes_in_flight,
70       HasRetransmittableData has_retransmittable_data) {
71   QuicTime::Delta time_until_send =
72       sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
73   if (!has_valid_rtt_) {
74     // Don't pace if we don't have an updated RTT estimate.
75     return time_until_send;
76   }
77
78   if (!time_until_send.IsZero()) {
79     DCHECK(time_until_send.IsInfinite());
80     // The underlying sender prevents sending.
81     return time_until_send;
82   }
83
84   if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
85     // Don't pace ACK packets, since they do not count against CWND and do not
86     // cause CWND to grow.
87     return QuicTime::Delta::Zero();
88   }
89
90   if (!was_last_send_delayed_ &&
91       (!next_packet_send_time_.IsInitialized() ||
92        now > next_packet_send_time_.Add(alarm_granularity_))) {
93     // An alarm did not go off late, instead the application is "slow"
94     // delivering data.  In this case, we restrict the amount of lost time
95     // that we can make up for.
96     next_packet_send_time_ = now.Subtract(alarm_granularity_);
97   }
98
99   // If the end of the epoch is far enough in the future, delay the send.
100   if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
101     was_last_send_delayed_ = true;
102     DVLOG(1) << "Delaying packet: "
103              << next_packet_send_time_.Subtract(now).ToMicroseconds();
104     return next_packet_send_time_.Subtract(now);
105   }
106
107   // Sent it immediately.  The epoch end will be adjusted in OnPacketSent.
108   was_last_send_delayed_ = false;
109   DVLOG(1) << "Sending packet now";
110   return QuicTime::Delta::Zero();
111 }
112
113 QuicBandwidth PacingSender::BandwidthEstimate() const {
114   return sender_->BandwidthEstimate();
115 }
116
117 QuicTime::Delta PacingSender::RetransmissionDelay() const {
118   return sender_->RetransmissionDelay();
119 }
120
121 QuicByteCount PacingSender::GetCongestionWindow() const {
122   return sender_->GetCongestionWindow();
123 }
124
125 }  // namespace net