| 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 uint32 initial_packet_burst) |
| 12 : sender_(sender), | 12 : sender_(sender), |
| 13 alarm_granularity_(alarm_granularity), | 13 alarm_granularity_(alarm_granularity), |
| 14 initial_packet_burst_(initial_packet_burst), | 14 initial_packet_burst_(initial_packet_burst), |
| 15 burst_tokens_(initial_packet_burst), | 15 burst_tokens_(initial_packet_burst), |
| 16 last_delayed_packet_sent_time_(QuicTime::Zero()), | 16 last_delayed_packet_sent_time_(QuicTime::Zero()), |
| 17 next_packet_send_time_(QuicTime::Zero()), | 17 next_packet_send_time_(QuicTime::Zero()), |
| 18 was_last_send_delayed_(false), | 18 was_last_send_delayed_(false) { |
| 19 has_valid_rtt_(false) { | |
| 20 } | 19 } |
| 21 | 20 |
| 22 PacingSender::~PacingSender() {} | 21 PacingSender::~PacingSender() {} |
| 23 | 22 |
| 24 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { | 23 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { |
| 25 // TODO(ianswett): Consider using the suggested RTT for pacing an initial | |
| 26 // response. | |
| 27 sender_->SetFromConfig(config, is_server); | 24 sender_->SetFromConfig(config, is_server); |
| 28 } | 25 } |
| 29 | 26 |
| 30 void PacingSender::SetNumEmulatedConnections(int num_connections) { | 27 void PacingSender::SetNumEmulatedConnections(int num_connections) { |
| 31 sender_->SetNumEmulatedConnections(num_connections); | 28 sender_->SetNumEmulatedConnections(num_connections); |
| 32 } | 29 } |
| 33 | 30 |
| 34 void PacingSender::OnIncomingQuicCongestionFeedbackFrame( | 31 void PacingSender::OnIncomingQuicCongestionFeedbackFrame( |
| 35 const QuicCongestionFeedbackFrame& feedback, | 32 const QuicCongestionFeedbackFrame& feedback, |
| 36 QuicTime feedback_receive_time) { | 33 QuicTime feedback_receive_time) { |
| 37 sender_->OnIncomingQuicCongestionFeedbackFrame( | 34 sender_->OnIncomingQuicCongestionFeedbackFrame( |
| 38 feedback, feedback_receive_time); | 35 feedback, feedback_receive_time); |
| 39 } | 36 } |
| 40 | 37 |
| 41 void PacingSender::OnCongestionEvent(bool rtt_updated, | 38 void PacingSender::OnCongestionEvent(bool rtt_updated, |
| 42 QuicByteCount bytes_in_flight, | 39 QuicByteCount bytes_in_flight, |
| 43 const CongestionVector& acked_packets, | 40 const CongestionVector& acked_packets, |
| 44 const CongestionVector& lost_packets) { | 41 const CongestionVector& lost_packets) { |
| 45 if (rtt_updated) { | |
| 46 has_valid_rtt_ = true; | |
| 47 } | |
| 48 sender_->OnCongestionEvent( | 42 sender_->OnCongestionEvent( |
| 49 rtt_updated, bytes_in_flight, acked_packets, lost_packets); | 43 rtt_updated, bytes_in_flight, acked_packets, lost_packets); |
| 50 } | 44 } |
| 51 | 45 |
| 52 bool PacingSender::OnPacketSent( | 46 bool PacingSender::OnPacketSent( |
| 53 QuicTime sent_time, | 47 QuicTime sent_time, |
| 54 QuicByteCount bytes_in_flight, | 48 QuicByteCount bytes_in_flight, |
| 55 QuicPacketSequenceNumber sequence_number, | 49 QuicPacketSequenceNumber sequence_number, |
| 56 QuicByteCount bytes, | 50 QuicByteCount bytes, |
| 57 HasRetransmittableData has_retransmittable_data) { | 51 HasRetransmittableData has_retransmittable_data) { |
| 58 // Only pace data packets once we have an updated RTT. | |
| 59 const bool in_flight = | 52 const bool in_flight = |
| 60 sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, | 53 sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, |
| 61 bytes, has_retransmittable_data); | 54 bytes, has_retransmittable_data); |
| 62 if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA || !has_valid_rtt_) { | 55 if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) { |
| 63 return in_flight; | 56 return in_flight; |
| 64 } | 57 } |
| 65 if (burst_tokens_ > 0) { | 58 if (burst_tokens_ > 0) { |
| 66 --burst_tokens_; | 59 --burst_tokens_; |
| 67 was_last_send_delayed_ = false; | 60 was_last_send_delayed_ = false; |
| 68 last_delayed_packet_sent_time_ = QuicTime::Zero(); | 61 last_delayed_packet_sent_time_ = QuicTime::Zero(); |
| 69 next_packet_send_time_ = QuicTime::Zero(); | 62 next_packet_send_time_ = QuicTime::Zero(); |
| 70 return in_flight; | 63 return in_flight; |
| 71 } | 64 } |
| 72 // The next packet should be sent as soon as the current packets has | 65 // The next packet should be sent as soon as the current packets has |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 void PacingSender::RevertRetransmissionTimeout() { | 103 void PacingSender::RevertRetransmissionTimeout() { |
| 111 sender_->RevertRetransmissionTimeout(); | 104 sender_->RevertRetransmissionTimeout(); |
| 112 } | 105 } |
| 113 | 106 |
| 114 QuicTime::Delta PacingSender::TimeUntilSend( | 107 QuicTime::Delta PacingSender::TimeUntilSend( |
| 115 QuicTime now, | 108 QuicTime now, |
| 116 QuicByteCount bytes_in_flight, | 109 QuicByteCount bytes_in_flight, |
| 117 HasRetransmittableData has_retransmittable_data) const { | 110 HasRetransmittableData has_retransmittable_data) const { |
| 118 QuicTime::Delta time_until_send = | 111 QuicTime::Delta time_until_send = |
| 119 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data); | 112 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data); |
| 120 if (!has_valid_rtt_) { | |
| 121 // Don't pace if we don't have an updated RTT estimate. | |
| 122 return time_until_send; | |
| 123 } | |
| 124 if (bytes_in_flight == 0) { | 113 if (bytes_in_flight == 0) { |
| 125 // Add more burst tokens anytime the connection is entering quiescence. | 114 // Add more burst tokens anytime the connection is entering quiescence. |
| 126 burst_tokens_ = initial_packet_burst_; | 115 burst_tokens_ = initial_packet_burst_; |
| 127 } | 116 } |
| 128 if (burst_tokens_ > 0) { | 117 if (burst_tokens_ > 0) { |
| 129 // Don't pace if we have burst tokens available. | 118 // Don't pace if we have burst tokens available. |
| 130 return time_until_send; | 119 return time_until_send; |
| 131 } | 120 } |
| 132 | 121 |
| 133 if (!time_until_send.IsZero()) { | 122 if (!time_until_send.IsZero()) { |
| 134 DCHECK(time_until_send.IsInfinite()); | 123 DCHECK(time_until_send.IsInfinite()); |
| 135 // The underlying sender prevents sending. | 124 // The underlying sender prevents sending. |
| 136 return time_until_send; | 125 return time_until_send; |
| 137 } | 126 } |
| 138 | 127 |
| 139 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { | 128 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { |
| 140 // Don't pace ACK packets, since they do not count against CWND and do not | 129 // Don't pace ACK packets, since they do not count against CWND and do not |
| 141 // cause CWND to grow. | 130 // cause CWND to grow. |
| 142 return QuicTime::Delta::Zero(); | 131 return QuicTime::Delta::Zero(); |
| 143 } | 132 } |
| 144 | 133 |
| 145 // If the next send time is within the alarm granularity, send immediately. | 134 // If the next send time is within the alarm granularity, send immediately. |
| 135 // TODO(ianswett): This granularity logic ends up sending more packets than |
| 136 // intended in an effort to make up for lost time that wasn't lost. |
| 146 if (next_packet_send_time_ > now.Add(alarm_granularity_)) { | 137 if (next_packet_send_time_ > now.Add(alarm_granularity_)) { |
| 147 DVLOG(1) << "Delaying packet: " | 138 DVLOG(1) << "Delaying packet: " |
| 148 << next_packet_send_time_.Subtract(now).ToMicroseconds(); | 139 << next_packet_send_time_.Subtract(now).ToMicroseconds(); |
| 149 was_last_send_delayed_ = true; | 140 was_last_send_delayed_ = true; |
| 150 return next_packet_send_time_.Subtract(now); | 141 return next_packet_send_time_.Subtract(now); |
| 151 } | 142 } |
| 152 | 143 |
| 153 DVLOG(1) << "Sending packet now"; | 144 DVLOG(1) << "Sending packet now"; |
| 154 return QuicTime::Delta::Zero(); | 145 return QuicTime::Delta::Zero(); |
| 155 } | 146 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 180 | 171 |
| 181 QuicByteCount PacingSender::GetSlowStartThreshold() const { | 172 QuicByteCount PacingSender::GetSlowStartThreshold() const { |
| 182 return sender_->GetSlowStartThreshold(); | 173 return sender_->GetSlowStartThreshold(); |
| 183 } | 174 } |
| 184 | 175 |
| 185 CongestionControlType PacingSender::GetCongestionControlType() const { | 176 CongestionControlType PacingSender::GetCongestionControlType() const { |
| 186 return sender_->GetCongestionControlType(); | 177 return sender_->GetCongestionControlType(); |
| 187 } | 178 } |
| 188 | 179 |
| 189 } // namespace net | 180 } // namespace net |
| OLD | NEW |