1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2#ifndef LSQUIC_BBR_H 3#define LSQUIC_BBR_H 4 5/* Our BBR implementation is copied from Chromium with some modifications. 6 * Besides the obvious translation from C++ to C, differences are: 7 * 8 * 1. Instead of OnCongestionEvent(), the ACK information is processed at the 9 * same time as the ACK itself using cci_begin_ack(), cci_ack(), and 10 * cci_end_ack() methods. This is done to fit with the flow in 11 * lsquic_send_ctl_got_ack(). 12 * 13 * 2. The bandwidth sampler does not use a hash. Instead, the sample 14 * information is attached directly to the packet via po_bwp_state. 15 * 16 * In this file and in lsquic_bbr.c, C++-style comments are those copied 17 * verbatim from Chromium. C-style comments are ours. 18 * 19 * Code is based on bbr_sender.cc 1a578a76c16abc942205a1a80584a288c262d03a in 20 * the "quiche" repository. (Not to be confused with Cloudflare's "quiche".) 21 * 22 * The BBR I-D is here: 23 * https://tools.ietf.org/html/draft-cardwell-iccrg-bbr-congestion-control-00 24 * 25 * As for quiche, see 26 * http://www.bernstein-plus-sons.com/RPDEQ.html 27 * 28 * Chromium copyright notice follows. 29 */ 30// Copyright 2016 The Chromium Authors. All rights reserved. 31// Use of this source code is governed by a BSD-style license that can be 32// found in the LICENSE.chrome file. 33 34struct lsquic_bbr 35{ 36 const struct lsquic_conn_public *bbr_conn_pub; 37 38 enum bbr_mode 39 { 40 BBR_MODE_STARTUP, 41 BBR_MODE_DRAIN, 42 BBR_MODE_PROBE_BW, 43 BBR_MODE_PROBE_RTT, 44 } bbr_mode; 45 46 enum 47 { 48 BBR_RS_NOT_IN_RECOVERY, 49 BBR_RS_CONSERVATION, 50 BBR_RS_GROWTH, 51 } bbr_recovery_state; 52 53 enum 54 { 55 BBR_FLAG_IN_ACK = 1 << 0, /* cci_begin_ack() has been called */ 56 BBR_FLAG_LAST_SAMPLE_APP_LIMITED = 1 << 1, 57 BBR_FLAG_HAS_NON_APP_LIMITED = 1 << 2, 58 BBR_FLAG_APP_LIMITED_SINCE_LAST_PROBE_RTT 59 = 1 << 3, 60 BBR_FLAG_PROBE_RTT_DISABLED_IF_APP_LIMITED 61 = 1 << 4, 62 BBR_FLAG_PROBE_RTT_SKIPPED_IF_SIMILAR_RTT 63 = 1 << 5, 64 BBR_FLAG_EXIT_STARTUP_ON_LOSS = 1 << 6, 65 BBR_FLAG_IS_AT_FULL_BANDWIDTH = 1 << 7, 66 BBR_FLAG_EXITING_QUIESCENCE = 1 << 8, 67 BBR_FLAG_PROBE_RTT_ROUND_PASSED = 1 << 9, 68 BBR_FLAG_FLEXIBLE_APP_LIMITED = 1 << 10, 69 // If true, will not exit low gain mode until bytes_in_flight drops 70 // below BDP or it's time for high gain mode. 71 BBR_FLAG_DRAIN_TO_TARGET = 1 << 11, 72 // When true, expire the windowed ack aggregation values in STARTUP 73 // when bandwidth increases more than 25%. 74 BBR_FLAG_EXPIRE_ACK_AGG_IN_STARTUP 75 = 1 << 12, 76 // If true, use a CWND of 0.75*BDP during probe_rtt instead of 4 77 // packets. 78 BBR_FLAG_PROBE_RTT_BASED_ON_BDP = 1 << 13, 79 // When true, pace at 1.5x and disable packet conservation in STARTUP. 80 BBR_FLAG_SLOWER_STARTUP = 1 << 14, 81 // When true, add the most recent ack aggregation measurement during STARTUP. 82 BBR_FLAG_ENABLE_ACK_AGG_IN_STARTUP 83 = 1 << 15, 84 // When true, disables packet conservation in STARTUP. 85 BBR_FLAG_RATE_BASED_STARTUP = 1 << 16, 86 } bbr_flags; 87 88 // Number of round-trips in PROBE_BW mode, used for determining the current 89 // pacing gain cycle. 90 unsigned bbr_cycle_current_offset; 91 92 const struct lsquic_rtt_stats 93 *bbr_rtt_stats; 94 95 struct bw_sampler bbr_bw_sampler; 96 97 /* 98 " BBR.BtlBwFilter: The max filter used to estimate BBR.BtlBw. 99 */ 100 struct minmax bbr_max_bandwidth; 101 102 // Tracks the maximum number of bytes acked faster than the sending rate. 103 struct minmax bbr_max_ack_height; 104 105 // The initial value of the bbr_cwnd. 106 uint64_t bbr_init_cwnd; 107 // The smallest value the bbr_cwnd can achieve. 108 uint64_t bbr_min_cwnd; 109 // The largest value the bbr_cwnd can achieve. 110 uint64_t bbr_max_cwnd; 111 // The maximum allowed number of bytes in flight. 112 uint64_t bbr_cwnd; 113 114 // The time this aggregation started and the number of bytes acked during it. 115 lsquic_time_t bbr_aggregation_epoch_start_time; 116 uint64_t bbr_aggregation_epoch_bytes; 117 118 lsquic_packno_t bbr_last_sent_packno; 119 lsquic_packno_t bbr_current_round_trip_end; 120 121 // Receiving acknowledgement of a packet after |bbr_end_recovery_at| will 122 // cause BBR to exit the recovery mode. A value above zero indicates at 123 // least one loss has been detected, so it must not be set back to zero. 124 lsquic_packno_t bbr_end_recovery_at; 125 126 /* 127 " BBR.round_count: Count of packet-timed round trips. 128 */ 129 uint64_t bbr_round_count; 130 131 /* Not documented in the draft: */ 132 uint64_t bbr_full_bw; 133 134 /* Not documented in the draft: */ 135 uint64_t bbr_full_bw_count; 136 137 /* 138 " BBR.pacing_rate: The current pacing rate for a BBR flow, which 139 " controls inter-packet spacing. 140 */ 141 struct bandwidth bbr_pacing_rate; 142 143 // Sum of bytes lost in STARTUP. 144 uint64_t bbr_startup_bytes_lost; 145 146 /* 147 " BBR.pacing_gain: The dynamic gain factor used to scale BBR.BtlBw to 148 " produce BBR.pacing_rate. 149 */ 150 float bbr_pacing_gain; 151 152 // The pacing gain applied during the STARTUP phase. 153 float bbr_high_gain; 154 155 // The CWND gain applied during the STARTUP phase. 156 float bbr_high_cwnd_gain; 157 158 // The pacing gain applied during the DRAIN phase. 159 float bbr_drain_gain; 160 161 // The number of RTTs to stay in STARTUP mode. Defaults to 3. 162 unsigned bbr_num_startup_rtts; 163 164 // Number of rounds during which there was no significant bandwidth 165 // increase. 166 unsigned bbr_round_wo_bw_gain; 167 168 /* 169 " BBR.cwnd_gain: The dynamic gain factor used to scale the estimated 170 " BDP to produce a congestion window (cwnd). 171 */ 172 float bbr_cwnd_gain; 173 174 // The bandwidth compared to which the increase is measured. 175 struct bandwidth bbr_bw_at_last_round; 176 177 // The time at which the last pacing gain cycle was started. 178 lsquic_time_t bbr_last_cycle_start; 179 180 // Time at which PROBE_RTT has to be exited. Setting it to zero indicates 181 // that the time is yet unknown as the number of packets in flight has not 182 // reached the required value. 183 lsquic_time_t bbr_exit_probe_rtt_at; 184 185 lsquic_time_t bbr_min_rtt_since_last_probe; 186 lsquic_time_t bbr_min_rtt; 187 lsquic_time_t bbr_min_rtt_timestamp; 188 189 // A window used to limit the number of bytes in flight during loss recovery 190 uint64_t bbr_recovery_window; 191 192 /* Accumulate information from a single ACK. Gets processed when 193 * cci_end_ack() is called. 194 */ 195 struct 196 { 197 TAILQ_HEAD(, bw_sample) samples; 198 lsquic_time_t ack_time; 199 lsquic_packno_t max_packno; 200 uint64_t acked_bytes; 201 uint64_t lost_bytes; 202 uint64_t total_bytes_acked_before; 203 uint64_t in_flight; 204 int has_losses; 205 } bbr_ack_state; 206}; 207 208extern const struct cong_ctl_if lsquic_cong_bbr_if; 209 210#endif 211