Home | History | Annotate | Download | only in congestion_control
      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