Upstream version 6.35.121.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       updated_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::OnPacketAcked(
32     QuicPacketSequenceNumber acked_sequence_number,
33     QuicByteCount acked_bytes) {
34   sender_->OnPacketAcked(acked_sequence_number, acked_bytes);
35 }
36
37 void PacingSender::OnPacketLost(QuicPacketSequenceNumber sequence_number,
38                                 QuicTime ack_receive_time) {
39   sender_->OnPacketLost(sequence_number, ack_receive_time);
40 }
41
42 bool PacingSender::OnPacketSent(
43     QuicTime sent_time,
44     QuicPacketSequenceNumber sequence_number,
45     QuicByteCount bytes,
46     TransmissionType transmission_type,
47     HasRetransmittableData has_retransmittable_data) {
48   // Only pace data packets once we have an updated RTT.
49   if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && updated_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, sequence_number, bytes,
60                                transmission_type, has_retransmittable_data);
61 }
62
63 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
64   sender_->OnRetransmissionTimeout(packets_retransmitted);
65 }
66
67 void PacingSender::OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
68                                      QuicByteCount abandoned_bytes) {
69   sender_->OnPacketAbandoned(sequence_number, abandoned_bytes);
70 }
71
72 QuicTime::Delta PacingSender::TimeUntilSend(
73       QuicTime now,
74       TransmissionType transmission_type,
75       HasRetransmittableData has_retransmittable_data,
76       IsHandshake handshake) {
77   QuicTime::Delta time_until_send =
78       sender_->TimeUntilSend(now, transmission_type,
79                              has_retransmittable_data, handshake);
80   if (!updated_rtt_) {
81     // Don't pace if we don't have an updated RTT estimate.
82     return time_until_send;
83   }
84
85   if (!time_until_send.IsZero()) {
86     DCHECK(time_until_send.IsInfinite());
87     // The underlying sender prevents sending.
88     return time_until_send;
89   }
90
91   if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
92     // Don't pace ACK packets, since they do not count against CWND and do not
93     // cause CWND to grow.
94     return QuicTime::Delta::Zero();
95   }
96
97   if (!was_last_send_delayed_ &&
98       (!next_packet_send_time_.IsInitialized() ||
99        now > next_packet_send_time_.Add(alarm_granularity_))) {
100     // An alarm did not go off late, instead the application is "slow"
101     // delivering data.  In this case, we restrict the amount of lost time
102     // that we can make up for.
103     next_packet_send_time_ = now.Subtract(alarm_granularity_);
104   }
105
106   // If the end of the epoch is far enough in the future, delay the send.
107   if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
108     was_last_send_delayed_ = true;
109     DVLOG(1) << "Delaying packet: "
110              << next_packet_send_time_.Subtract(now).ToMicroseconds();
111     return next_packet_send_time_.Subtract(now);
112   }
113
114   // Sent it immediately.  The epoch end will be adjusted in OnPacketSent.
115   was_last_send_delayed_ = false;
116   DVLOG(1) << "Sending packet now";
117   return QuicTime::Delta::Zero();
118 }
119
120 QuicBandwidth PacingSender::BandwidthEstimate() const {
121   return sender_->BandwidthEstimate();
122 }
123
124 void PacingSender::UpdateRtt(QuicTime::Delta rtt_sample) {
125   updated_rtt_= true;
126   sender_->UpdateRtt(rtt_sample);
127 }
128
129 QuicTime::Delta PacingSender::RetransmissionDelay() const {
130   return sender_->RetransmissionDelay();
131 }
132
133 QuicByteCount PacingSender::GetCongestionWindow() const {
134   return sender_->GetCongestionWindow();
135 }
136
137 }  // namespace net