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