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