1 /*
2  * ngtcp2
3  *
4  * Copyright (c) 2018 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_CC_H
26 #define NGTCP2_CC_H
27 
28 #ifdef HAVE_CONFIG_H
29 #  include <config.h>
30 #endif /* HAVE_CONFIG_H */
31 
32 #include <ngtcp2/ngtcp2.h>
33 
34 #define NGTCP2_LOSS_REDUCTION_FACTOR_BITS 1
35 #define NGTCP2_PERSISTENT_CONGESTION_THRESHOLD 3
36 
37 typedef struct ngtcp2_log ngtcp2_log;
38 
39 /*
40  * ngtcp2_cc_compute_initcwnd computes initial cwnd.
41  */
42 uint64_t ngtcp2_cc_compute_initcwnd(size_t max_packet_size);
43 
44 ngtcp2_cc_pkt *ngtcp2_cc_pkt_init(ngtcp2_cc_pkt *pkt, int64_t pkt_num,
45                                   size_t pktlen, ngtcp2_pktns_id pktns_id,
46                                   ngtcp2_tstamp sent_ts);
47 
48 /* ngtcp2_reno_cc is the RENO congestion controller. */
49 typedef struct ngtcp2_reno_cc {
50   ngtcp2_cc_base ccb;
51   uint64_t max_delivery_rate_sec;
52   uint64_t target_cwnd;
53   uint64_t pending_add;
54 } ngtcp2_reno_cc;
55 
56 int ngtcp2_cc_reno_cc_init(ngtcp2_cc *cc, ngtcp2_log *log,
57                            const ngtcp2_mem *mem);
58 
59 void ngtcp2_cc_reno_cc_free(ngtcp2_cc *cc, const ngtcp2_mem *mem);
60 
61 void ngtcp2_reno_cc_init(ngtcp2_reno_cc *cc, ngtcp2_log *log);
62 
63 void ngtcp2_reno_cc_free(ngtcp2_reno_cc *cc);
64 
65 void ngtcp2_cc_reno_cc_on_pkt_acked(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
66                                     const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
67 
68 void ngtcp2_cc_reno_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
69                                         ngtcp2_tstamp sent_ts,
70                                         ngtcp2_tstamp ts);
71 
72 void ngtcp2_cc_reno_cc_on_persistent_congestion(ngtcp2_cc *cc,
73                                                 ngtcp2_conn_stat *cstat,
74                                                 ngtcp2_tstamp ts);
75 
76 void ngtcp2_cc_reno_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
77                                    const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
78 
79 void ngtcp2_cc_reno_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
80                              ngtcp2_tstamp ts);
81 
82 /* ngtcp2_cubic_cc is CUBIC congestion controller. */
83 typedef struct ngtcp2_cubic_cc {
84   ngtcp2_cc_base ccb;
85   uint64_t max_delivery_rate_sec;
86   uint64_t target_cwnd;
87   uint64_t w_last_max;
88   uint64_t w_tcp;
89   uint64_t origin_point;
90   ngtcp2_tstamp epoch_start;
91   uint64_t k;
92   /* prior stores the congestion state when a congestion event occurs
93      in order to restore the state when it turns out that the event is
94      spurious. */
95   struct {
96     uint64_t cwnd;
97     uint64_t ssthresh;
98     uint64_t w_last_max;
99     uint64_t w_tcp;
100     uint64_t origin_point;
101     ngtcp2_tstamp epoch_start;
102     uint64_t k;
103   } prior;
104   /* HyStart++ variables */
105   size_t rtt_sample_count;
106   uint64_t current_round_min_rtt;
107   uint64_t last_round_min_rtt;
108   int64_t window_end;
109   uint64_t pending_add;
110   uint64_t pending_w_add;
111 } ngtcp2_cubic_cc;
112 
113 int ngtcp2_cc_cubic_cc_init(ngtcp2_cc *cc, ngtcp2_log *log,
114                             const ngtcp2_mem *mem);
115 
116 void ngtcp2_cc_cubic_cc_free(ngtcp2_cc *cc, const ngtcp2_mem *mem);
117 
118 void ngtcp2_cubic_cc_init(ngtcp2_cubic_cc *cc, ngtcp2_log *log);
119 
120 void ngtcp2_cubic_cc_free(ngtcp2_cubic_cc *cc);
121 
122 void ngtcp2_cc_cubic_cc_on_pkt_acked(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
123                                      const ngtcp2_cc_pkt *pkt,
124                                      ngtcp2_tstamp ts);
125 
126 void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
127                                          ngtcp2_tstamp sent_ts,
128                                          ngtcp2_tstamp ts);
129 
130 void ngtcp2_cc_cubic_cc_on_spurious_congestion(ngtcp2_cc *ccx,
131                                                ngtcp2_conn_stat *cstat,
132                                                ngtcp2_tstamp ts);
133 
134 void ngtcp2_cc_cubic_cc_on_persistent_congestion(ngtcp2_cc *cc,
135                                                  ngtcp2_conn_stat *cstat,
136                                                  ngtcp2_tstamp ts);
137 
138 void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
139                                     const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
140 
141 void ngtcp2_cc_cubic_cc_on_pkt_sent(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
142                                     const ngtcp2_cc_pkt *pkt);
143 
144 void ngtcp2_cc_cubic_cc_new_rtt_sample(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
145                                        ngtcp2_tstamp ts);
146 
147 void ngtcp2_cc_cubic_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
148                               ngtcp2_tstamp ts);
149 
150 void ngtcp2_cc_cubic_cc_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
151                               ngtcp2_cc_event_type event, ngtcp2_tstamp ts);
152 
153 #endif /* NGTCP2_CC_H */
154