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