1 // Copyright 2016 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 "quiche/quic/core/congestion_control/bandwidth_sampler.h"
6
7 #include <algorithm>
8
9 #include "quiche/quic/core/quic_types.h"
10 #include "quiche/quic/platform/api/quic_bug_tracker.h"
11 #include "quiche/quic/platform/api/quic_flag_utils.h"
12 #include "quiche/quic/platform/api/quic_flags.h"
13 #include "quiche/quic/platform/api/quic_logging.h"
14
15 namespace quic {
16
operator <<(std::ostream & os,const SendTimeState & s)17 std::ostream& operator<<(std::ostream& os, const SendTimeState& s) {
18 os << "{valid:" << s.is_valid << ", app_limited:" << s.is_app_limited
19 << ", total_sent:" << s.total_bytes_sent
20 << ", total_acked:" << s.total_bytes_acked
21 << ", total_lost:" << s.total_bytes_lost
22 << ", inflight:" << s.bytes_in_flight << "}";
23 return os;
24 }
25
Update(QuicBandwidth bandwidth_estimate,bool is_new_max_bandwidth,QuicRoundTripCount round_trip_count,QuicPacketNumber last_sent_packet_number,QuicPacketNumber last_acked_packet_number,QuicTime ack_time,QuicByteCount bytes_acked)26 QuicByteCount MaxAckHeightTracker::Update(
27 QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
28 QuicRoundTripCount round_trip_count,
29 QuicPacketNumber last_sent_packet_number,
30 QuicPacketNumber last_acked_packet_number, QuicTime ack_time,
31 QuicByteCount bytes_acked) {
32 bool force_new_epoch = false;
33
34 if (reduce_extra_acked_on_bandwidth_increase_ && is_new_max_bandwidth) {
35 // Save and clear existing entries.
36 ExtraAckedEvent best = max_ack_height_filter_.GetBest();
37 ExtraAckedEvent second_best = max_ack_height_filter_.GetSecondBest();
38 ExtraAckedEvent third_best = max_ack_height_filter_.GetThirdBest();
39 max_ack_height_filter_.Clear();
40
41 // Reinsert the heights into the filter after recalculating.
42 QuicByteCount expected_bytes_acked = bandwidth_estimate * best.time_delta;
43 if (expected_bytes_acked < best.bytes_acked) {
44 best.extra_acked = best.bytes_acked - expected_bytes_acked;
45 max_ack_height_filter_.Update(best, best.round);
46 }
47 expected_bytes_acked = bandwidth_estimate * second_best.time_delta;
48 if (expected_bytes_acked < second_best.bytes_acked) {
49 QUICHE_DCHECK_LE(best.round, second_best.round);
50 second_best.extra_acked = second_best.bytes_acked - expected_bytes_acked;
51 max_ack_height_filter_.Update(second_best, second_best.round);
52 }
53 expected_bytes_acked = bandwidth_estimate * third_best.time_delta;
54 if (expected_bytes_acked < third_best.bytes_acked) {
55 QUICHE_DCHECK_LE(second_best.round, third_best.round);
56 third_best.extra_acked = third_best.bytes_acked - expected_bytes_acked;
57 max_ack_height_filter_.Update(third_best, third_best.round);
58 }
59 }
60
61 // If any packet sent after the start of the epoch has been acked, start a new
62 // epoch.
63 if (start_new_aggregation_epoch_after_full_round_ &&
64 last_sent_packet_number_before_epoch_.IsInitialized() &&
65 last_acked_packet_number.IsInitialized() &&
66 last_acked_packet_number > last_sent_packet_number_before_epoch_) {
67 QUIC_DVLOG(3) << "Force starting a new aggregation epoch. "
68 "last_sent_packet_number_before_epoch_:"
69 << last_sent_packet_number_before_epoch_
70 << ", last_acked_packet_number:" << last_acked_packet_number;
71 if (reduce_extra_acked_on_bandwidth_increase_) {
72 QUIC_BUG(quic_bwsampler_46)
73 << "A full round of aggregation should never "
74 << "pass with startup_include_extra_acked(B204) enabled.";
75 }
76 force_new_epoch = true;
77 }
78 if (aggregation_epoch_start_time_ == QuicTime::Zero() || force_new_epoch) {
79 aggregation_epoch_bytes_ = bytes_acked;
80 aggregation_epoch_start_time_ = ack_time;
81 last_sent_packet_number_before_epoch_ = last_sent_packet_number;
82 ++num_ack_aggregation_epochs_;
83 return 0;
84 }
85
86 // Compute how many bytes are expected to be delivered, assuming max bandwidth
87 // is correct.
88 QuicTime::Delta aggregation_delta = ack_time - aggregation_epoch_start_time_;
89 QuicByteCount expected_bytes_acked = bandwidth_estimate * aggregation_delta;
90 // Reset the current aggregation epoch as soon as the ack arrival rate is less
91 // than or equal to the max bandwidth.
92 if (aggregation_epoch_bytes_ <=
93 ack_aggregation_bandwidth_threshold_ * expected_bytes_acked) {
94 QUIC_DVLOG(3) << "Starting a new aggregation epoch because "
95 "aggregation_epoch_bytes_ "
96 << aggregation_epoch_bytes_
97 << " is smaller than expected. "
98 "ack_aggregation_bandwidth_threshold_:"
99 << ack_aggregation_bandwidth_threshold_
100 << ", expected_bytes_acked:" << expected_bytes_acked
101 << ", bandwidth_estimate:" << bandwidth_estimate
102 << ", aggregation_duration:" << aggregation_delta
103 << ", new_aggregation_epoch:" << ack_time
104 << ", new_aggregation_bytes_acked:" << bytes_acked;
105 // Reset to start measuring a new aggregation epoch.
106 aggregation_epoch_bytes_ = bytes_acked;
107 aggregation_epoch_start_time_ = ack_time;
108 last_sent_packet_number_before_epoch_ = last_sent_packet_number;
109 ++num_ack_aggregation_epochs_;
110 return 0;
111 }
112
113 aggregation_epoch_bytes_ += bytes_acked;
114
115 // Compute how many extra bytes were delivered vs max bandwidth.
116 QuicByteCount extra_bytes_acked =
117 aggregation_epoch_bytes_ - expected_bytes_acked;
118 QUIC_DVLOG(3) << "Updating MaxAckHeight. ack_time:" << ack_time
119 << ", last sent packet:" << last_sent_packet_number
120 << ", bandwidth_estimate:" << bandwidth_estimate
121 << ", bytes_acked:" << bytes_acked
122 << ", expected_bytes_acked:" << expected_bytes_acked
123 << ", aggregation_epoch_bytes_:" << aggregation_epoch_bytes_
124 << ", extra_bytes_acked:" << extra_bytes_acked;
125 ExtraAckedEvent new_event;
126 new_event.extra_acked = extra_bytes_acked;
127 new_event.bytes_acked = aggregation_epoch_bytes_;
128 new_event.time_delta = aggregation_delta;
129 max_ack_height_filter_.Update(new_event, round_trip_count);
130 return extra_bytes_acked;
131 }
132
BandwidthSampler(const QuicUnackedPacketMap * unacked_packet_map,QuicRoundTripCount max_height_tracker_window_length)133 BandwidthSampler::BandwidthSampler(
134 const QuicUnackedPacketMap* unacked_packet_map,
135 QuicRoundTripCount max_height_tracker_window_length)
136 : total_bytes_sent_(0),
137 total_bytes_acked_(0),
138 total_bytes_lost_(0),
139 total_bytes_neutered_(0),
140 total_bytes_sent_at_last_acked_packet_(0),
141 last_acked_packet_sent_time_(QuicTime::Zero()),
142 last_acked_packet_ack_time_(QuicTime::Zero()),
143 is_app_limited_(true),
144 connection_state_map_(),
145 max_tracked_packets_(GetQuicFlag(quic_max_tracked_packet_count)),
146 unacked_packet_map_(unacked_packet_map),
147 max_ack_height_tracker_(max_height_tracker_window_length),
148 total_bytes_acked_after_last_ack_event_(0),
149 overestimate_avoidance_(false),
150 limit_max_ack_height_tracker_by_send_rate_(false) {}
151
BandwidthSampler(const BandwidthSampler & other)152 BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
153 : total_bytes_sent_(other.total_bytes_sent_),
154 total_bytes_acked_(other.total_bytes_acked_),
155 total_bytes_lost_(other.total_bytes_lost_),
156 total_bytes_neutered_(other.total_bytes_neutered_),
157 total_bytes_sent_at_last_acked_packet_(
158 other.total_bytes_sent_at_last_acked_packet_),
159 last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
160 last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
161 last_sent_packet_(other.last_sent_packet_),
162 last_acked_packet_(other.last_acked_packet_),
163 is_app_limited_(other.is_app_limited_),
164 end_of_app_limited_phase_(other.end_of_app_limited_phase_),
165 connection_state_map_(other.connection_state_map_),
166 recent_ack_points_(other.recent_ack_points_),
167 a0_candidates_(other.a0_candidates_),
168 max_tracked_packets_(other.max_tracked_packets_),
169 unacked_packet_map_(other.unacked_packet_map_),
170 max_ack_height_tracker_(other.max_ack_height_tracker_),
171 total_bytes_acked_after_last_ack_event_(
172 other.total_bytes_acked_after_last_ack_event_),
173 overestimate_avoidance_(other.overestimate_avoidance_),
174 limit_max_ack_height_tracker_by_send_rate_(
175 other.limit_max_ack_height_tracker_by_send_rate_) {}
176
EnableOverestimateAvoidance()177 void BandwidthSampler::EnableOverestimateAvoidance() {
178 if (overestimate_avoidance_) {
179 return;
180 }
181
182 overestimate_avoidance_ = true;
183 // TODO(wub): Change the default value of
184 // --quic_ack_aggregation_bandwidth_threshold to 2.0.
185 max_ack_height_tracker_.SetAckAggregationBandwidthThreshold(2.0);
186 }
187
~BandwidthSampler()188 BandwidthSampler::~BandwidthSampler() {}
189
OnPacketSent(QuicTime sent_time,QuicPacketNumber packet_number,QuicByteCount bytes,QuicByteCount bytes_in_flight,HasRetransmittableData has_retransmittable_data)190 void BandwidthSampler::OnPacketSent(
191 QuicTime sent_time, QuicPacketNumber packet_number, QuicByteCount bytes,
192 QuicByteCount bytes_in_flight,
193 HasRetransmittableData has_retransmittable_data) {
194 last_sent_packet_ = packet_number;
195
196 if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
197 return;
198 }
199
200 total_bytes_sent_ += bytes;
201
202 // If there are no packets in flight, the time at which the new transmission
203 // opens can be treated as the A_0 point for the purpose of bandwidth
204 // sampling. This underestimates bandwidth to some extent, and produces some
205 // artificially low samples for most packets in flight, but it provides with
206 // samples at important points where we would not have them otherwise, most
207 // importantly at the beginning of the connection.
208 if (bytes_in_flight == 0) {
209 last_acked_packet_ack_time_ = sent_time;
210 if (overestimate_avoidance_) {
211 recent_ack_points_.Clear();
212 recent_ack_points_.Update(sent_time, total_bytes_acked_);
213 a0_candidates_.clear();
214 a0_candidates_.push_back(recent_ack_points_.MostRecentPoint());
215 }
216 total_bytes_sent_at_last_acked_packet_ = total_bytes_sent_;
217
218 // In this situation ack compression is not a concern, set send rate to
219 // effectively infinite.
220 last_acked_packet_sent_time_ = sent_time;
221 }
222
223 if (!connection_state_map_.IsEmpty() &&
224 packet_number >
225 connection_state_map_.last_packet() + max_tracked_packets_) {
226 if (unacked_packet_map_ != nullptr && !unacked_packet_map_->empty()) {
227 QuicPacketNumber maybe_least_unacked =
228 unacked_packet_map_->GetLeastUnacked();
229 QUIC_BUG(quic_bug_10437_1)
230 << "BandwidthSampler in-flight packet map has exceeded maximum "
231 "number of tracked packets("
232 << max_tracked_packets_
233 << "). First tracked: " << connection_state_map_.first_packet()
234 << "; last tracked: " << connection_state_map_.last_packet()
235 << "; entry_slots_used: " << connection_state_map_.entry_slots_used()
236 << "; number_of_present_entries: "
237 << connection_state_map_.number_of_present_entries()
238 << "; packet number: " << packet_number
239 << "; unacked_map: " << unacked_packet_map_->DebugString()
240 << "; total_bytes_sent: " << total_bytes_sent_
241 << "; total_bytes_acked: " << total_bytes_acked_
242 << "; total_bytes_lost: " << total_bytes_lost_
243 << "; total_bytes_neutered: " << total_bytes_neutered_
244 << "; last_acked_packet_sent_time: " << last_acked_packet_sent_time_
245 << "; total_bytes_sent_at_last_acked_packet: "
246 << total_bytes_sent_at_last_acked_packet_
247 << "; least_unacked_packet_info: "
248 << (unacked_packet_map_->IsUnacked(maybe_least_unacked)
249 ? unacked_packet_map_
250 ->GetTransmissionInfo(maybe_least_unacked)
251 .DebugString()
252 : "n/a");
253 } else {
254 QUIC_BUG(quic_bug_10437_2)
255 << "BandwidthSampler in-flight packet map has exceeded maximum "
256 "number of tracked packets.";
257 }
258 }
259
260 bool success = connection_state_map_.Emplace(packet_number, sent_time, bytes,
261 bytes_in_flight + bytes, *this);
262 QUIC_BUG_IF(quic_bug_10437_3, !success)
263 << "BandwidthSampler failed to insert the packet "
264 "into the map, most likely because it's already "
265 "in it.";
266 }
267
OnPacketNeutered(QuicPacketNumber packet_number)268 void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
269 connection_state_map_.Remove(
270 packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
271 QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
272 total_bytes_neutered_ += sent_packet.size();
273 });
274 }
275
276 BandwidthSamplerInterface::CongestionEventSample
OnCongestionEvent(QuicTime ack_time,const AckedPacketVector & acked_packets,const LostPacketVector & lost_packets,QuicBandwidth max_bandwidth,QuicBandwidth est_bandwidth_upper_bound,QuicRoundTripCount round_trip_count)277 BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
278 const AckedPacketVector& acked_packets,
279 const LostPacketVector& lost_packets,
280 QuicBandwidth max_bandwidth,
281 QuicBandwidth est_bandwidth_upper_bound,
282 QuicRoundTripCount round_trip_count) {
283 CongestionEventSample event_sample;
284
285 SendTimeState last_lost_packet_send_state;
286
287 for (const LostPacket& packet : lost_packets) {
288 SendTimeState send_state =
289 OnPacketLost(packet.packet_number, packet.bytes_lost);
290 if (send_state.is_valid) {
291 last_lost_packet_send_state = send_state;
292 }
293 }
294
295 if (acked_packets.empty()) {
296 // Only populate send state for a loss-only event.
297 event_sample.last_packet_send_state = last_lost_packet_send_state;
298 return event_sample;
299 }
300
301 SendTimeState last_acked_packet_send_state;
302 QuicBandwidth max_send_rate = QuicBandwidth::Zero();
303 for (const auto& packet : acked_packets) {
304 if (packet.spurious_loss) {
305 // If the packet has been detected as lost before, QuicSentPacketManager
306 // should set the AckedPacket.bytes_acked to 0 before passing the packet
307 // to the congestion controller.
308 QUICHE_DCHECK_EQ(packet.bytes_acked, 0);
309 continue;
310 }
311 BandwidthSample sample =
312 OnPacketAcknowledged(ack_time, packet.packet_number);
313 if (!sample.state_at_send.is_valid) {
314 continue;
315 }
316
317 last_acked_packet_send_state = sample.state_at_send;
318
319 if (!sample.rtt.IsZero()) {
320 event_sample.sample_rtt = std::min(event_sample.sample_rtt, sample.rtt);
321 }
322 if (sample.bandwidth > event_sample.sample_max_bandwidth) {
323 event_sample.sample_max_bandwidth = sample.bandwidth;
324 event_sample.sample_is_app_limited = sample.state_at_send.is_app_limited;
325 }
326 if (!sample.send_rate.IsInfinite()) {
327 max_send_rate = std::max(max_send_rate, sample.send_rate);
328 }
329 const QuicByteCount inflight_sample =
330 total_bytes_acked() - last_acked_packet_send_state.total_bytes_acked;
331 if (inflight_sample > event_sample.sample_max_inflight) {
332 event_sample.sample_max_inflight = inflight_sample;
333 }
334 }
335
336 if (!last_lost_packet_send_state.is_valid) {
337 event_sample.last_packet_send_state = last_acked_packet_send_state;
338 } else if (!last_acked_packet_send_state.is_valid) {
339 event_sample.last_packet_send_state = last_lost_packet_send_state;
340 } else {
341 // If two packets are inflight and an alarm is armed to lose a packet and it
342 // wakes up late, then the first of two in flight packets could have been
343 // acknowledged before the wakeup, which re-evaluates loss detection, and
344 // could declare the later of the two lost.
345 event_sample.last_packet_send_state =
346 lost_packets.back().packet_number > acked_packets.back().packet_number
347 ? last_lost_packet_send_state
348 : last_acked_packet_send_state;
349 }
350
351 bool is_new_max_bandwidth = event_sample.sample_max_bandwidth > max_bandwidth;
352 max_bandwidth = std::max(max_bandwidth, event_sample.sample_max_bandwidth);
353 if (limit_max_ack_height_tracker_by_send_rate_) {
354 max_bandwidth = std::max(max_bandwidth, max_send_rate);
355 }
356 // TODO(ianswett): Why is the min being passed in here?
357 event_sample.extra_acked =
358 OnAckEventEnd(std::min(est_bandwidth_upper_bound, max_bandwidth),
359 is_new_max_bandwidth, round_trip_count);
360
361 return event_sample;
362 }
363
OnAckEventEnd(QuicBandwidth bandwidth_estimate,bool is_new_max_bandwidth,QuicRoundTripCount round_trip_count)364 QuicByteCount BandwidthSampler::OnAckEventEnd(
365 QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
366 QuicRoundTripCount round_trip_count) {
367 const QuicByteCount newly_acked_bytes =
368 total_bytes_acked_ - total_bytes_acked_after_last_ack_event_;
369
370 if (newly_acked_bytes == 0) {
371 return 0;
372 }
373 total_bytes_acked_after_last_ack_event_ = total_bytes_acked_;
374 QuicByteCount extra_acked = max_ack_height_tracker_.Update(
375 bandwidth_estimate, is_new_max_bandwidth, round_trip_count,
376 last_sent_packet_, last_acked_packet_, last_acked_packet_ack_time_,
377 newly_acked_bytes);
378 // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack
379 // aggregation epoch, save LessRecentPoint, which is the last ack point of the
380 // previous epoch, as a A0 candidate.
381 if (overestimate_avoidance_ && extra_acked == 0) {
382 a0_candidates_.push_back(recent_ack_points_.LessRecentPoint());
383 QUIC_DVLOG(1) << "New a0_candidate:" << a0_candidates_.back();
384 }
385 return extra_acked;
386 }
387
OnPacketAcknowledged(QuicTime ack_time,QuicPacketNumber packet_number)388 BandwidthSample BandwidthSampler::OnPacketAcknowledged(
389 QuicTime ack_time, QuicPacketNumber packet_number) {
390 last_acked_packet_ = packet_number;
391 ConnectionStateOnSentPacket* sent_packet_pointer =
392 connection_state_map_.GetEntry(packet_number);
393 if (sent_packet_pointer == nullptr) {
394 // See the TODO below.
395 return BandwidthSample();
396 }
397 BandwidthSample sample =
398 OnPacketAcknowledgedInner(ack_time, packet_number, *sent_packet_pointer);
399 return sample;
400 }
401
OnPacketAcknowledgedInner(QuicTime ack_time,QuicPacketNumber packet_number,const ConnectionStateOnSentPacket & sent_packet)402 BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
403 QuicTime ack_time, QuicPacketNumber packet_number,
404 const ConnectionStateOnSentPacket& sent_packet) {
405 total_bytes_acked_ += sent_packet.size();
406 total_bytes_sent_at_last_acked_packet_ =
407 sent_packet.send_time_state().total_bytes_sent;
408 last_acked_packet_sent_time_ = sent_packet.sent_time();
409 last_acked_packet_ack_time_ = ack_time;
410 if (overestimate_avoidance_) {
411 recent_ack_points_.Update(ack_time, total_bytes_acked_);
412 }
413
414 if (is_app_limited_) {
415 // Exit app-limited phase in two cases:
416 // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
417 // packets are sent while there are buffered packets or pending data.
418 // (2) The current acked packet is after the sent packet marked as the end
419 // of the app limit phase.
420 if (!end_of_app_limited_phase_.IsInitialized() ||
421 packet_number > end_of_app_limited_phase_) {
422 is_app_limited_ = false;
423 }
424 }
425
426 // There might have been no packets acknowledged at the moment when the
427 // current packet was sent. In that case, there is no bandwidth sample to
428 // make.
429 if (sent_packet.last_acked_packet_sent_time() == QuicTime::Zero()) {
430 QUIC_BUG(quic_bug_10437_4)
431 << "sent_packet.last_acked_packet_sent_time is zero";
432 return BandwidthSample();
433 }
434
435 // Infinite rate indicates that the sampler is supposed to discard the
436 // current send rate sample and use only the ack rate.
437 QuicBandwidth send_rate = QuicBandwidth::Infinite();
438 if (sent_packet.sent_time() > sent_packet.last_acked_packet_sent_time()) {
439 send_rate = QuicBandwidth::FromBytesAndTimeDelta(
440 sent_packet.send_time_state().total_bytes_sent -
441 sent_packet.total_bytes_sent_at_last_acked_packet(),
442 sent_packet.sent_time() - sent_packet.last_acked_packet_sent_time());
443 }
444
445 AckPoint a0;
446 if (overestimate_avoidance_ &&
447 ChooseA0Point(sent_packet.send_time_state().total_bytes_acked, &a0)) {
448 QUIC_DVLOG(2) << "Using a0 point: " << a0;
449 } else {
450 a0.ack_time = sent_packet.last_acked_packet_ack_time(),
451 a0.total_bytes_acked = sent_packet.send_time_state().total_bytes_acked;
452 }
453
454 // During the slope calculation, ensure that ack time of the current packet is
455 // always larger than the time of the previous packet, otherwise division by
456 // zero or integer underflow can occur.
457 if (ack_time <= a0.ack_time) {
458 // TODO(wub): Compare this code count before and after fixing clock jitter
459 // issue.
460 if (a0.ack_time == sent_packet.sent_time()) {
461 // This is the 1st packet after quiescense.
462 QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 1, 2);
463 } else {
464 QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 2, 2);
465 }
466 QUIC_LOG_EVERY_N_SEC(ERROR, 60)
467 << "Time of the previously acked packet:"
468 << a0.ack_time.ToDebuggingValue()
469 << " is larger than the ack time of the current packet:"
470 << ack_time.ToDebuggingValue()
471 << ". acked packet number:" << packet_number
472 << ", total_bytes_acked_:" << total_bytes_acked_
473 << ", overestimate_avoidance_:" << overestimate_avoidance_
474 << ", sent_packet:" << sent_packet;
475 return BandwidthSample();
476 }
477 QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
478 total_bytes_acked_ - a0.total_bytes_acked, ack_time - a0.ack_time);
479
480 BandwidthSample sample;
481 sample.bandwidth = std::min(send_rate, ack_rate);
482 // Note: this sample does not account for delayed acknowledgement time. This
483 // means that the RTT measurements here can be artificially high, especially
484 // on low bandwidth connections.
485 sample.rtt = ack_time - sent_packet.sent_time();
486 sample.send_rate = send_rate;
487 SentPacketToSendTimeState(sent_packet, &sample.state_at_send);
488
489 if (sample.bandwidth.IsZero()) {
490 QUIC_LOG_EVERY_N_SEC(ERROR, 60)
491 << "ack_rate: " << ack_rate << ", send_rate: " << send_rate
492 << ". acked packet number:" << packet_number
493 << ", overestimate_avoidance_:" << overestimate_avoidance_ << "a1:{"
494 << total_bytes_acked_ << "@" << ack_time << "}, a0:{"
495 << a0.total_bytes_acked << "@" << a0.ack_time
496 << "}, sent_packet:" << sent_packet;
497 }
498 return sample;
499 }
500
ChooseA0Point(QuicByteCount total_bytes_acked,AckPoint * a0)501 bool BandwidthSampler::ChooseA0Point(QuicByteCount total_bytes_acked,
502 AckPoint* a0) {
503 if (a0_candidates_.empty()) {
504 QUIC_BUG(quic_bug_10437_5)
505 << "No A0 point candicates. total_bytes_acked:" << total_bytes_acked;
506 return false;
507 }
508
509 if (a0_candidates_.size() == 1) {
510 *a0 = a0_candidates_.front();
511 return true;
512 }
513
514 for (size_t i = 1; i < a0_candidates_.size(); ++i) {
515 if (a0_candidates_[i].total_bytes_acked > total_bytes_acked) {
516 *a0 = a0_candidates_[i - 1];
517 if (i > 1) {
518 a0_candidates_.pop_front_n(i - 1);
519 }
520 return true;
521 }
522 }
523
524 // All candidates' total_bytes_acked is <= |total_bytes_acked|.
525 *a0 = a0_candidates_.back();
526 a0_candidates_.pop_front_n(a0_candidates_.size() - 1);
527 return true;
528 }
529
OnPacketLost(QuicPacketNumber packet_number,QuicPacketLength bytes_lost)530 SendTimeState BandwidthSampler::OnPacketLost(QuicPacketNumber packet_number,
531 QuicPacketLength bytes_lost) {
532 // TODO(vasilvv): see the comment for the case of missing packets in
533 // BandwidthSampler::OnPacketAcknowledged on why this does not raise a
534 // QUIC_BUG when removal fails.
535 SendTimeState send_time_state;
536
537 total_bytes_lost_ += bytes_lost;
538 ConnectionStateOnSentPacket* sent_packet_pointer =
539 connection_state_map_.GetEntry(packet_number);
540 if (sent_packet_pointer != nullptr) {
541 SentPacketToSendTimeState(*sent_packet_pointer, &send_time_state);
542 }
543
544 return send_time_state;
545 }
546
SentPacketToSendTimeState(const ConnectionStateOnSentPacket & sent_packet,SendTimeState * send_time_state) const547 void BandwidthSampler::SentPacketToSendTimeState(
548 const ConnectionStateOnSentPacket& sent_packet,
549 SendTimeState* send_time_state) const {
550 *send_time_state = sent_packet.send_time_state();
551 send_time_state->is_valid = true;
552 }
553
OnAppLimited()554 void BandwidthSampler::OnAppLimited() {
555 is_app_limited_ = true;
556 end_of_app_limited_phase_ = last_sent_packet_;
557 }
558
RemoveObsoletePackets(QuicPacketNumber least_unacked)559 void BandwidthSampler::RemoveObsoletePackets(QuicPacketNumber least_unacked) {
560 // A packet can become obsolete when it is removed from QuicUnackedPacketMap's
561 // view of inflight before it is acked or marked as lost. For example, when
562 // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet,
563 // the packet is removed from QuicUnackedPacketMap's inflight, but is not
564 // marked as acked or lost in the BandwidthSampler.
565 connection_state_map_.RemoveUpTo(least_unacked);
566 }
567
total_bytes_sent() const568 QuicByteCount BandwidthSampler::total_bytes_sent() const {
569 return total_bytes_sent_;
570 }
571
total_bytes_acked() const572 QuicByteCount BandwidthSampler::total_bytes_acked() const {
573 return total_bytes_acked_;
574 }
575
total_bytes_lost() const576 QuicByteCount BandwidthSampler::total_bytes_lost() const {
577 return total_bytes_lost_;
578 }
579
total_bytes_neutered() const580 QuicByteCount BandwidthSampler::total_bytes_neutered() const {
581 return total_bytes_neutered_;
582 }
583
is_app_limited() const584 bool BandwidthSampler::is_app_limited() const { return is_app_limited_; }
585
end_of_app_limited_phase() const586 QuicPacketNumber BandwidthSampler::end_of_app_limited_phase() const {
587 return end_of_app_limited_phase_;
588 }
589
590 } // namespace quic
591