1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/quic/congestion_control/pacing_sender.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace net { 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PacingSender::PacingSender(SendAlgorithmInterface* sender, 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch QuicTime::Delta alarm_granularity, 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 initial_packet_burst) 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : sender_(sender), 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) alarm_granularity_(alarm_granularity), 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch initial_packet_burst_(initial_packet_burst), 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch burst_tokens_(initial_packet_burst), 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) last_delayed_packet_sent_time_(QuicTime::Zero()), 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_packet_send_time_(QuicTime::Zero()), 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) was_last_send_delayed_(false), 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) has_valid_rtt_(false) { 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PacingSender::~PacingSender() {} 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(ianswett): Consider using the suggested RTT for pacing an initial 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // response. 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sender_->SetFromConfig(config, is_server); 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PacingSender::OnIncomingQuicCongestionFeedbackFrame( 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const QuicCongestionFeedbackFrame& feedback, 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicTime feedback_receive_time) { 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sender_->OnIncomingQuicCongestionFeedbackFrame( 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) feedback, feedback_receive_time); 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void PacingSender::OnCongestionEvent(bool rtt_updated, 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) QuicByteCount bytes_in_flight, 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const CongestionVector& acked_packets, 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const CongestionVector& lost_packets) { 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (rtt_updated) { 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) has_valid_rtt_ = true; 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sender_->OnCongestionEvent( 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rtt_updated, bytes_in_flight, acked_packets, lost_packets); 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool PacingSender::OnPacketSent( 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicTime sent_time, 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) QuicByteCount bytes_in_flight, 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicPacketSequenceNumber sequence_number, 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicByteCount bytes, 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HasRetransmittableData has_retransmittable_data) { 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only pace data packets once we have an updated RTT. 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const bool in_flight = 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bytes, has_retransmittable_data); 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA || !has_valid_rtt_) { 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return in_flight; 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (burst_tokens_ > 0) { 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch --burst_tokens_; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch was_last_send_delayed_ = false; 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_delayed_packet_sent_time_ = QuicTime::Zero(); 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch next_packet_send_time_ = QuicTime::Zero(); 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return in_flight; 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The next packet should be sent as soon as the current packets has 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // been transferred. We pace at twice the rate of the underlying 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // sender's bandwidth estimate during slow start and 1.25x during congestion 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // avoidance to ensure pacing doesn't prevent us from filling the window. 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const float kPacingAggression = sender_->InSlowStart() ? 2 : 1.25; 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch QuicTime::Delta delay = 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes); 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the last send was delayed, and the alarm took a long time to get 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // invoked, allow the connection to make up for lost time. 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (was_last_send_delayed_) { 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch next_packet_send_time_ = next_packet_send_time_.Add(delay); 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The send was application limited if it takes longer than the 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // pacing delay between sent packets. 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const bool application_limited = 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_delayed_packet_sent_time_.IsInitialized() && 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sent_time > last_delayed_packet_sent_time_.Add(delay); 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const bool making_up_for_lost_time = next_packet_send_time_ <= sent_time; 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // As long as we're making up time and not application limited, 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // continue to consider the packets delayed, allowing the packets to be 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // sent immediately. 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (making_up_for_lost_time && !application_limited) { 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_delayed_packet_sent_time_ = sent_time; 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch was_last_send_delayed_ = false; 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_delayed_packet_sent_time_ = QuicTime::Zero(); 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch next_packet_send_time_ = 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch QuicTime::Max(next_packet_send_time_.Add(delay), 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sent_time.Add(delay).Subtract(alarm_granularity_)); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return in_flight; 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sender_->OnRetransmissionTimeout(packets_retransmitted); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PacingSender::RevertRetransmissionTimeout() { 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sender_->RevertRetransmissionTimeout(); 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicTime::Delta PacingSender::TimeUntilSend( 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicTime now, 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) QuicByteCount bytes_in_flight, 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) HasRetransmittableData has_retransmittable_data) const { 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicTime::Delta time_until_send = 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data); 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!has_valid_rtt_) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't pace if we don't have an updated RTT estimate. 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return time_until_send; 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (bytes_in_flight == 0) { 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Add more burst tokens anytime the connection is entering quiescence. 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch burst_tokens_ = initial_packet_burst_; 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (burst_tokens_ > 0) { 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Don't pace if we have burst tokens available. 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return time_until_send; 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!time_until_send.IsZero()) { 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(time_until_send.IsInfinite()); 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The underlying sender prevents sending. 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return time_until_send; 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Don't pace ACK packets, since they do not count against CWND and do not 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cause CWND to grow. 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return QuicTime::Delta::Zero(); 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the next send time is within the alarm granularity, send immediately. 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (next_packet_send_time_ > now.Add(alarm_granularity_)) { 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Delaying packet: " 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << next_packet_send_time_.Subtract(now).ToMicroseconds(); 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) was_last_send_delayed_ = true; 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return next_packet_send_time_.Subtract(now); 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Sending packet now"; 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return QuicTime::Delta::Zero(); 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicBandwidth PacingSender::BandwidthEstimate() const { 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return sender_->BandwidthEstimate(); 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PacingSender::HasReliableBandwidthEstimate() const { 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return sender_->HasReliableBandwidthEstimate(); 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicTime::Delta PacingSender::RetransmissionDelay() const { 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return sender_->RetransmissionDelay(); 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicByteCount PacingSender::GetCongestionWindow() const { 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return sender_->GetCongestionWindow(); 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PacingSender::InSlowStart() const { 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return sender_->InSlowStart(); 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PacingSender::InRecovery() const { 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return sender_->InRecovery(); 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 177116680a4aac90f2aa7413d9095a592090648e557Ben MurdochQuicByteCount PacingSender::GetSlowStartThreshold() const { 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return sender_->GetSlowStartThreshold(); 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)CongestionControlType PacingSender::GetCongestionControlType() const { 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return sender_->GetCongestionControlType(); 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace net 186