xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/congestion_control/prr_sender.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2014 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/prr_sender.h"
6 
7 #include "quiche/quic/core/quic_packets.h"
8 
9 namespace quic {
10 
PrrSender()11 PrrSender::PrrSender()
12     : bytes_sent_since_loss_(0),
13       bytes_delivered_since_loss_(0),
14       ack_count_since_loss_(0),
15       bytes_in_flight_before_loss_(0) {}
16 
OnPacketSent(QuicByteCount sent_bytes)17 void PrrSender::OnPacketSent(QuicByteCount sent_bytes) {
18   bytes_sent_since_loss_ += sent_bytes;
19 }
20 
OnPacketLost(QuicByteCount prior_in_flight)21 void PrrSender::OnPacketLost(QuicByteCount prior_in_flight) {
22   bytes_sent_since_loss_ = 0;
23   bytes_in_flight_before_loss_ = prior_in_flight;
24   bytes_delivered_since_loss_ = 0;
25   ack_count_since_loss_ = 0;
26 }
27 
OnPacketAcked(QuicByteCount acked_bytes)28 void PrrSender::OnPacketAcked(QuicByteCount acked_bytes) {
29   bytes_delivered_since_loss_ += acked_bytes;
30   ++ack_count_since_loss_;
31 }
32 
CanSend(QuicByteCount congestion_window,QuicByteCount bytes_in_flight,QuicByteCount slowstart_threshold) const33 bool PrrSender::CanSend(QuicByteCount congestion_window,
34                         QuicByteCount bytes_in_flight,
35                         QuicByteCount slowstart_threshold) const {
36   // Return QuicTime::Zero in order to ensure limited transmit always works.
37   if (bytes_sent_since_loss_ == 0 || bytes_in_flight < kMaxSegmentSize) {
38     return true;
39   }
40   if (congestion_window > bytes_in_flight) {
41     // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
42     // of sending the entire available window. This prevents burst retransmits
43     // when more packets are lost than the CWND reduction.
44     //   limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
45     if (bytes_delivered_since_loss_ + ack_count_since_loss_ * kMaxSegmentSize <=
46         bytes_sent_since_loss_) {
47       return false;
48     }
49     return true;
50   }
51   // Implement Proportional Rate Reduction (RFC6937).
52   // Checks a simplified version of the PRR formula that doesn't use division:
53   // AvailableSendWindow =
54   //   CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent
55   if (bytes_delivered_since_loss_ * slowstart_threshold >
56       bytes_sent_since_loss_ * bytes_in_flight_before_loss_) {
57     return true;
58   }
59   return false;
60 }
61 
62 }  // namespace quic
63