1 // Copyright (c) 2015 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 // TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic. 6 7 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_ 8 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_ 9 10 #include <cstdint> 11 #include <string> 12 13 #include "quiche/quic/core/congestion_control/cubic_bytes.h" 14 #include "quiche/quic/core/congestion_control/hybrid_slow_start.h" 15 #include "quiche/quic/core/congestion_control/prr_sender.h" 16 #include "quiche/quic/core/congestion_control/send_algorithm_interface.h" 17 #include "quiche/quic/core/quic_bandwidth.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/platform/api/quic_export.h" 22 23 namespace quic { 24 25 class RttStats; 26 27 // Maximum window to allow when doing bandwidth resumption. 28 inline constexpr QuicPacketCount kMaxResumptionCongestionWindow = 200; 29 30 namespace test { 31 class TcpCubicSenderBytesPeer; 32 } // namespace test 33 34 class QUICHE_EXPORT TcpCubicSenderBytes : public SendAlgorithmInterface { 35 public: 36 TcpCubicSenderBytes(const QuicClock* clock, const RttStats* rtt_stats, 37 bool reno, QuicPacketCount initial_tcp_congestion_window, 38 QuicPacketCount max_congestion_window, 39 QuicConnectionStats* stats); 40 TcpCubicSenderBytes(const TcpCubicSenderBytes&) = delete; 41 TcpCubicSenderBytes& operator=(const TcpCubicSenderBytes&) = delete; 42 ~TcpCubicSenderBytes() override; 43 44 // Start implementation of SendAlgorithmInterface. 45 void SetFromConfig(const QuicConfig& config, 46 Perspective perspective) override; ApplyConnectionOptions(const QuicTagVector &)47 void ApplyConnectionOptions( 48 const QuicTagVector& /*connection_options*/) override {} 49 void AdjustNetworkParameters(const NetworkParams& params) override; 50 void SetNumEmulatedConnections(int num_connections); 51 void SetInitialCongestionWindowInPackets( 52 QuicPacketCount congestion_window) override; 53 void OnConnectionMigration() override; 54 void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight, 55 QuicTime event_time, 56 const AckedPacketVector& acked_packets, 57 const LostPacketVector& lost_packets, 58 QuicPacketCount num_ect, 59 QuicPacketCount num_ce) override; 60 void OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight, 61 QuicPacketNumber packet_number, QuicByteCount bytes, 62 HasRetransmittableData is_retransmittable) override; OnPacketNeutered(QuicPacketNumber)63 void OnPacketNeutered(QuicPacketNumber /*packet_number*/) override {} 64 void OnRetransmissionTimeout(bool packets_retransmitted) override; 65 bool CanSend(QuicByteCount bytes_in_flight) override; 66 QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override; 67 QuicBandwidth BandwidthEstimate() const override; HasGoodBandwidthEstimateForResumption()68 bool HasGoodBandwidthEstimateForResumption() const override { return false; } 69 QuicByteCount GetCongestionWindow() const override; 70 QuicByteCount GetSlowStartThreshold() const override; 71 CongestionControlType GetCongestionControlType() const override; 72 bool InSlowStart() const override; 73 bool InRecovery() const override; 74 std::string GetDebugState() const override; 75 void OnApplicationLimited(QuicByteCount bytes_in_flight) override; PopulateConnectionStats(QuicConnectionStats *)76 void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {} EnableECT0()77 bool EnableECT0() override { return false; } EnableECT1()78 bool EnableECT1() override { return false; } 79 // End implementation of SendAlgorithmInterface. 80 min_congestion_window()81 QuicByteCount min_congestion_window() const { return min_congestion_window_; } 82 83 protected: 84 // Compute the TCP Reno beta based on the current number of connections. 85 float RenoBeta() const; 86 87 bool IsCwndLimited(QuicByteCount bytes_in_flight) const; 88 89 // TODO(ianswett): Remove these and migrate to OnCongestionEvent. 90 void OnPacketAcked(QuicPacketNumber acked_packet_number, 91 QuicByteCount acked_bytes, QuicByteCount prior_in_flight, 92 QuicTime event_time); 93 void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth, 94 QuicTime::Delta rtt); 95 void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window); 96 void ExitSlowstart(); 97 void OnPacketLost(QuicPacketNumber packet_number, QuicByteCount lost_bytes, 98 QuicByteCount prior_in_flight); 99 void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number, 100 QuicByteCount acked_bytes, 101 QuicByteCount prior_in_flight, QuicTime event_time); 102 void HandleRetransmissionTimeout(); 103 104 private: 105 friend class test::TcpCubicSenderBytesPeer; 106 107 HybridSlowStart hybrid_slow_start_; 108 PrrSender prr_; 109 const RttStats* rtt_stats_; 110 QuicConnectionStats* stats_; 111 112 // If true, Reno congestion control is used instead of Cubic. 113 const bool reno_; 114 115 // Number of connections to simulate. 116 uint32_t num_connections_; 117 118 // Track the largest packet that has been sent. 119 QuicPacketNumber largest_sent_packet_number_; 120 121 // Track the largest packet that has been acked. 122 QuicPacketNumber largest_acked_packet_number_; 123 124 // Track the largest packet number outstanding when a CWND cutback occurs. 125 QuicPacketNumber largest_sent_at_last_cutback_; 126 127 // Whether to use 4 packets as the actual min, but pace lower. 128 bool min4_mode_; 129 130 // Whether the last loss event caused us to exit slowstart. 131 // Used for stats collection of slowstart_packets_lost 132 bool last_cutback_exited_slowstart_; 133 134 // When true, exit slow start with large cutback of congestion window. 135 bool slow_start_large_reduction_; 136 137 // When true, use unity pacing instead of PRR. 138 bool no_prr_; 139 140 CubicBytes cubic_; 141 142 // ACK counter for the Reno implementation. 143 uint64_t num_acked_packets_; 144 145 // Congestion window in bytes. 146 QuicByteCount congestion_window_; 147 148 // Minimum congestion window in bytes. 149 QuicByteCount min_congestion_window_; 150 151 // Maximum congestion window in bytes. 152 QuicByteCount max_congestion_window_; 153 154 // Slow start congestion window in bytes, aka ssthresh. 155 QuicByteCount slowstart_threshold_; 156 157 // Initial TCP congestion window in bytes. This variable can only be set when 158 // this algorithm is created. 159 const QuicByteCount initial_tcp_congestion_window_; 160 161 // Initial maximum TCP congestion window in bytes. This variable can only be 162 // set when this algorithm is created. 163 const QuicByteCount initial_max_tcp_congestion_window_; 164 165 // The minimum window when exiting slow start with large reduction. 166 QuicByteCount min_slow_start_exit_window_; 167 }; 168 169 } // namespace quic 170 171 #endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_ 172