fix_rate_sender.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
1// Copyright (c) 2012 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/fix_rate_sender.h" 6 7#include <math.h> 8 9#include "base/logging.h" 10#include "net/quic/quic_protocol.h" 11 12namespace { 13 const int kInitialBitrate = 100000; // In bytes per second. 14 const uint64 kWindowSizeUs = 10000; // 10 ms. 15} 16 17namespace net { 18 19FixRateSender::FixRateSender(const QuicClock* clock) 20 : bitrate_(QuicBandwidth::FromBytesPerSecond(kInitialBitrate)), 21 fix_rate_leaky_bucket_(bitrate_), 22 paced_sender_(bitrate_), 23 data_in_flight_(0), 24 latest_rtt_(QuicTime::Delta::Zero()) { 25 DLOG(INFO) << "FixRateSender"; 26} 27 28FixRateSender::~FixRateSender() { 29} 30 31void FixRateSender::OnIncomingQuicCongestionFeedbackFrame( 32 const QuicCongestionFeedbackFrame& feedback, 33 QuicTime feedback_receive_time, 34 const SentPacketsMap& /*sent_packets*/) { 35 DCHECK(feedback.type == kFixRate) << 36 "Invalid incoming CongestionFeedbackType:" << feedback.type; 37 if (feedback.type == kFixRate) { 38 bitrate_ = feedback.fix_rate.bitrate; 39 fix_rate_leaky_bucket_.SetDrainingRate(feedback_receive_time, bitrate_); 40 paced_sender_.UpdateBandwidthEstimate(feedback_receive_time, bitrate_); 41 } 42 // Silently ignore invalid messages in release mode. 43} 44 45void FixRateSender::OnIncomingAck( 46 QuicPacketSequenceNumber /*acked_sequence_number*/, 47 QuicByteCount bytes_acked, 48 QuicTime::Delta rtt) { 49 // RTT can't be negative. 50 DCHECK_LE(0, rtt.ToMicroseconds()); 51 52 data_in_flight_ -= bytes_acked; 53 if (rtt.IsInfinite()) { 54 return; 55 } 56 latest_rtt_ = rtt; 57} 58 59void FixRateSender::OnIncomingLoss(QuicTime /*ack_receive_time*/) { 60 // Ignore losses for fix rate sender. 61} 62 63bool FixRateSender::SentPacket( 64 QuicTime sent_time, 65 QuicPacketSequenceNumber /*sequence_number*/, 66 QuicByteCount bytes, 67 Retransmission is_retransmission, 68 HasRetransmittableData /*has_retransmittable_data*/) { 69 fix_rate_leaky_bucket_.Add(sent_time, bytes); 70 paced_sender_.SentPacket(sent_time, bytes); 71 if (is_retransmission == NOT_RETRANSMISSION) { 72 data_in_flight_ += bytes; 73 } 74 return true; 75} 76 77void FixRateSender::AbandoningPacket( 78 QuicPacketSequenceNumber /*sequence_number*/, 79 QuicByteCount /*abandoned_bytes*/) { 80} 81 82QuicTime::Delta FixRateSender::TimeUntilSend( 83 QuicTime now, 84 Retransmission /*is_retransmission*/, 85 HasRetransmittableData /*has_retransmittable_data*/, 86 IsHandshake /*handshake*/) { 87 if (CongestionWindow() > fix_rate_leaky_bucket_.BytesPending(now)) { 88 if (CongestionWindow() <= data_in_flight_) { 89 // We need an ack before we send more. 90 return QuicTime::Delta::Infinite(); 91 } 92 return paced_sender_.TimeUntilSend(now, QuicTime::Delta::Zero()); 93 } 94 QuicTime::Delta time_remaining = fix_rate_leaky_bucket_.TimeRemaining(now); 95 if (time_remaining.IsZero()) { 96 // We need an ack before we send more. 97 return QuicTime::Delta::Infinite(); 98 } 99 return paced_sender_.TimeUntilSend(now, time_remaining); 100} 101 102QuicByteCount FixRateSender::CongestionWindow() { 103 QuicByteCount window_size_bytes = bitrate_.ToBytesPerPeriod( 104 QuicTime::Delta::FromMicroseconds(kWindowSizeUs)); 105 // Make sure window size is not less than a packet. 106 return std::max(kMaxPacketSize, window_size_bytes); 107} 108 109QuicBandwidth FixRateSender::BandwidthEstimate() { 110 return bitrate_; 111} 112 113QuicTime::Delta FixRateSender::SmoothedRtt() { 114 // TODO(satyamshekhar): Calculate and return smoothed rtt. 115 return latest_rtt_; 116} 117 118QuicTime::Delta FixRateSender::RetransmissionDelay() { 119 // TODO(pwestin): Calculate and return retransmission delay. 120 // Use 2 * the latest RTT for now. 121 return latest_rtt_.Add(latest_rtt_); 122} 123 124} // namespace net 125