211 lines
7.8 KiB
C
211 lines
7.8 KiB
C
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
|
|
#ifndef LSQUIC_BBR_H
|
|
#define LSQUIC_BBR_H
|
|
|
|
/* Our BBR implementation is copied from Chromium with some modifications.
|
|
* Besides the obvious translation from C++ to C, differences are:
|
|
*
|
|
* 1. Instead of OnCongestionEvent(), the ACK information is processed at the
|
|
* same time as the ACK itself using cci_begin_ack(), cci_ack(), and
|
|
* cci_end_ack() methods. This is done to fit with the flow in
|
|
* lsquic_send_ctl_got_ack().
|
|
*
|
|
* 2. The bandwidth sampler does not use a hash. Instead, the sample
|
|
* information is attached directly to the packet via po_bwp_state.
|
|
*
|
|
* In this file and in lsquic_bbr.c, C++-style comments are those copied
|
|
* verbatim from Chromium. C-style comments are ours.
|
|
*
|
|
* Code is based on bbr_sender.cc 1a578a76c16abc942205a1a80584a288c262d03a in
|
|
* the "quiche" repository. (Not to be confused with Cloudflare's "quiche".)
|
|
*
|
|
* The BBR I-D is here:
|
|
* https://tools.ietf.org/html/draft-cardwell-iccrg-bbr-congestion-control-00
|
|
*
|
|
* As for quiche, see
|
|
* http://www.bernstein-plus-sons.com/RPDEQ.html
|
|
*
|
|
* Chromium copyright notice follows.
|
|
*/
|
|
// Copyright 2016 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.chrome file.
|
|
|
|
struct lsquic_bbr
|
|
{
|
|
const struct lsquic_conn_public *bbr_conn_pub;
|
|
|
|
enum bbr_mode
|
|
{
|
|
BBR_MODE_STARTUP,
|
|
BBR_MODE_DRAIN,
|
|
BBR_MODE_PROBE_BW,
|
|
BBR_MODE_PROBE_RTT,
|
|
} bbr_mode;
|
|
|
|
enum
|
|
{
|
|
BBR_RS_NOT_IN_RECOVERY,
|
|
BBR_RS_CONSERVATION,
|
|
BBR_RS_GROWTH,
|
|
} bbr_recovery_state;
|
|
|
|
enum
|
|
{
|
|
BBR_FLAG_IN_ACK = 1 << 0, /* cci_begin_ack() has been called */
|
|
BBR_FLAG_LAST_SAMPLE_APP_LIMITED = 1 << 1,
|
|
BBR_FLAG_HAS_NON_APP_LIMITED = 1 << 2,
|
|
BBR_FLAG_APP_LIMITED_SINCE_LAST_PROBE_RTT
|
|
= 1 << 3,
|
|
BBR_FLAG_PROBE_RTT_DISABLED_IF_APP_LIMITED
|
|
= 1 << 4,
|
|
BBR_FLAG_PROBE_RTT_SKIPPED_IF_SIMILAR_RTT
|
|
= 1 << 5,
|
|
BBR_FLAG_EXIT_STARTUP_ON_LOSS = 1 << 6,
|
|
BBR_FLAG_IS_AT_FULL_BANDWIDTH = 1 << 7,
|
|
BBR_FLAG_EXITING_QUIESCENCE = 1 << 8,
|
|
BBR_FLAG_PROBE_RTT_ROUND_PASSED = 1 << 9,
|
|
BBR_FLAG_FLEXIBLE_APP_LIMITED = 1 << 10,
|
|
// If true, will not exit low gain mode until bytes_in_flight drops
|
|
// below BDP or it's time for high gain mode.
|
|
BBR_FLAG_DRAIN_TO_TARGET = 1 << 11,
|
|
// When true, expire the windowed ack aggregation values in STARTUP
|
|
// when bandwidth increases more than 25%.
|
|
BBR_FLAG_EXPIRE_ACK_AGG_IN_STARTUP
|
|
= 1 << 12,
|
|
// If true, use a CWND of 0.75*BDP during probe_rtt instead of 4
|
|
// packets.
|
|
BBR_FLAG_PROBE_RTT_BASED_ON_BDP = 1 << 13,
|
|
// When true, pace at 1.5x and disable packet conservation in STARTUP.
|
|
BBR_FLAG_SLOWER_STARTUP = 1 << 14,
|
|
// When true, add the most recent ack aggregation measurement during STARTUP.
|
|
BBR_FLAG_ENABLE_ACK_AGG_IN_STARTUP
|
|
= 1 << 15,
|
|
// When true, disables packet conservation in STARTUP.
|
|
BBR_FLAG_RATE_BASED_STARTUP = 1 << 16,
|
|
} bbr_flags;
|
|
|
|
// Number of round-trips in PROBE_BW mode, used for determining the current
|
|
// pacing gain cycle.
|
|
unsigned bbr_cycle_current_offset;
|
|
|
|
const struct lsquic_rtt_stats
|
|
*bbr_rtt_stats;
|
|
|
|
struct bw_sampler bbr_bw_sampler;
|
|
|
|
/*
|
|
" BBR.BtlBwFilter: The max filter used to estimate BBR.BtlBw.
|
|
*/
|
|
struct minmax bbr_max_bandwidth;
|
|
|
|
// Tracks the maximum number of bytes acked faster than the sending rate.
|
|
struct minmax bbr_max_ack_height;
|
|
|
|
// The initial value of the bbr_cwnd.
|
|
uint64_t bbr_init_cwnd;
|
|
// The smallest value the bbr_cwnd can achieve.
|
|
uint64_t bbr_min_cwnd;
|
|
// The largest value the bbr_cwnd can achieve.
|
|
uint64_t bbr_max_cwnd;
|
|
// The maximum allowed number of bytes in flight.
|
|
uint64_t bbr_cwnd;
|
|
|
|
// The time this aggregation started and the number of bytes acked during it.
|
|
lsquic_time_t bbr_aggregation_epoch_start_time;
|
|
uint64_t bbr_aggregation_epoch_bytes;
|
|
|
|
lsquic_packno_t bbr_last_sent_packno;
|
|
lsquic_packno_t bbr_current_round_trip_end;
|
|
|
|
// Receiving acknowledgement of a packet after |bbr_end_recovery_at| will
|
|
// cause BBR to exit the recovery mode. A value above zero indicates at
|
|
// least one loss has been detected, so it must not be set back to zero.
|
|
lsquic_packno_t bbr_end_recovery_at;
|
|
|
|
/*
|
|
" BBR.round_count: Count of packet-timed round trips.
|
|
*/
|
|
uint64_t bbr_round_count;
|
|
|
|
/* Not documented in the draft: */
|
|
uint64_t bbr_full_bw;
|
|
|
|
/* Not documented in the draft: */
|
|
uint64_t bbr_full_bw_count;
|
|
|
|
/*
|
|
" BBR.pacing_rate: The current pacing rate for a BBR flow, which
|
|
" controls inter-packet spacing.
|
|
*/
|
|
struct bandwidth bbr_pacing_rate;
|
|
|
|
// Sum of bytes lost in STARTUP.
|
|
uint64_t bbr_startup_bytes_lost;
|
|
|
|
/*
|
|
" BBR.pacing_gain: The dynamic gain factor used to scale BBR.BtlBw to
|
|
" produce BBR.pacing_rate.
|
|
*/
|
|
float bbr_pacing_gain;
|
|
|
|
// The pacing gain applied during the STARTUP phase.
|
|
float bbr_high_gain;
|
|
|
|
// The CWND gain applied during the STARTUP phase.
|
|
float bbr_high_cwnd_gain;
|
|
|
|
// The pacing gain applied during the DRAIN phase.
|
|
float bbr_drain_gain;
|
|
|
|
// The number of RTTs to stay in STARTUP mode. Defaults to 3.
|
|
unsigned bbr_num_startup_rtts;
|
|
|
|
// Number of rounds during which there was no significant bandwidth
|
|
// increase.
|
|
unsigned bbr_round_wo_bw_gain;
|
|
|
|
/*
|
|
" BBR.cwnd_gain: The dynamic gain factor used to scale the estimated
|
|
" BDP to produce a congestion window (cwnd).
|
|
*/
|
|
float bbr_cwnd_gain;
|
|
|
|
// The bandwidth compared to which the increase is measured.
|
|
struct bandwidth bbr_bw_at_last_round;
|
|
|
|
// The time at which the last pacing gain cycle was started.
|
|
lsquic_time_t bbr_last_cycle_start;
|
|
|
|
// Time at which PROBE_RTT has to be exited. Setting it to zero indicates
|
|
// that the time is yet unknown as the number of packets in flight has not
|
|
// reached the required value.
|
|
lsquic_time_t bbr_exit_probe_rtt_at;
|
|
|
|
lsquic_time_t bbr_min_rtt_since_last_probe;
|
|
lsquic_time_t bbr_min_rtt;
|
|
lsquic_time_t bbr_min_rtt_timestamp;
|
|
|
|
// A window used to limit the number of bytes in flight during loss recovery
|
|
uint64_t bbr_recovery_window;
|
|
|
|
/* Accumulate information from a single ACK. Gets processed when
|
|
* cci_end_ack() is called.
|
|
*/
|
|
struct
|
|
{
|
|
TAILQ_HEAD(, bw_sample) samples;
|
|
lsquic_time_t ack_time;
|
|
lsquic_packno_t max_packno;
|
|
uint64_t acked_bytes;
|
|
uint64_t lost_bytes;
|
|
uint64_t total_bytes_acked_before;
|
|
uint64_t in_flight;
|
|
int has_losses;
|
|
} bbr_ack_state;
|
|
};
|
|
|
|
extern const struct cong_ctl_if lsquic_cong_bbr_if;
|
|
|
|
#endif
|