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