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 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_ 6 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_ 7 8 #include "quiche/quic/core/congestion_control/send_algorithm_interface.h" 9 #include "quiche/quic/core/congestion_control/windowed_filter.h" 10 #include "quiche/quic/core/packet_number_indexed_queue.h" 11 #include "quiche/quic/core/quic_bandwidth.h" 12 #include "quiche/quic/core/quic_packet_number.h" 13 #include "quiche/quic/core/quic_packets.h" 14 #include "quiche/quic/core/quic_time.h" 15 #include "quiche/quic/core/quic_types.h" 16 #include "quiche/quic/core/quic_unacked_packet_map.h" 17 #include "quiche/quic/platform/api/quic_export.h" 18 #include "quiche/quic/platform/api/quic_flags.h" 19 #include "quiche/common/quiche_circular_deque.h" 20 21 namespace quic { 22 23 namespace test { 24 class BandwidthSamplerPeer; 25 } // namespace test 26 27 // A subset of BandwidthSampler::ConnectionStateOnSentPacket which is returned 28 // to the caller when the packet is acked or lost. 29 struct QUICHE_EXPORT SendTimeState { SendTimeStateSendTimeState30 SendTimeState() 31 : is_valid(false), 32 is_app_limited(false), 33 total_bytes_sent(0), 34 total_bytes_acked(0), 35 total_bytes_lost(0), 36 bytes_in_flight(0) {} 37 SendTimeStateSendTimeState38 SendTimeState(bool is_app_limited, QuicByteCount total_bytes_sent, 39 QuicByteCount total_bytes_acked, QuicByteCount total_bytes_lost, 40 QuicByteCount bytes_in_flight) 41 : is_valid(true), 42 is_app_limited(is_app_limited), 43 total_bytes_sent(total_bytes_sent), 44 total_bytes_acked(total_bytes_acked), 45 total_bytes_lost(total_bytes_lost), 46 bytes_in_flight(bytes_in_flight) {} 47 48 SendTimeState(const SendTimeState& other) = default; 49 SendTimeState& operator=(const SendTimeState& other) = default; 50 51 friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os, 52 const SendTimeState& s); 53 54 // Whether other states in this object is valid. 55 bool is_valid; 56 57 // Whether the sender is app limited at the time the packet was sent. 58 // App limited bandwidth sample might be artificially low because the sender 59 // did not have enough data to send in order to saturate the link. 60 bool is_app_limited; 61 62 // Total number of sent bytes at the time the packet was sent. 63 // Includes the packet itself. 64 QuicByteCount total_bytes_sent; 65 66 // Total number of acked bytes at the time the packet was sent. 67 QuicByteCount total_bytes_acked; 68 69 // Total number of lost bytes at the time the packet was sent. 70 QuicByteCount total_bytes_lost; 71 72 // Total number of inflight bytes at the time the packet was sent. 73 // Includes the packet itself. 74 // It should be equal to |total_bytes_sent| minus the sum of 75 // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes. 76 QuicByteCount bytes_in_flight; 77 }; 78 79 struct QUICHE_EXPORT ExtraAckedEvent { 80 // The excess bytes acknowlwedged in the time delta for this event. 81 QuicByteCount extra_acked = 0; 82 83 // The bytes acknowledged and time delta from the event. 84 QuicByteCount bytes_acked = 0; 85 QuicTime::Delta time_delta = QuicTime::Delta::Zero(); 86 // The round trip of the event. 87 QuicRoundTripCount round = 0; 88 89 bool operator>=(const ExtraAckedEvent& other) const { 90 return extra_acked >= other.extra_acked; 91 } 92 bool operator==(const ExtraAckedEvent& other) const { 93 return extra_acked == other.extra_acked; 94 } 95 }; 96 97 struct QUICHE_EXPORT BandwidthSample { 98 // The bandwidth at that particular sample. Zero if no valid bandwidth sample 99 // is available. 100 QuicBandwidth bandwidth = QuicBandwidth::Zero(); 101 102 // The RTT measurement at this particular sample. Zero if no RTT sample is 103 // available. Does not correct for delayed ack time. 104 QuicTime::Delta rtt = QuicTime::Delta::Zero(); 105 106 // |send_rate| is computed from the current packet being acked('P') and an 107 // earlier packet that is acked before P was sent. 108 QuicBandwidth send_rate = QuicBandwidth::Infinite(); 109 110 // States captured when the packet was sent. 111 SendTimeState state_at_send; 112 }; 113 114 // MaxAckHeightTracker is part of the BandwidthSampler. It is called after every 115 // ack event to keep track the degree of ack aggregation(a.k.a "ack height"). 116 class QUICHE_EXPORT MaxAckHeightTracker { 117 public: MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)118 explicit MaxAckHeightTracker(QuicRoundTripCount initial_filter_window) 119 : max_ack_height_filter_(initial_filter_window, ExtraAckedEvent(), 0) {} 120 Get()121 QuicByteCount Get() const { 122 return max_ack_height_filter_.GetBest().extra_acked; 123 } 124 125 QuicByteCount Update(QuicBandwidth bandwidth_estimate, 126 bool is_new_max_bandwidth, 127 QuicRoundTripCount round_trip_count, 128 QuicPacketNumber last_sent_packet_number, 129 QuicPacketNumber last_acked_packet_number, 130 QuicTime ack_time, QuicByteCount bytes_acked); 131 SetFilterWindowLength(QuicRoundTripCount length)132 void SetFilterWindowLength(QuicRoundTripCount length) { 133 max_ack_height_filter_.SetWindowLength(length); 134 } 135 Reset(QuicByteCount new_height,QuicRoundTripCount new_time)136 void Reset(QuicByteCount new_height, QuicRoundTripCount new_time) { 137 ExtraAckedEvent new_event; 138 new_event.extra_acked = new_height; 139 new_event.round = new_time; 140 max_ack_height_filter_.Reset(new_event, new_time); 141 } 142 SetAckAggregationBandwidthThreshold(double threshold)143 void SetAckAggregationBandwidthThreshold(double threshold) { 144 ack_aggregation_bandwidth_threshold_ = threshold; 145 } 146 SetStartNewAggregationEpochAfterFullRound(bool value)147 void SetStartNewAggregationEpochAfterFullRound(bool value) { 148 start_new_aggregation_epoch_after_full_round_ = value; 149 } 150 SetReduceExtraAckedOnBandwidthIncrease(bool value)151 void SetReduceExtraAckedOnBandwidthIncrease(bool value) { 152 reduce_extra_acked_on_bandwidth_increase_ = value; 153 } 154 ack_aggregation_bandwidth_threshold()155 double ack_aggregation_bandwidth_threshold() const { 156 return ack_aggregation_bandwidth_threshold_; 157 } 158 num_ack_aggregation_epochs()159 uint64_t num_ack_aggregation_epochs() const { 160 return num_ack_aggregation_epochs_; 161 } 162 163 private: 164 // Tracks the maximum number of bytes acked faster than the estimated 165 // bandwidth. 166 using MaxAckHeightFilter = 167 WindowedFilter<ExtraAckedEvent, MaxFilter<ExtraAckedEvent>, 168 QuicRoundTripCount, QuicRoundTripCount>; 169 MaxAckHeightFilter max_ack_height_filter_; 170 171 // The time this aggregation started and the number of bytes acked during it. 172 QuicTime aggregation_epoch_start_time_ = QuicTime::Zero(); 173 QuicByteCount aggregation_epoch_bytes_ = 0; 174 // The last sent packet number before the current aggregation epoch started. 175 QuicPacketNumber last_sent_packet_number_before_epoch_; 176 // The number of ack aggregation epochs ever started, including the ongoing 177 // one. Stats only. 178 uint64_t num_ack_aggregation_epochs_ = 0; 179 double ack_aggregation_bandwidth_threshold_ = 180 GetQuicFlag(quic_ack_aggregation_bandwidth_threshold); 181 bool start_new_aggregation_epoch_after_full_round_ = false; 182 bool reduce_extra_acked_on_bandwidth_increase_ = false; 183 }; 184 185 // An interface common to any class that can provide bandwidth samples from the 186 // information per individual acknowledged packet. 187 class QUICHE_EXPORT BandwidthSamplerInterface { 188 public: ~BandwidthSamplerInterface()189 virtual ~BandwidthSamplerInterface() {} 190 191 // Inputs the sent packet information into the sampler. Assumes that all 192 // packets are sent in order. The information about the packet will not be 193 // released from the sampler until it the packet is either acknowledged or 194 // declared lost. 195 virtual void OnPacketSent( 196 QuicTime sent_time, QuicPacketNumber packet_number, QuicByteCount bytes, 197 QuicByteCount bytes_in_flight, 198 HasRetransmittableData has_retransmittable_data) = 0; 199 200 virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0; 201 202 struct QUICHE_EXPORT CongestionEventSample { 203 // The maximum bandwidth sample from all acked packets. 204 // QuicBandwidth::Zero() if no samples are available. 205 QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero(); 206 // Whether |sample_max_bandwidth| is from a app-limited sample. 207 bool sample_is_app_limited = false; 208 // The minimum rtt sample from all acked packets. 209 // QuicTime::Delta::Infinite() if no samples are available. 210 QuicTime::Delta sample_rtt = QuicTime::Delta::Infinite(); 211 // For each packet p in acked packets, this is the max value of INFLIGHT(p), 212 // where INFLIGHT(p) is the number of bytes acked while p is inflight. 213 QuicByteCount sample_max_inflight = 0; 214 // The send state of the largest packet in acked_packets, unless it is 215 // empty. If acked_packets is empty, it's the send state of the largest 216 // packet in lost_packets. 217 SendTimeState last_packet_send_state; 218 // The number of extra bytes acked from this ack event, compared to what is 219 // expected from the flow's bandwidth. Larger value means more ack 220 // aggregation. 221 QuicByteCount extra_acked = 0; 222 }; 223 // Notifies the sampler that at |ack_time|, all packets in |acked_packets| 224 // have been acked, and all packets in |lost_packets| have been lost. 225 // See the comments in CongestionEventSample for the return value. 226 // |max_bandwidth| is the windowed maximum observed bandwidth. 227 // |est_bandwidth_upper_bound| is an upper bound of estimated bandwidth used 228 // to calculate extra_acked. 229 virtual CongestionEventSample OnCongestionEvent( 230 QuicTime ack_time, const AckedPacketVector& acked_packets, 231 const LostPacketVector& lost_packets, QuicBandwidth max_bandwidth, 232 QuicBandwidth est_bandwidth_upper_bound, 233 QuicRoundTripCount round_trip_count) = 0; 234 235 // Informs the sampler that the connection is currently app-limited, causing 236 // the sampler to enter the app-limited phase. The phase will expire by 237 // itself. 238 virtual void OnAppLimited() = 0; 239 240 // Remove all the packets lower than the specified packet number. 241 virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0; 242 243 // Total number of bytes sent/acked/lost/neutered in the connection. 244 virtual QuicByteCount total_bytes_sent() const = 0; 245 virtual QuicByteCount total_bytes_acked() const = 0; 246 virtual QuicByteCount total_bytes_lost() const = 0; 247 virtual QuicByteCount total_bytes_neutered() const = 0; 248 249 // Application-limited information exported for debugging. 250 virtual bool is_app_limited() const = 0; 251 252 virtual QuicPacketNumber end_of_app_limited_phase() const = 0; 253 }; 254 255 // BandwidthSampler keeps track of sent and acknowledged packets and outputs a 256 // bandwidth sample for every packet acknowledged. The samples are taken for 257 // individual packets, and are not filtered; the consumer has to filter the 258 // bandwidth samples itself. In certain cases, the sampler will locally severely 259 // underestimate the bandwidth, hence a maximum filter with a size of at least 260 // one RTT is recommended. 261 // 262 // This class bases its samples on the slope of two curves: the number of bytes 263 // sent over time, and the number of bytes acknowledged as received over time. 264 // It produces a sample of both slopes for every packet that gets acknowledged, 265 // based on a slope between two points on each of the corresponding curves. Note 266 // that due to the packet loss, the number of bytes on each curve might get 267 // further and further away from each other, meaning that it is not feasible to 268 // compare byte values coming from different curves with each other. 269 // 270 // The obvious points for measuring slope sample are the ones corresponding to 271 // the packet that was just acknowledged. Let us denote them as S_1 (point at 272 // which the current packet was sent) and A_1 (point at which the current packet 273 // was acknowledged). However, taking a slope requires two points on each line, 274 // so estimating bandwidth requires picking a packet in the past with respect to 275 // which the slope is measured. 276 // 277 // For that purpose, BandwidthSampler always keeps track of the most recently 278 // acknowledged packet, and records it together with every outgoing packet. 279 // When a packet gets acknowledged (A_1), it has not only information about when 280 // it itself was sent (S_1), but also the information about a previously 281 // acknowledged packet before it was sent (S_0 and A_0). 282 // 283 // Based on that data, send and ack rate are estimated as: 284 // send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0)) 285 // ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0)) 286 // 287 // Here, the ack rate is intuitively the rate we want to treat as bandwidth. 288 // However, in certain cases (e.g. ack compression) the ack rate at a point may 289 // end up higher than the rate at which the data was originally sent, which is 290 // not indicative of the real bandwidth. Hence, we use the send rate as an upper 291 // bound, and the sample value is 292 // rate_sample = min(send_rate, ack_rate) 293 // 294 // An important edge case handled by the sampler is tracking the app-limited 295 // samples. There are multiple meaning of "app-limited" used interchangeably, 296 // hence it is important to understand and to be able to distinguish between 297 // them. 298 // 299 // Meaning 1: connection state. The connection is said to be app-limited when 300 // there is no outstanding data to send. This means that certain bandwidth 301 // samples in the future would not be an accurate indication of the link 302 // capacity, and it is important to inform consumer about that. Whenever 303 // connection becomes app-limited, the sampler is notified via OnAppLimited() 304 // method. 305 // 306 // Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth 307 // sampler becomes notified about the connection being app-limited, it enters 308 // app-limited phase. In that phase, all *sent* packets are marked as 309 // app-limited. Note that the connection itself does not have to be 310 // app-limited during the app-limited phase, and in fact it will not be 311 // (otherwise how would it send packets?). The boolean flag below indicates 312 // whether the sampler is in that phase. 313 // 314 // Meaning 3: a flag on the sent packet and on the sample. If a sent packet is 315 // sent during the app-limited phase, the resulting sample related to the 316 // packet will be marked as app-limited. 317 // 318 // With the terminology issue out of the way, let us consider the question of 319 // what kind of situation it addresses. 320 // 321 // Consider a scenario where we first send packets 1 to 20 at a regular 322 // bandwidth, and then immediately run out of data. After a few seconds, we send 323 // packets 21 to 60, and only receive ack for 21 between sending packets 40 and 324 // 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0 325 // we use to compute the slope is going to be packet 20, a few seconds apart 326 // from the current packet, hence the resulting estimate would be extremely low 327 // and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21, 328 // meaning that the bandwidth sample would exclude the quiescence. 329 // 330 // Based on the analysis of that scenario, we implement the following rule: once 331 // OnAppLimited() is called, all sent packets will produce app-limited samples 332 // up until an ack for a packet that was sent after OnAppLimited() was called. 333 // Note that while the scenario above is not the only scenario when the 334 // connection is app-limited, the approach works in other cases too. 335 class QUICHE_EXPORT BandwidthSampler : public BandwidthSamplerInterface { 336 public: 337 BandwidthSampler(const QuicUnackedPacketMap* unacked_packet_map, 338 QuicRoundTripCount max_height_tracker_window_length); 339 340 // Copy states from |other|. This is useful when changing send algorithms in 341 // the middle of a connection. 342 BandwidthSampler(const BandwidthSampler& other); 343 ~BandwidthSampler() override; 344 345 void OnPacketSent(QuicTime sent_time, QuicPacketNumber packet_number, 346 QuicByteCount bytes, QuicByteCount bytes_in_flight, 347 HasRetransmittableData has_retransmittable_data) override; 348 void OnPacketNeutered(QuicPacketNumber packet_number) override; 349 350 CongestionEventSample OnCongestionEvent( 351 QuicTime ack_time, const AckedPacketVector& acked_packets, 352 const LostPacketVector& lost_packets, QuicBandwidth max_bandwidth, 353 QuicBandwidth est_bandwidth_upper_bound, 354 QuicRoundTripCount round_trip_count) override; 355 QuicByteCount OnAckEventEnd(QuicBandwidth bandwidth_estimate, 356 bool is_new_max_bandwidth, 357 QuicRoundTripCount round_trip_count); 358 359 void OnAppLimited() override; 360 361 void RemoveObsoletePackets(QuicPacketNumber least_unacked) override; 362 363 QuicByteCount total_bytes_sent() const override; 364 QuicByteCount total_bytes_acked() const override; 365 QuicByteCount total_bytes_lost() const override; 366 QuicByteCount total_bytes_neutered() const override; 367 368 bool is_app_limited() const override; 369 370 QuicPacketNumber end_of_app_limited_phase() const override; 371 max_ack_height()372 QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); } 373 num_ack_aggregation_epochs()374 uint64_t num_ack_aggregation_epochs() const { 375 return max_ack_height_tracker_.num_ack_aggregation_epochs(); 376 } 377 SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length)378 void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) { 379 max_ack_height_tracker_.SetFilterWindowLength(length); 380 } 381 ResetMaxAckHeightTracker(QuicByteCount new_height,QuicRoundTripCount new_time)382 void ResetMaxAckHeightTracker(QuicByteCount new_height, 383 QuicRoundTripCount new_time) { 384 max_ack_height_tracker_.Reset(new_height, new_time); 385 } 386 SetStartNewAggregationEpochAfterFullRound(bool value)387 void SetStartNewAggregationEpochAfterFullRound(bool value) { 388 max_ack_height_tracker_.SetStartNewAggregationEpochAfterFullRound(value); 389 } 390 SetLimitMaxAckHeightTrackerBySendRate(bool value)391 void SetLimitMaxAckHeightTrackerBySendRate(bool value) { 392 limit_max_ack_height_tracker_by_send_rate_ = value; 393 } 394 SetReduceExtraAckedOnBandwidthIncrease(bool value)395 void SetReduceExtraAckedOnBandwidthIncrease(bool value) { 396 max_ack_height_tracker_.SetReduceExtraAckedOnBandwidthIncrease(value); 397 } 398 399 // AckPoint represents a point on the ack line. 400 struct QUICHE_EXPORT AckPoint { 401 QuicTime ack_time = QuicTime::Zero(); 402 QuicByteCount total_bytes_acked = 0; 403 404 friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os, 405 const AckPoint& ack_point) { 406 return os << ack_point.ack_time << ":" << ack_point.total_bytes_acked; 407 } 408 }; 409 410 // RecentAckPoints maintains the most recent 2 ack points at distinct times. 411 class QUICHE_EXPORT RecentAckPoints { 412 public: Update(QuicTime ack_time,QuicByteCount total_bytes_acked)413 void Update(QuicTime ack_time, QuicByteCount total_bytes_acked) { 414 QUICHE_DCHECK_GE(total_bytes_acked, ack_points_[1].total_bytes_acked); 415 416 if (ack_time < ack_points_[1].ack_time) { 417 // This can only happen when time goes backwards, we use the smaller 418 // timestamp for the most recent ack point in that case. 419 // TODO(wub): Add a QUIC_BUG if ack time stops going backwards. 420 ack_points_[1].ack_time = ack_time; 421 } else if (ack_time > ack_points_[1].ack_time) { 422 ack_points_[0] = ack_points_[1]; 423 ack_points_[1].ack_time = ack_time; 424 } 425 426 ack_points_[1].total_bytes_acked = total_bytes_acked; 427 } 428 Clear()429 void Clear() { ack_points_[0] = ack_points_[1] = AckPoint(); } 430 MostRecentPoint()431 const AckPoint& MostRecentPoint() const { return ack_points_[1]; } 432 LessRecentPoint()433 const AckPoint& LessRecentPoint() const { 434 if (ack_points_[0].total_bytes_acked != 0) { 435 return ack_points_[0]; 436 } 437 438 return ack_points_[1]; 439 } 440 441 private: 442 AckPoint ack_points_[2]; 443 }; 444 445 void EnableOverestimateAvoidance(); IsOverestimateAvoidanceEnabled()446 bool IsOverestimateAvoidanceEnabled() const { 447 return overestimate_avoidance_; 448 } 449 450 private: 451 friend class test::BandwidthSamplerPeer; 452 453 // ConnectionStateOnSentPacket represents the information about a sent packet 454 // and the state of the connection at the moment the packet was sent, 455 // specifically the information about the most recently acknowledged packet at 456 // that moment. 457 class QUICHE_EXPORT ConnectionStateOnSentPacket { 458 public: 459 // Time at which the packet is sent. sent_time()460 QuicTime sent_time() const { return sent_time_; } 461 462 // Size of the packet. size()463 QuicByteCount size() const { return size_; } 464 465 // The value of |total_bytes_sent_at_last_acked_packet_| at the time the 466 // packet was sent. total_bytes_sent_at_last_acked_packet()467 QuicByteCount total_bytes_sent_at_last_acked_packet() const { 468 return total_bytes_sent_at_last_acked_packet_; 469 } 470 471 // The value of |last_acked_packet_sent_time_| at the time the packet was 472 // sent. last_acked_packet_sent_time()473 QuicTime last_acked_packet_sent_time() const { 474 return last_acked_packet_sent_time_; 475 } 476 477 // The value of |last_acked_packet_ack_time_| at the time the packet was 478 // sent. last_acked_packet_ack_time()479 QuicTime last_acked_packet_ack_time() const { 480 return last_acked_packet_ack_time_; 481 } 482 483 // Send time states that are returned to the congestion controller when the 484 // packet is acked or lost. send_time_state()485 const SendTimeState& send_time_state() const { return send_time_state_; } 486 487 // Snapshot constructor. Records the current state of the bandwidth 488 // sampler. 489 // |bytes_in_flight| is the bytes in flight right after the packet is sent. ConnectionStateOnSentPacket(QuicTime sent_time,QuicByteCount size,QuicByteCount bytes_in_flight,const BandwidthSampler & sampler)490 ConnectionStateOnSentPacket(QuicTime sent_time, QuicByteCount size, 491 QuicByteCount bytes_in_flight, 492 const BandwidthSampler& sampler) 493 : sent_time_(sent_time), 494 size_(size), 495 total_bytes_sent_at_last_acked_packet_( 496 sampler.total_bytes_sent_at_last_acked_packet_), 497 last_acked_packet_sent_time_(sampler.last_acked_packet_sent_time_), 498 last_acked_packet_ack_time_(sampler.last_acked_packet_ack_time_), 499 send_time_state_(sampler.is_app_limited_, sampler.total_bytes_sent_, 500 sampler.total_bytes_acked_, 501 sampler.total_bytes_lost_, bytes_in_flight) {} 502 503 // Default constructor. Required to put this structure into 504 // PacketNumberIndexedQueue. ConnectionStateOnSentPacket()505 ConnectionStateOnSentPacket() 506 : sent_time_(QuicTime::Zero()), 507 size_(0), 508 total_bytes_sent_at_last_acked_packet_(0), 509 last_acked_packet_sent_time_(QuicTime::Zero()), 510 last_acked_packet_ack_time_(QuicTime::Zero()) {} 511 512 friend QUICHE_EXPORT std::ostream& operator<<( 513 std::ostream& os, const ConnectionStateOnSentPacket& p) { 514 os << "{sent_time:" << p.sent_time() << ", size:" << p.size() 515 << ", total_bytes_sent_at_last_acked_packet:" 516 << p.total_bytes_sent_at_last_acked_packet() 517 << ", last_acked_packet_sent_time:" << p.last_acked_packet_sent_time() 518 << ", last_acked_packet_ack_time:" << p.last_acked_packet_ack_time() 519 << ", send_time_state:" << p.send_time_state() << "}"; 520 return os; 521 } 522 523 private: 524 QuicTime sent_time_; 525 QuicByteCount size_; 526 QuicByteCount total_bytes_sent_at_last_acked_packet_; 527 QuicTime last_acked_packet_sent_time_; 528 QuicTime last_acked_packet_ack_time_; 529 SendTimeState send_time_state_; 530 }; 531 532 BandwidthSample OnPacketAcknowledged(QuicTime ack_time, 533 QuicPacketNumber packet_number); 534 535 SendTimeState OnPacketLost(QuicPacketNumber packet_number, 536 QuicPacketLength bytes_lost); 537 538 // Copy a subset of the (private) ConnectionStateOnSentPacket to the (public) 539 // SendTimeState. Always set send_time_state->is_valid to true. 540 void SentPacketToSendTimeState(const ConnectionStateOnSentPacket& sent_packet, 541 SendTimeState* send_time_state) const; 542 543 // Choose the best a0 from |a0_candidates_| to calculate the ack rate. 544 // |total_bytes_acked| is the total bytes acked when the packet being acked is 545 // sent. The best a0 is chosen as follows: 546 // - If there's only one candidate, use it. 547 // - If there are multiple candidates, let a[n] be the nth candidate, and 548 // a[n-1].total_bytes_acked <= |total_bytes_acked| < a[n].total_bytes_acked, 549 // use a[n-1]. 550 // - If all candidates's total_bytes_acked is > |total_bytes_acked|, use a[0]. 551 // This may happen when acks are received out of order, and ack[n] caused 552 // some candidates of ack[n-x] to be removed. 553 // - If all candidates's total_bytes_acked is <= |total_bytes_acked|, use 554 // a[a.size()-1]. 555 bool ChooseA0Point(QuicByteCount total_bytes_acked, AckPoint* a0); 556 557 // The total number of congestion controlled bytes sent during the connection. 558 QuicByteCount total_bytes_sent_; 559 560 // The total number of congestion controlled bytes which were acknowledged. 561 QuicByteCount total_bytes_acked_; 562 563 // The total number of congestion controlled bytes which were lost. 564 QuicByteCount total_bytes_lost_; 565 566 // The total number of congestion controlled bytes which have been neutered. 567 QuicByteCount total_bytes_neutered_; 568 569 // The value of |total_bytes_sent_| at the time the last acknowledged packet 570 // was sent. Valid only when |last_acked_packet_sent_time_| is valid. 571 QuicByteCount total_bytes_sent_at_last_acked_packet_; 572 573 // The time at which the last acknowledged packet was sent. Set to 574 // QuicTime::Zero() if no valid timestamp is available. 575 QuicTime last_acked_packet_sent_time_; 576 577 // The time at which the most recent packet was acknowledged. 578 QuicTime last_acked_packet_ack_time_; 579 580 // The most recently sent packet. 581 QuicPacketNumber last_sent_packet_; 582 583 // The most recently acked packet. 584 QuicPacketNumber last_acked_packet_; 585 586 // Indicates whether the bandwidth sampler is currently in an app-limited 587 // phase. 588 bool is_app_limited_; 589 590 // The packet that will be acknowledged after this one will cause the sampler 591 // to exit the app-limited phase. 592 QuicPacketNumber end_of_app_limited_phase_; 593 594 // Record of the connection state at the point where each packet in flight was 595 // sent, indexed by the packet number. 596 PacketNumberIndexedQueue<ConnectionStateOnSentPacket> connection_state_map_; 597 598 RecentAckPoints recent_ack_points_; 599 quiche::QuicheCircularDeque<AckPoint> a0_candidates_; 600 601 // Maximum number of tracked packets. 602 const QuicPacketCount max_tracked_packets_; 603 604 // The main unacked packet map. Used for outputting extra debugging details. 605 // May be null. 606 // TODO(vasilvv): remove this once it's no longer useful for debugging. 607 const QuicUnackedPacketMap* unacked_packet_map_; 608 609 // Handles the actual bandwidth calculations, whereas the outer method handles 610 // retrieving and removing |sent_packet|. 611 BandwidthSample OnPacketAcknowledgedInner( 612 QuicTime ack_time, QuicPacketNumber packet_number, 613 const ConnectionStateOnSentPacket& sent_packet); 614 615 MaxAckHeightTracker max_ack_height_tracker_; 616 QuicByteCount total_bytes_acked_after_last_ack_event_; 617 618 // True if connection option 'BSAO' is set. 619 bool overestimate_avoidance_; 620 621 // True if connection option 'BBRB' is set. 622 bool limit_max_ack_height_tracker_by_send_rate_; 623 }; 624 625 } // namespace quic 626 627 #endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_ 628