1 // Copyright (c) 2012 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 // The pure virtual class for send side congestion control algorithm.
6 
7 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
8 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
9 
10 #include <algorithm>
11 #include <map>
12 #include <string>
13 
14 #include "quiche/quic/core/crypto/quic_random.h"
15 #include "quiche/quic/core/quic_bandwidth.h"
16 #include "quiche/quic/core/quic_clock.h"
17 #include "quiche/quic/core/quic_config.h"
18 #include "quiche/quic/core/quic_connection_stats.h"
19 #include "quiche/quic/core/quic_packets.h"
20 #include "quiche/quic/core/quic_time.h"
21 #include "quiche/quic/core/quic_types.h"
22 #include "quiche/quic/core/quic_unacked_packet_map.h"
23 #include "quiche/quic/platform/api/quic_export.h"
24 
25 namespace quic {
26 
27 using QuicRoundTripCount = uint64_t;
28 
29 class CachedNetworkParameters;
30 class RttStats;
31 
32 class QUICHE_EXPORT SendAlgorithmInterface {
33  public:
34   // Network Params for AdjustNetworkParameters.
35   struct QUICHE_EXPORT NetworkParams {
36     NetworkParams() = default;
NetworkParamsNetworkParams37     NetworkParams(const QuicBandwidth& bandwidth, const QuicTime::Delta& rtt,
38                   bool allow_cwnd_to_decrease)
39         : bandwidth(bandwidth),
40           rtt(rtt),
41           allow_cwnd_to_decrease(allow_cwnd_to_decrease) {}
42 
43     bool operator==(const NetworkParams& other) const {
44       return bandwidth == other.bandwidth && rtt == other.rtt &&
45              max_initial_congestion_window ==
46                  other.max_initial_congestion_window &&
47              allow_cwnd_to_decrease == other.allow_cwnd_to_decrease &&
48              is_rtt_trusted == other.is_rtt_trusted;
49     }
50 
51     QuicBandwidth bandwidth = QuicBandwidth::Zero();
52     QuicTime::Delta rtt = QuicTime::Delta::Zero();
53     int max_initial_congestion_window = 0;
54     bool allow_cwnd_to_decrease = false;
55     bool is_rtt_trusted = false;
56   };
57 
58   static SendAlgorithmInterface* Create(
59       const QuicClock* clock, const RttStats* rtt_stats,
60       const QuicUnackedPacketMap* unacked_packets, CongestionControlType type,
61       QuicRandom* random, QuicConnectionStats* stats,
62       QuicPacketCount initial_congestion_window,
63       SendAlgorithmInterface* old_send_algorithm);
64 
~SendAlgorithmInterface()65   virtual ~SendAlgorithmInterface() {}
66 
67   virtual void SetFromConfig(const QuicConfig& config,
68                              Perspective perspective) = 0;
69 
70   virtual void ApplyConnectionOptions(
71       const QuicTagVector& connection_options) = 0;
72 
73   // Sets the initial congestion window in number of packets.  May be ignored
74   // if called after the initial congestion window is no longer relevant.
75   virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0;
76 
77   // Indicates an update to the congestion state, caused either by an incoming
78   // ack or loss event timeout.  |rtt_updated| indicates whether a new
79   // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
80   // prior to the congestion event.  |acked_packets| and |lost_packets| are any
81   // packets considered acked or lost as a result of the congestion event.
82   // |num_ect| and |num_ce| indicate the number of newly acknowledged packets
83   // for which the receiver reported the Explicit Congestion Notification (ECN)
84   // bits were set to ECT(1) or CE, respectively. A sender will not use ECT(0).
85   // If QUIC determines the peer's feedback is invalid, it will send zero in
86   // these fields.
87   virtual void OnCongestionEvent(bool rtt_updated,
88                                  QuicByteCount prior_in_flight,
89                                  QuicTime event_time,
90                                  const AckedPacketVector& acked_packets,
91                                  const LostPacketVector& lost_packets,
92                                  QuicPacketCount num_ect,
93                                  QuicPacketCount num_ce) = 0;
94 
95   // Inform that we sent |bytes| to the wire, and if the packet is
96   // retransmittable.  |bytes_in_flight| is the number of bytes in flight before
97   // the packet was sent.
98   // Note: this function must be called for every packet sent to the wire.
99   virtual void OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight,
100                             QuicPacketNumber packet_number, QuicByteCount bytes,
101                             HasRetransmittableData is_retransmittable) = 0;
102 
103   // Inform that |packet_number| has been neutered.
104   virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
105 
106   // Called when the retransmission timeout fires.  Neither OnPacketAbandoned
107   // nor OnPacketLost will be called for these packets.
108   virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
109 
110   // Called when connection migrates and cwnd needs to be reset.
111   virtual void OnConnectionMigration() = 0;
112 
113   // Make decision on whether the sender can send right now.  Note that even
114   // when this method returns true, the sending can be delayed due to pacing.
115   virtual bool CanSend(QuicByteCount bytes_in_flight) = 0;
116 
117   // The pacing rate of the send algorithm.  May be zero if the rate is unknown.
118   virtual QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const = 0;
119 
120   // What's the current estimated bandwidth in bytes per second.
121   // Returns 0 when it does not have an estimate.
122   virtual QuicBandwidth BandwidthEstimate() const = 0;
123 
124   // Whether BandwidthEstimate returns a good measurement for resumption.
125   virtual bool HasGoodBandwidthEstimateForResumption() const = 0;
126 
127   // Returns the size of the current congestion window in bytes.  Note, this is
128   // not the *available* window.  Some send algorithms may not use a congestion
129   // window and will return 0.
130   virtual QuicByteCount GetCongestionWindow() const = 0;
131 
132   // Whether the send algorithm is currently in slow start.  When true, the
133   // BandwidthEstimate is expected to be too low.
134   virtual bool InSlowStart() const = 0;
135 
136   // Whether the send algorithm is currently in recovery.
137   virtual bool InRecovery() const = 0;
138 
139   // Returns the size of the slow start congestion window in bytes,
140   // aka ssthresh.  Only defined for Cubic and Reno, other algorithms return 0.
141   virtual QuicByteCount GetSlowStartThreshold() const = 0;
142 
143   virtual CongestionControlType GetCongestionControlType() const = 0;
144 
145   // Notifies the congestion control algorithm of an external network
146   // measurement or prediction.  Either |bandwidth| or |rtt| may be zero if no
147   // sample is available.
148   virtual void AdjustNetworkParameters(const NetworkParams& params) = 0;
149 
150   // Retrieves debugging information about the current state of the
151   // send algorithm.
152   virtual std::string GetDebugState() const = 0;
153 
154   // Called when the connection has no outstanding data to send. Specifically,
155   // this means that none of the data streams are write-blocked, there are no
156   // packets in the connection queue, and there are no pending retransmissins,
157   // i.e. the sender cannot send anything for reasons other than being blocked
158   // by congestion controller. This includes cases when the connection is
159   // blocked by the flow controller.
160   //
161   // The fact that this method is called does not necessarily imply that the
162   // connection would not be blocked by the congestion control if it actually
163   // tried to send data. If the congestion control algorithm needs to exclude
164   // such cases, it should use the internal state it uses for congestion control
165   // for that.
166   virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0;
167 
168   // Called before connection close to collect stats.
169   virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
170 
171   // Causes this send algorithm to respond to Congestion Experienced (CE)
172   // indications in accordance with RFC3168 [ECT(0)] or RFC9331 [ECT(1)] and
173   // returns true, if this mode is supported. Otherwise, returns false. Once an
174   // ECN mode is enabled, it is an error to call either of these methods.
175   virtual bool EnableECT0() = 0;
176   virtual bool EnableECT1() = 0;
177 };
178 
179 }  // namespace quic
180 
181 #endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
182