| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/congestion_control/pacing_sender.h" | 5 #include "net/quic/congestion_control/pacing_sender.h" |
| 6 | 6 |
| 7 namespace net { | 7 namespace net { |
| 8 | 8 |
| 9 PacingSender::PacingSender(SendAlgorithmInterface* sender, | 9 PacingSender::PacingSender(SendAlgorithmInterface* sender, |
| 10 QuicTime::Delta alarm_granularity) | 10 QuicTime::Delta alarm_granularity, |
| 11 uint32 initial_packet_burst) |
| 11 : sender_(sender), | 12 : sender_(sender), |
| 12 alarm_granularity_(alarm_granularity), | 13 alarm_granularity_(alarm_granularity), |
| 14 initial_packet_burst_(initial_packet_burst), |
| 15 burst_tokens_(initial_packet_burst), |
| 13 last_delayed_packet_sent_time_(QuicTime::Zero()), | 16 last_delayed_packet_sent_time_(QuicTime::Zero()), |
| 14 next_packet_send_time_(QuicTime::Zero()), | 17 next_packet_send_time_(QuicTime::Zero()), |
| 15 was_last_send_delayed_(false), | 18 was_last_send_delayed_(false), |
| 16 has_valid_rtt_(false) { | 19 has_valid_rtt_(false) { |
| 17 } | 20 } |
| 18 | 21 |
| 19 PacingSender::~PacingSender() {} | 22 PacingSender::~PacingSender() {} |
| 20 | 23 |
| 21 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { | 24 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { |
| 25 // TODO(ianswett): Consider using the suggested RTT for pacing an initial |
| 26 // response. |
| 22 sender_->SetFromConfig(config, is_server); | 27 sender_->SetFromConfig(config, is_server); |
| 23 } | 28 } |
| 24 | 29 |
| 25 void PacingSender::OnIncomingQuicCongestionFeedbackFrame( | 30 void PacingSender::OnIncomingQuicCongestionFeedbackFrame( |
| 26 const QuicCongestionFeedbackFrame& feedback, | 31 const QuicCongestionFeedbackFrame& feedback, |
| 27 QuicTime feedback_receive_time) { | 32 QuicTime feedback_receive_time) { |
| 28 sender_->OnIncomingQuicCongestionFeedbackFrame( | 33 sender_->OnIncomingQuicCongestionFeedbackFrame( |
| 29 feedback, feedback_receive_time); | 34 feedback, feedback_receive_time); |
| 30 } | 35 } |
| 31 | 36 |
| 32 void PacingSender::OnCongestionEvent(bool rtt_updated, | 37 void PacingSender::OnCongestionEvent(bool rtt_updated, |
| 33 QuicByteCount bytes_in_flight, | 38 QuicByteCount bytes_in_flight, |
| 34 const CongestionMap& acked_packets, | 39 const CongestionMap& acked_packets, |
| 35 const CongestionMap& lost_packets) { | 40 const CongestionMap& lost_packets) { |
| 36 if (rtt_updated) { | 41 if (rtt_updated) { |
| 37 has_valid_rtt_ = true; | 42 has_valid_rtt_ = true; |
| 38 } | 43 } |
| 44 if (bytes_in_flight == 0) { |
| 45 // Add more burst tokens anytime the connection is entering quiescence. |
| 46 burst_tokens_ = initial_packet_burst_; |
| 47 } |
| 39 sender_->OnCongestionEvent( | 48 sender_->OnCongestionEvent( |
| 40 rtt_updated, bytes_in_flight, acked_packets, lost_packets); | 49 rtt_updated, bytes_in_flight, acked_packets, lost_packets); |
| 41 } | 50 } |
| 42 | 51 |
| 43 bool PacingSender::OnPacketSent( | 52 bool PacingSender::OnPacketSent( |
| 44 QuicTime sent_time, | 53 QuicTime sent_time, |
| 45 QuicByteCount bytes_in_flight, | 54 QuicByteCount bytes_in_flight, |
| 46 QuicPacketSequenceNumber sequence_number, | 55 QuicPacketSequenceNumber sequence_number, |
| 47 QuicByteCount bytes, | 56 QuicByteCount bytes, |
| 48 HasRetransmittableData has_retransmittable_data) { | 57 HasRetransmittableData has_retransmittable_data) { |
| 49 // Only pace data packets once we have an updated RTT. | 58 // Only pace data packets once we have an updated RTT. |
| 50 if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && has_valid_rtt_) { | 59 const bool in_flight = |
| 51 // The next packet should be sent as soon as the current packets has | 60 sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, |
| 52 // been transferred. We pace at twice the rate of the underlying | 61 bytes, has_retransmittable_data); |
| 53 // sender's bandwidth estimate to help ensure that pacing doesn't become | 62 if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA || !has_valid_rtt_) { |
| 54 // a bottleneck. | 63 return in_flight; |
| 55 const float kPacingAggression = 2; | 64 } |
| 56 QuicTime::Delta delay = | 65 if (burst_tokens_ > 0) { |
| 57 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes); | 66 --burst_tokens_; |
| 58 // If the last send was delayed, and the alarm took a long time to get | 67 was_last_send_delayed_ = false; |
| 59 // invoked, allow the connection to make up for lost time. | 68 last_delayed_packet_sent_time_ = QuicTime::Zero(); |
| 60 if (was_last_send_delayed_) { | 69 next_packet_send_time_ = QuicTime::Zero(); |
| 61 next_packet_send_time_ = next_packet_send_time_.Add(delay); | 70 return in_flight; |
| 62 // The send was application limited if it takes longer than the | 71 } |
| 63 // pacing delay between sent packets. | 72 // The next packet should be sent as soon as the current packets has |
| 64 const bool application_limited = | 73 // been transferred. We pace at twice the rate of the underlying |
| 65 last_delayed_packet_sent_time_.IsInitialized() && | 74 // sender's bandwidth estimate to help ensure that pacing doesn't become |
| 66 sent_time > last_delayed_packet_sent_time_.Add(delay); | 75 // a bottleneck. |
| 67 const bool making_up_for_lost_time = next_packet_send_time_ <= sent_time; | 76 const float kPacingAggression = 2; |
| 68 // As long as we're making up time and not application limited, | 77 QuicTime::Delta delay = |
| 69 // continue to consider the packets delayed, allowing the packets to be | 78 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes); |
| 70 // sent immediately. | 79 // If the last send was delayed, and the alarm took a long time to get |
| 71 if (making_up_for_lost_time && !application_limited) { | 80 // invoked, allow the connection to make up for lost time. |
| 72 last_delayed_packet_sent_time_ = sent_time; | 81 if (was_last_send_delayed_) { |
| 73 } else { | 82 next_packet_send_time_ = next_packet_send_time_.Add(delay); |
| 74 was_last_send_delayed_ = false; | 83 // The send was application limited if it takes longer than the |
| 75 last_delayed_packet_sent_time_ = QuicTime::Zero(); | 84 // pacing delay between sent packets. |
| 76 } | 85 const bool application_limited = |
| 86 last_delayed_packet_sent_time_.IsInitialized() && |
| 87 sent_time > last_delayed_packet_sent_time_.Add(delay); |
| 88 const bool making_up_for_lost_time = next_packet_send_time_ <= sent_time; |
| 89 // As long as we're making up time and not application limited, |
| 90 // continue to consider the packets delayed, allowing the packets to be |
| 91 // sent immediately. |
| 92 if (making_up_for_lost_time && !application_limited) { |
| 93 last_delayed_packet_sent_time_ = sent_time; |
| 77 } else { | 94 } else { |
| 78 next_packet_send_time_ = | 95 was_last_send_delayed_ = false; |
| 79 QuicTime::Max(next_packet_send_time_.Add(delay), | 96 last_delayed_packet_sent_time_ = QuicTime::Zero(); |
| 80 sent_time.Add(delay).Subtract(alarm_granularity_)); | |
| 81 } | 97 } |
| 98 } else { |
| 99 next_packet_send_time_ = |
| 100 QuicTime::Max(next_packet_send_time_.Add(delay), |
| 101 sent_time.Add(delay).Subtract(alarm_granularity_)); |
| 82 } | 102 } |
| 83 return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, | 103 return in_flight; |
| 84 bytes, has_retransmittable_data); | |
| 85 } | 104 } |
| 86 | 105 |
| 87 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { | 106 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { |
| 88 sender_->OnRetransmissionTimeout(packets_retransmitted); | 107 sender_->OnRetransmissionTimeout(packets_retransmitted); |
| 89 } | 108 } |
| 90 | 109 |
| 91 void PacingSender::RevertRetransmissionTimeout() { | 110 void PacingSender::RevertRetransmissionTimeout() { |
| 92 sender_->RevertRetransmissionTimeout(); | 111 sender_->RevertRetransmissionTimeout(); |
| 93 } | 112 } |
| 94 | 113 |
| 95 QuicTime::Delta PacingSender::TimeUntilSend( | 114 QuicTime::Delta PacingSender::TimeUntilSend( |
| 96 QuicTime now, | 115 QuicTime now, |
| 97 QuicByteCount bytes_in_flight, | 116 QuicByteCount bytes_in_flight, |
| 98 HasRetransmittableData has_retransmittable_data) const { | 117 HasRetransmittableData has_retransmittable_data) const { |
| 99 QuicTime::Delta time_until_send = | 118 QuicTime::Delta time_until_send = |
| 100 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data); | 119 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data); |
| 101 if (!has_valid_rtt_) { | 120 if (!has_valid_rtt_) { |
| 102 // Don't pace if we don't have an updated RTT estimate. | 121 // Don't pace if we don't have an updated RTT estimate. |
| 103 return time_until_send; | 122 return time_until_send; |
| 104 } | 123 } |
| 124 if (burst_tokens_ > 0) { |
| 125 // Don't pace if we have burst tokens available. |
| 126 return time_until_send; |
| 127 } |
| 105 | 128 |
| 106 if (!time_until_send.IsZero()) { | 129 if (!time_until_send.IsZero()) { |
| 107 DCHECK(time_until_send.IsInfinite()); | 130 DCHECK(time_until_send.IsInfinite()); |
| 108 // The underlying sender prevents sending. | 131 // The underlying sender prevents sending. |
| 109 return time_until_send; | 132 return time_until_send; |
| 110 } | 133 } |
| 111 | 134 |
| 112 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { | 135 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { |
| 113 // Don't pace ACK packets, since they do not count against CWND and do not | 136 // Don't pace ACK packets, since they do not count against CWND and do not |
| 114 // cause CWND to grow. | 137 // cause CWND to grow. |
| 115 return QuicTime::Delta::Zero(); | 138 return QuicTime::Delta::Zero(); |
| 116 } | 139 } |
| 117 | 140 |
| 118 // If the next send time is within the alarm granularity, send immediately. | 141 // If the next send time is within the alarm granularity, send immediately. |
| 119 if (next_packet_send_time_ > now.Add(alarm_granularity_)) { | 142 if (next_packet_send_time_ > now.Add(alarm_granularity_)) { |
| 120 DVLOG(1) << "Delaying packet: " | 143 DVLOG(1) << "Delaying packet: " |
| 121 << next_packet_send_time_.Subtract(now).ToMicroseconds(); | 144 << next_packet_send_time_.Subtract(now).ToMicroseconds(); |
| 122 was_last_send_delayed_ = true; | 145 was_last_send_delayed_ = true; |
| 123 return next_packet_send_time_.Subtract(now); | 146 return next_packet_send_time_.Subtract(now); |
| 124 } | 147 } |
| 125 | 148 |
| 126 DVLOG(1) << "Sending packet now"; | 149 DVLOG(1) << "Sending packet now"; |
| 127 return QuicTime::Delta::Zero(); | 150 return QuicTime::Delta::Zero(); |
| 128 } | 151 } |
| 129 | 152 |
| 130 QuicBandwidth PacingSender::BandwidthEstimate() const { | 153 QuicBandwidth PacingSender::BandwidthEstimate() const { |
| 131 return sender_->BandwidthEstimate(); | 154 return sender_->BandwidthEstimate(); |
| 132 } | 155 } |
| 133 | 156 |
| 157 bool PacingSender::HasReliableBandwidthEstimate() const { |
| 158 return sender_->HasReliableBandwidthEstimate(); |
| 159 } |
| 160 |
| 134 QuicTime::Delta PacingSender::RetransmissionDelay() const { | 161 QuicTime::Delta PacingSender::RetransmissionDelay() const { |
| 135 return sender_->RetransmissionDelay(); | 162 return sender_->RetransmissionDelay(); |
| 136 } | 163 } |
| 137 | 164 |
| 138 QuicByteCount PacingSender::GetCongestionWindow() const { | 165 QuicByteCount PacingSender::GetCongestionWindow() const { |
| 139 return sender_->GetCongestionWindow(); | 166 return sender_->GetCongestionWindow(); |
| 140 } | 167 } |
| 141 | 168 |
| 142 } // namespace net | 169 } // namespace net |
| OLD | NEW |