summaryrefslogtreecommitdiffstats
path: root/lib/ngtcp2_bbr.h
blob: 7311f051e187bc56c2605c0261c14362ddbd43e2 (plain)
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 */