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