1 /* 2 * ngtcp2 3 * 4 * Copyright (c) 2021 ngtcp2 contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef NGTCP2_BBR_H 26 #define NGTCP2_BBR_H 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif /* HAVE_CONFIG_H */ 31 32 #include <ngtcp2/ngtcp2.h> 33 34 #include "ngtcp2_window_filter.h" 35 36 typedef struct ngtcp2_rst ngtcp2_rst; 37 38 typedef enum ngtcp2_bbr_state { 39 NGTCP2_BBR_STATE_STARTUP, 40 NGTCP2_BBR_STATE_DRAIN, 41 NGTCP2_BBR_STATE_PROBE_BW, 42 NGTCP2_BBR_STATE_PROBE_RTT, 43 } ngtcp2_bbr_state; 44 45 /* 46 * ngtcp2_bbr_cc is BBR congestion controller, described in 47 * https://tools.ietf.org/html/draft-cardwell-iccrg-bbr-congestion-control-00 48 */ 49 typedef struct ngtcp2_bbr_cc { 50 ngtcp2_cc_base ccb; 51 52 /* The max filter used to estimate BBR.BtlBw. */ 53 ngtcp2_window_filter btl_bw_filter; 54 uint64_t initial_cwnd; 55 ngtcp2_rst *rst; 56 ngtcp2_rand rand; 57 ngtcp2_rand_ctx rand_ctx; 58 59 /* BBR variables */ 60 61 /* The dynamic gain factor used to scale BBR.BtlBw to 62 produce BBR.pacing_rate. */ 63 double pacing_gain; 64 /* The dynamic gain factor used to scale the estimated BDP to produce a 65 congestion window (cwnd). */ 66 double cwnd_gain; 67 uint64_t full_bw; 68 /* packet.delivered value denoting the end of a packet-timed round trip. */ 69 uint64_t next_round_delivered; 70 /* Count of packet-timed round trips. */ 71 uint64_t round_count; 72 uint64_t prior_cwnd; 73 /* target_cwnd is the upper bound on the volume of data BBR 74 allows in flight. */ 75 uint64_t target_cwnd; 76 /* BBR's estimated bottleneck bandwidth available to the 77 transport flow, estimated from the maximum delivery rate sample in a 78 sliding window. */ 79 uint64_t btl_bw; 80 /* BBR's estimated two-way round-trip propagation delay of 81 the path, estimated from the windowed minimum recent round-trip delay 82 sample. */ 83 ngtcp2_duration rt_prop; 84 /* The wall clock time at which the current BBR.RTProp 85 sample was obtained. */ 86 ngtcp2_tstamp rtprop_stamp; 87 ngtcp2_tstamp cycle_stamp; 88 ngtcp2_tstamp probe_rtt_done_stamp; 89 /* congestion_recovery_start_ts is the time when congestion recovery 90 period started.*/ 91 ngtcp2_tstamp congestion_recovery_start_ts; 92 size_t full_bw_count; 93 size_t cycle_index; 94 ngtcp2_bbr_state state; 95 /* A boolean that records whether BBR estimates that it has ever fully 96 utilized its available bandwidth ("filled the pipe"). */ 97 int filled_pipe; 98 /* A boolean that BBR sets to true once per packet-timed round trip, 99 on ACKs that advance BBR.round_count. */ 100 int round_start; 101 int rtprop_expired; 102 int idle_restart; 103 int packet_conservation; 104 int probe_rtt_round_done; 105 /* in_loss_recovery becomes nonzero when BBR enters loss recovery 106 period. */ 107 int in_loss_recovery; 108 } ngtcp2_bbr_cc; 109 110 int ngtcp2_cc_bbr_cc_init(ngtcp2_cc *cc, ngtcp2_log *log, 111 ngtcp2_conn_stat *cstat, ngtcp2_rst *rst, 112 ngtcp2_tstamp initial_ts, ngtcp2_rand rand, 113 const ngtcp2_rand_ctx *rand_ctx, 114 const ngtcp2_mem *mem); 115 116 void ngtcp2_cc_bbr_cc_free(ngtcp2_cc *cc, const ngtcp2_mem *mem); 117 118 void ngtcp2_bbr_cc_init(ngtcp2_bbr_cc *bbr_cc, ngtcp2_conn_stat *cstat, 119 ngtcp2_rst *rst, ngtcp2_tstamp initial_ts, 120 ngtcp2_rand rand, const ngtcp2_rand_ctx *rand_ctx, 121 ngtcp2_log *log); 122 123 void ngtcp2_bbr_cc_free(ngtcp2_bbr_cc *cc); 124 125 void ngtcp2_cc_bbr_cc_on_pkt_acked(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 126 const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts); 127 128 void ngtcp2_cc_bbr_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 129 ngtcp2_tstamp sent_ts, ngtcp2_tstamp ts); 130 131 void ngtcp2_cc_bbr_cc_on_spurious_congestion(ngtcp2_cc *ccx, 132 ngtcp2_conn_stat *cstat, 133 ngtcp2_tstamp ts); 134 135 void ngtcp2_cc_bbr_cc_on_persistent_congestion(ngtcp2_cc *cc, 136 ngtcp2_conn_stat *cstat, 137 ngtcp2_tstamp ts); 138 139 void ngtcp2_cc_bbr_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 140 const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts); 141 142 void ngtcp2_cc_bbr_cc_on_pkt_sent(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 143 const ngtcp2_cc_pkt *pkt); 144 145 void ngtcp2_cc_bbr_cc_new_rtt_sample(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 146 ngtcp2_tstamp ts); 147 148 void ngtcp2_cc_bbr_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 149 ngtcp2_tstamp ts); 150 151 void ngtcp2_cc_bbr_cc_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 152 ngtcp2_cc_event_type event, ngtcp2_tstamp ts); 153 154 #endif /* NGTCP2_CC_H */ 155