|  | // Copyright 2019 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_ | 
|  | #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_ | 
|  |  | 
|  | #include <cstdint> | 
|  |  | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_drain.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_rtt.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h" | 
|  | #include "net/third_party/quiche/src/quic/core/congestion_control/windowed_filter.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_types.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" | 
|  |  | 
|  | namespace quic { | 
|  |  | 
|  | class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface { | 
|  | public: | 
|  | Bbr2Sender(QuicTime now, | 
|  | const RttStats* rtt_stats, | 
|  | const QuicUnackedPacketMap* unacked_packets, | 
|  | QuicPacketCount initial_cwnd_in_packets, | 
|  | QuicPacketCount max_cwnd_in_packets, | 
|  | QuicRandom* random, | 
|  | QuicConnectionStats* /*stats*/); | 
|  |  | 
|  | ~Bbr2Sender() override = default; | 
|  |  | 
|  | // Start implementation of SendAlgorithmInterface. | 
|  | bool InSlowStart() const override { return mode_ == Bbr2Mode::STARTUP; } | 
|  |  | 
|  | bool InRecovery() const override { | 
|  | // TODO(wub): Implement Recovery. | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool ShouldSendProbingPacket() const override; | 
|  |  | 
|  | void SetFromConfig(const QuicConfig& config, | 
|  | Perspective perspective) override; | 
|  |  | 
|  | void AdjustNetworkParameters(QuicBandwidth bandwidth, | 
|  | QuicTime::Delta rtt, | 
|  | bool allow_cwnd_to_decrease) override; | 
|  |  | 
|  | void SetInitialCongestionWindowInPackets( | 
|  | QuicPacketCount congestion_window) override; | 
|  |  | 
|  | void OnCongestionEvent(bool rtt_updated, | 
|  | QuicByteCount prior_in_flight, | 
|  | QuicTime event_time, | 
|  | const AckedPacketVector& acked_packets, | 
|  | const LostPacketVector& lost_packets) override; | 
|  |  | 
|  | void OnPacketSent(QuicTime sent_time, | 
|  | QuicByteCount bytes_in_flight, | 
|  | QuicPacketNumber packet_number, | 
|  | QuicByteCount bytes, | 
|  | HasRetransmittableData is_retransmittable) override; | 
|  |  | 
|  | void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {} | 
|  |  | 
|  | void OnConnectionMigration() override {} | 
|  |  | 
|  | bool CanSend(QuicByteCount bytes_in_flight) override; | 
|  |  | 
|  | QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override; | 
|  |  | 
|  | QuicBandwidth BandwidthEstimate() const override { | 
|  | return model_.BandwidthEstimate(); | 
|  | } | 
|  |  | 
|  | QuicByteCount GetCongestionWindow() const override; | 
|  |  | 
|  | QuicByteCount GetSlowStartThreshold() const override { return 0; } | 
|  |  | 
|  | CongestionControlType GetCongestionControlType() const override { | 
|  | return kBBRv2; | 
|  | } | 
|  |  | 
|  | std::string GetDebugState() const override; | 
|  |  | 
|  | void OnApplicationLimited(QuicByteCount bytes_in_flight) override; | 
|  | // End implementation of SendAlgorithmInterface. | 
|  |  | 
|  | const Bbr2Params& Params() const { return params_; } | 
|  |  | 
|  | QuicByteCount GetMinimumCongestionWindow() const { | 
|  | return cwnd_limits().Min(); | 
|  | } | 
|  |  | 
|  | struct DebugState { | 
|  | Bbr2Mode mode; | 
|  |  | 
|  | // Shared states. | 
|  | QuicRoundTripCount round_trip_count; | 
|  | QuicBandwidth bandwidth_hi = QuicBandwidth::Zero(); | 
|  | QuicBandwidth bandwidth_lo = QuicBandwidth::Zero(); | 
|  | QuicBandwidth bandwidth_est = QuicBandwidth::Zero(); | 
|  | QuicTime::Delta min_rtt = QuicTime::Delta::Zero(); | 
|  | QuicTime min_rtt_timestamp = QuicTime::Zero(); | 
|  | QuicByteCount congestion_window; | 
|  | QuicBandwidth pacing_rate = QuicBandwidth::Zero(); | 
|  | bool last_sample_is_app_limited; | 
|  | QuicPacketNumber end_of_app_limited_phase; | 
|  |  | 
|  | // Mode-specific debug states. | 
|  | Bbr2StartupMode::DebugState startup; | 
|  | Bbr2DrainMode::DebugState drain; | 
|  | Bbr2ProbeBwMode::DebugState probe_bw; | 
|  | Bbr2ProbeRttMode::DebugState probe_rtt; | 
|  | }; | 
|  |  | 
|  | DebugState ExportDebugState() const; | 
|  |  | 
|  | private: | 
|  | void UpdatePacingRate(QuicByteCount bytes_acked); | 
|  | void UpdateCongestionWindow(QuicByteCount bytes_acked); | 
|  | QuicByteCount GetTargetCongestionWindow(float gain) const; | 
|  |  | 
|  | // Helper function for BBR2_MODE_DISPATCH. | 
|  | Bbr2ProbeRttMode& probe_rtt_or_die() { | 
|  | DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT); | 
|  | return probe_rtt_; | 
|  | } | 
|  |  | 
|  | const Bbr2ProbeRttMode& probe_rtt_or_die() const { | 
|  | DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT); | 
|  | return probe_rtt_; | 
|  | } | 
|  |  | 
|  | uint64_t RandomUint64(uint64_t max) const { | 
|  | return random_->RandUint64() % max; | 
|  | } | 
|  |  | 
|  | // Returns true if there are enough bytes in flight to ensure more bandwidth | 
|  | // will be observed if present. | 
|  | bool IsPipeSufficientlyFull() const; | 
|  |  | 
|  | // Cwnd limits imposed by the current Bbr2 mode. | 
|  | Limits<QuicByteCount> GetCwndLimitsByMode() const; | 
|  |  | 
|  | // Cwnd limits imposed by caller. | 
|  | const Limits<QuicByteCount>& cwnd_limits() const; | 
|  |  | 
|  | Bbr2Mode mode_; | 
|  |  | 
|  | const RttStats* const rtt_stats_; | 
|  | const QuicUnackedPacketMap* const unacked_packets_; | 
|  | QuicRandom* random_; | 
|  |  | 
|  | const Bbr2Params params_; | 
|  |  | 
|  | Bbr2NetworkModel model_; | 
|  |  | 
|  | const QuicByteCount initial_cwnd_; | 
|  |  | 
|  | // Current cwnd and pacing rate. | 
|  | QuicByteCount cwnd_; | 
|  | QuicBandwidth pacing_rate_; | 
|  |  | 
|  | Bbr2StartupMode startup_; | 
|  | Bbr2DrainMode drain_; | 
|  | Bbr2ProbeBwMode probe_bw_; | 
|  | Bbr2ProbeRttMode probe_rtt_; | 
|  |  | 
|  | // Indicates app-limited calls should be ignored as long as there's | 
|  | // enough data inflight to see more bandwidth when necessary. | 
|  | bool flexible_app_limited_; | 
|  |  | 
|  | // Debug only. | 
|  | bool last_sample_is_app_limited_; | 
|  |  | 
|  | friend class Bbr2StartupMode; | 
|  | friend class Bbr2DrainMode; | 
|  | friend class Bbr2ProbeBwMode; | 
|  | friend class Bbr2ProbeRttMode; | 
|  | }; | 
|  |  | 
|  | QUIC_EXPORT_PRIVATE std::ostream& operator<<( | 
|  | std::ostream& os, | 
|  | const Bbr2Sender::DebugState& state); | 
|  |  | 
|  | }  // namespace quic | 
|  |  | 
|  | #endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_ |