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