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.
5 #include "net/quic/congestion_control/fix_rate_sender.h"
11 #include "base/logging.h"
12 #include "net/quic/quic_protocol.h"
15 const int kInitialBitrate = 100000; // In bytes per second.
16 const uint64 kWindowSizeUs = 10000; // 10 ms.
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_),
27 latest_rtt_(QuicTime::Delta::Zero()) {
28 DLOG(INFO) << "FixRateSender";
31 FixRateSender::~FixRateSender() {
34 void FixRateSender::SetFromConfig(const QuicConfig& config, bool is_server) {
35 max_segment_size_ = config.server_max_packet_size();
36 paced_sender_.set_max_segment_size(max_segment_size_);
39 void FixRateSender::OnIncomingQuicCongestionFeedbackFrame(
40 const QuicCongestionFeedbackFrame& feedback,
41 QuicTime feedback_receive_time,
42 const SentPacketsMap& /*sent_packets*/) {
43 if (feedback.type != kFixRate) {
44 LOG(DFATAL) << "Invalid incoming CongestionFeedbackType:" << feedback.type;
46 if (feedback.type == kFixRate) {
47 bitrate_ = feedback.fix_rate.bitrate;
48 fix_rate_leaky_bucket_.SetDrainingRate(feedback_receive_time, bitrate_);
49 paced_sender_.UpdateBandwidthEstimate(feedback_receive_time, bitrate_);
51 // Silently ignore invalid messages in release mode.
54 void FixRateSender::OnIncomingAck(
55 QuicPacketSequenceNumber /*acked_sequence_number*/,
56 QuicByteCount bytes_acked,
57 QuicTime::Delta rtt) {
58 // RTT can't be negative.
59 DCHECK_LE(0, rtt.ToMicroseconds());
61 data_in_flight_ -= bytes_acked;
62 if (rtt.IsInfinite()) {
68 void FixRateSender::OnIncomingLoss(QuicTime /*ack_receive_time*/) {
69 // Ignore losses for fix rate sender.
72 bool FixRateSender::OnPacketSent(
74 QuicPacketSequenceNumber /*sequence_number*/,
76 TransmissionType transmission_type,
77 HasRetransmittableData /*has_retransmittable_data*/) {
78 fix_rate_leaky_bucket_.Add(sent_time, bytes);
79 paced_sender_.OnPacketSent(sent_time, bytes);
80 if (transmission_type == NOT_RETRANSMISSION) {
81 data_in_flight_ += bytes;
86 void FixRateSender::OnPacketAbandoned(
87 QuicPacketSequenceNumber /*sequence_number*/,
88 QuicByteCount /*abandoned_bytes*/) {
91 QuicTime::Delta FixRateSender::TimeUntilSend(
93 TransmissionType /* transmission_type */,
94 HasRetransmittableData /*has_retransmittable_data*/,
95 IsHandshake /*handshake*/) {
96 if (CongestionWindow() > fix_rate_leaky_bucket_.BytesPending(now)) {
97 if (CongestionWindow() <= data_in_flight_) {
98 // We need an ack before we send more.
99 return QuicTime::Delta::Infinite();
101 return paced_sender_.TimeUntilSend(now, QuicTime::Delta::Zero());
103 QuicTime::Delta time_remaining = fix_rate_leaky_bucket_.TimeRemaining(now);
104 if (time_remaining.IsZero()) {
105 // We need an ack before we send more.
106 return QuicTime::Delta::Infinite();
108 return paced_sender_.TimeUntilSend(now, time_remaining);
111 QuicByteCount FixRateSender::CongestionWindow() {
112 QuicByteCount window_size_bytes = bitrate_.ToBytesPerPeriod(
113 QuicTime::Delta::FromMicroseconds(kWindowSizeUs));
114 // Make sure window size is not less than a packet.
115 return std::max(kDefaultMaxPacketSize, window_size_bytes);
118 QuicBandwidth FixRateSender::BandwidthEstimate() {
122 QuicTime::Delta FixRateSender::SmoothedRtt() {
123 // TODO(satyamshekhar): Calculate and return smoothed rtt.
127 QuicTime::Delta FixRateSender::RetransmissionDelay() {
128 // TODO(pwestin): Calculate and return retransmission delay.
129 // Use 2 * the latest RTT for now.
130 return latest_rtt_.Add(latest_rtt_);
133 QuicByteCount FixRateSender::GetCongestionWindow() {
137 void FixRateSender::SetCongestionWindow(QuicByteCount window) {