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