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_cc.h" 35 #include "ngtcp2_window_filter.h" 36 37 typedef struct ngtcp2_rst ngtcp2_rst; 38 39 typedef enum ngtcp2_bbr_state { 40 NGTCP2_BBR_STATE_STARTUP, 41 NGTCP2_BBR_STATE_DRAIN, 42 NGTCP2_BBR_STATE_PROBE_BW, 43 NGTCP2_BBR_STATE_PROBE_RTT, 44 } ngtcp2_bbr_state; 45 46 /* 47 * ngtcp2_bbr_cc is BBR congestion controller, described in 48 * https://tools.ietf.org/html/draft-cardwell-iccrg-bbr-congestion-control-00 49 */ 50 typedef struct ngtcp2_bbr_cc { 51 ngtcp2_cc_base ccb; 52 53 /* The max filter used to estimate BBR.BtlBw. */ 54 ngtcp2_window_filter btl_bw_filter; 55 uint64_t initial_cwnd; 56 ngtcp2_rst *rst; 57 ngtcp2_rand rand; 58 ngtcp2_rand_ctx rand_ctx; 59 60 /* BBR variables */ 61 62 /* The dynamic gain factor used to scale BBR.BtlBw to 63 produce BBR.pacing_rate. */ 64 double pacing_gain; 65 /* The dynamic gain factor used to scale the estimated BDP to produce a 66 congestion window (cwnd). */ 67 double cwnd_gain; 68 uint64_t full_bw; 69 /* packet.delivered value denoting the end of a packet-timed round trip. */ 70 uint64_t next_round_delivered; 71 /* Count of packet-timed round trips. */ 72 uint64_t round_count; 73 uint64_t prior_cwnd; 74 /* target_cwnd is the upper bound on the volume of data BBR 75 allows in flight. */ 76 uint64_t target_cwnd; 77 /* BBR's estimated bottleneck bandwidth available to the 78 transport flow, estimated from the maximum delivery rate sample in a 79 sliding window. */ 80 uint64_t btl_bw; 81 /* BBR's estimated two-way round-trip propagation delay of 82 the path, estimated from the windowed minimum recent round-trip delay 83 sample. */ 84 ngtcp2_duration rt_prop; 85 /* The wall clock time at which the current BBR.RTProp 86 sample was obtained. */ 87 ngtcp2_tstamp rtprop_stamp; 88 ngtcp2_tstamp cycle_stamp; 89 ngtcp2_tstamp probe_rtt_done_stamp; 90 /* congestion_recovery_start_ts is the time when congestion recovery 91 period started.*/ 92 ngtcp2_tstamp congestion_recovery_start_ts; 93 uint64_t congestion_recovery_next_round_delivered; 94 size_t full_bw_count; 95 size_t cycle_index; 96 ngtcp2_bbr_state state; 97 /* A boolean that records whether BBR estimates that it has ever fully 98 utilized its available bandwidth ("filled the pipe"). */ 99 int filled_pipe; 100 /* A boolean that BBR sets to true once per packet-timed round trip, 101 on ACKs that advance BBR.round_count. */ 102 int round_start; 103 int rtprop_expired; 104 int idle_restart; 105 int packet_conservation; 106 int probe_rtt_round_done; 107 /* in_loss_recovery becomes nonzero when BBR enters loss recovery 108 period. */ 109 int in_loss_recovery; 110 } ngtcp2_bbr_cc; 111 112 int ngtcp2_cc_bbr_cc_init(ngtcp2_cc *cc, ngtcp2_log *log, 113 ngtcp2_conn_stat *cstat, ngtcp2_rst *rst, 114 ngtcp2_tstamp initial_ts, ngtcp2_rand rand, 115 const ngtcp2_rand_ctx *rand_ctx, 116 const ngtcp2_mem *mem); 117 118 void ngtcp2_cc_bbr_cc_free(ngtcp2_cc *cc, const ngtcp2_mem *mem); 119 120 void ngtcp2_bbr_cc_init(ngtcp2_bbr_cc *bbr_cc, ngtcp2_conn_stat *cstat, 121 ngtcp2_rst *rst, ngtcp2_tstamp initial_ts, 122 ngtcp2_rand rand, const ngtcp2_rand_ctx *rand_ctx, 123 ngtcp2_log *log); 124 125 void ngtcp2_bbr_cc_free(ngtcp2_bbr_cc *cc); 126 127 void ngtcp2_cc_bbr_cc_on_pkt_acked(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 128 const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts); 129 130 void ngtcp2_cc_bbr_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 131 ngtcp2_tstamp sent_ts, ngtcp2_tstamp ts); 132 133 void ngtcp2_cc_bbr_cc_on_spurious_congestion(ngtcp2_cc *ccx, 134 ngtcp2_conn_stat *cstat, 135 ngtcp2_tstamp ts); 136 137 void ngtcp2_cc_bbr_cc_on_persistent_congestion(ngtcp2_cc *cc, 138 ngtcp2_conn_stat *cstat, 139 ngtcp2_tstamp ts); 140 141 void ngtcp2_cc_bbr_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 142 const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts); 143 144 void ngtcp2_cc_bbr_cc_on_pkt_sent(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 145 const ngtcp2_cc_pkt *pkt); 146 147 void ngtcp2_cc_bbr_cc_new_rtt_sample(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 148 ngtcp2_tstamp ts); 149 150 void ngtcp2_cc_bbr_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 151 ngtcp2_tstamp ts); 152 153 void ngtcp2_cc_bbr_cc_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, 154 ngtcp2_cc_event_type event, ngtcp2_tstamp ts); 155 156 #endif /* NGTCP2_BBR_H */ 157