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