blob: 74efc89f812c6b0c9cbf83dd4edd3619dadd51c7 [file] [log] [blame]
// 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 QUIC_EXPORT_PRIVATE DebugState {
Bbr2Mode mode;
// Shared states.
QuicRoundTripCount round_trip_count;
QuicBandwidth bandwidth_hi = QuicBandwidth::Zero();
QuicBandwidth bandwidth_lo = QuicBandwidth::Zero();
QuicBandwidth bandwidth_est = QuicBandwidth::Zero();
QuicByteCount inflight_hi;
QuicByteCount inflight_lo;
QuicByteCount max_ack_height;
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_