ngtcp2_bbr.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425
  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. #include "ngtcp2_bbr.h"
  26. #include <assert.h>
  27. #include <string.h>
  28. #include "ngtcp2_log.h"
  29. #include "ngtcp2_macro.h"
  30. #include "ngtcp2_mem.h"
  31. #include "ngtcp2_rcvry.h"
  32. #include "ngtcp2_rst.h"
  33. #include "ngtcp2_conn_stat.h"
  34. #define NGTCP2_BBR_MAX_BW_FILTERLEN 2
  35. #define NGTCP2_BBR_EXTRA_ACKED_FILTERLEN 10
  36. #define NGTCP2_BBR_STARTUP_PACING_GAIN_H 277
  37. #define NGTCP2_BBR_DRAIN_PACING_GAIN_H 35
  38. #define NGTCP2_BBR_DEFAULT_CWND_GAIN_H 200
  39. #define NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H 50
  40. #define NGTCP2_BBR_BETA_NUMER 7
  41. #define NGTCP2_BBR_BETA_DENOM 10
  42. #define NGTCP2_BBR_LOSS_THRESH_NUMER 2
  43. #define NGTCP2_BBR_LOSS_THRESH_DENOM 100
  44. #define NGTCP2_BBR_HEADROOM_NUMER 15
  45. #define NGTCP2_BBR_HEADROOM_DENOM 100
  46. #define NGTCP2_BBR_PROBE_RTT_INTERVAL (5 * NGTCP2_SECONDS)
  47. #define NGTCP2_BBR_MIN_RTT_FILTERLEN (10 * NGTCP2_SECONDS)
  48. #define NGTCP2_BBR_PROBE_RTT_DURATION (200 * NGTCP2_MILLISECONDS)
  49. #define NGTCP2_BBR_PACING_MARGIN_PERCENT 1
  50. static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  51. ngtcp2_tstamp initial_ts);
  52. static void bbr_on_transmit(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  53. ngtcp2_tstamp ts);
  54. static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr);
  55. static void bbr_reset_lower_bounds(ngtcp2_cc_bbr *bbr);
  56. static void bbr_init_round_counting(ngtcp2_cc_bbr *bbr);
  57. static void bbr_reset_full_bw(ngtcp2_cc_bbr *bbr);
  58. static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  59. static void bbr_set_pacing_rate_with_gain(ngtcp2_cc_bbr *bbr,
  60. ngtcp2_conn_stat *cstat,
  61. uint64_t pacing_gain_h);
  62. static void bbr_set_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  63. static void bbr_enter_startup(ngtcp2_cc_bbr *bbr);
  64. static void bbr_check_startup_done(ngtcp2_cc_bbr *bbr);
  65. static void bbr_update_on_ack(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  66. const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
  67. static void bbr_update_model_and_state(ngtcp2_cc_bbr *cc,
  68. ngtcp2_conn_stat *cstat,
  69. const ngtcp2_cc_ack *ack,
  70. ngtcp2_tstamp ts);
  71. static void bbr_update_control_parameters(ngtcp2_cc_bbr *cc,
  72. ngtcp2_conn_stat *cstat,
  73. const ngtcp2_cc_ack *ack);
  74. static void bbr_update_on_loss(ngtcp2_cc_bbr *cc, ngtcp2_conn_stat *cstat,
  75. const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
  76. static void bbr_update_latest_delivery_signals(ngtcp2_cc_bbr *bbr,
  77. ngtcp2_conn_stat *cstat);
  78. static void bbr_advance_latest_delivery_signals(ngtcp2_cc_bbr *bbr,
  79. ngtcp2_conn_stat *cstat);
  80. static void bbr_update_congestion_signals(ngtcp2_cc_bbr *bbr,
  81. ngtcp2_conn_stat *cstat,
  82. const ngtcp2_cc_ack *ack);
  83. static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_cc_bbr *bbr,
  84. ngtcp2_conn_stat *cstat);
  85. static void bbr_init_lower_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  86. static void bbr_loss_lower_bounds(ngtcp2_cc_bbr *bbr);
  87. static void bbr_bound_bw_for_model(ngtcp2_cc_bbr *bbr);
  88. static void bbr_update_max_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  89. const ngtcp2_cc_ack *ack);
  90. static void bbr_update_round(ngtcp2_cc_bbr *bbr, const ngtcp2_cc_ack *ack);
  91. static void bbr_start_round(ngtcp2_cc_bbr *bbr);
  92. static int bbr_is_in_probe_bw_state(ngtcp2_cc_bbr *bbr);
  93. static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
  94. ngtcp2_conn_stat *cstat,
  95. const ngtcp2_cc_ack *ack,
  96. ngtcp2_tstamp ts);
  97. static void bbr_enter_drain(ngtcp2_cc_bbr *bbr);
  98. static void bbr_check_drain(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  99. ngtcp2_tstamp ts);
  100. static void bbr_enter_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts);
  101. static void bbr_start_probe_bw_down(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts);
  102. static void bbr_start_probe_bw_cruise(ngtcp2_cc_bbr *bbr);
  103. static void bbr_start_probe_bw_refill(ngtcp2_cc_bbr *bbr);
  104. static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  105. static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
  106. ngtcp2_conn_stat *cstat,
  107. const ngtcp2_cc_ack *ack,
  108. ngtcp2_tstamp ts);
  109. static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  110. ngtcp2_tstamp ts);
  111. static int bbr_is_time_to_go_down(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  112. static int bbr_has_elapsed_in_phase(ngtcp2_cc_bbr *bbr,
  113. ngtcp2_duration interval, ngtcp2_tstamp ts);
  114. static uint64_t bbr_inflight_with_headroom(ngtcp2_cc_bbr *bbr,
  115. ngtcp2_conn_stat *cstat);
  116. static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
  117. ngtcp2_conn_stat *cstat);
  118. static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
  119. ngtcp2_conn_stat *cstat,
  120. const ngtcp2_cc_ack *ack);
  121. static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  122. const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
  123. static int bbr_is_time_to_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  124. ngtcp2_tstamp ts);
  125. static void bbr_pick_probe_wait(ngtcp2_cc_bbr *bbr);
  126. static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
  127. ngtcp2_conn_stat *cstat);
  128. static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
  129. ngtcp2_conn_stat *cstat);
  130. static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr,
  131. ngtcp2_conn_stat *cstat,
  132. ngtcp2_tstamp ts);
  133. static int is_inflight_too_high(const ngtcp2_rs *rs);
  134. static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
  135. ngtcp2_conn_stat *cstat,
  136. const ngtcp2_rs *rs, ngtcp2_tstamp ts);
  137. static void bbr_note_loss(ngtcp2_cc_bbr *bbr);
  138. static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  139. const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
  140. static uint64_t bbr_inflight_hi_from_lost_packet(ngtcp2_cc_bbr *bbr,
  141. const ngtcp2_rs *rs,
  142. const ngtcp2_cc_pkt *pkt);
  143. static void bbr_update_min_rtt(ngtcp2_cc_bbr *bbr, const ngtcp2_cc_ack *ack,
  144. ngtcp2_tstamp ts);
  145. static void bbr_check_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  146. ngtcp2_tstamp ts);
  147. static void bbr_enter_probe_rtt(ngtcp2_cc_bbr *bbr);
  148. static void bbr_handle_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  149. ngtcp2_tstamp ts);
  150. static void bbr_check_probe_rtt_done(ngtcp2_cc_bbr *bbr,
  151. ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts);
  152. static void bbr_mark_connection_app_limited(ngtcp2_cc_bbr *bbr,
  153. ngtcp2_conn_stat *cstat);
  154. static void bbr_exit_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts);
  155. static void bbr_handle_restart_from_idle(ngtcp2_cc_bbr *bbr,
  156. ngtcp2_conn_stat *cstat,
  157. ngtcp2_tstamp ts);
  158. static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h);
  159. static uint64_t bbr_quantization_budget(ngtcp2_cc_bbr *bbr,
  160. ngtcp2_conn_stat *cstat,
  161. uint64_t inflight);
  162. static uint64_t bbr_inflight(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  163. uint64_t gain_h);
  164. static void bbr_update_max_inflight(ngtcp2_cc_bbr *bbr,
  165. ngtcp2_conn_stat *cstat);
  166. static void bbr_update_offload_budget(ngtcp2_cc_bbr *bbr,
  167. ngtcp2_conn_stat *cstat);
  168. static uint64_t min_pipe_cwnd(size_t max_udp_payload_size);
  169. static void bbr_advance_max_bw_filter(ngtcp2_cc_bbr *bbr);
  170. static void bbr_save_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  171. static void bbr_restore_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  172. static uint64_t bbr_probe_rtt_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  173. static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_cc_bbr *bbr,
  174. ngtcp2_conn_stat *cstat);
  175. static void bbr_set_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  176. const ngtcp2_cc_ack *ack);
  177. static void bbr_bound_cwnd_for_model(ngtcp2_cc_bbr *bbr,
  178. ngtcp2_conn_stat *cstat);
  179. static void bbr_set_send_quantum(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
  180. static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
  181. ngtcp2_tstamp sent_time);
  182. static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  183. const ngtcp2_cc_ack *ack);
  184. static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  185. ngtcp2_tstamp initial_ts) {
  186. ngtcp2_window_filter_init(&bbr->max_bw_filter, NGTCP2_BBR_MAX_BW_FILTERLEN);
  187. ngtcp2_window_filter_init(&bbr->extra_acked_filter,
  188. NGTCP2_BBR_EXTRA_ACKED_FILTERLEN);
  189. bbr->min_rtt = UINT64_MAX;
  190. bbr->min_rtt_stamp = initial_ts;
  191. /* remark: Use UINT64_MAX instead of 0 for consistency. */
  192. bbr->probe_rtt_done_stamp = UINT64_MAX;
  193. bbr->probe_rtt_round_done = 0;
  194. bbr->prior_cwnd = 0;
  195. bbr->idle_restart = 0;
  196. bbr->extra_acked_interval_start = initial_ts;
  197. bbr->extra_acked_delivered = 0;
  198. bbr->full_bw_reached = 0;
  199. bbr_reset_congestion_signals(bbr);
  200. bbr_reset_lower_bounds(bbr);
  201. bbr_init_round_counting(bbr);
  202. bbr_reset_full_bw(bbr);
  203. bbr_init_pacing_rate(bbr, cstat);
  204. bbr_enter_startup(bbr);
  205. cstat->send_quantum = cstat->max_tx_udp_payload_size * 10;
  206. /* Missing in documentation */
  207. bbr->loss_round_start = 0;
  208. bbr->loss_round_delivered = UINT64_MAX;
  209. bbr->rounds_since_bw_probe = 0;
  210. bbr->max_bw = 0;
  211. bbr->bw = 0;
  212. bbr->cycle_count = 0;
  213. bbr->extra_acked = 0;
  214. bbr->bytes_lost_in_round = 0;
  215. bbr->loss_events_in_round = 0;
  216. bbr->offload_budget = 0;
  217. bbr->probe_up_cnt = UINT64_MAX;
  218. bbr->cycle_stamp = UINT64_MAX;
  219. bbr->ack_phase = 0;
  220. bbr->bw_probe_wait = 0;
  221. bbr->bw_probe_samples = 0;
  222. bbr->bw_probe_up_rounds = 0;
  223. bbr->bw_probe_up_acks = 0;
  224. bbr->inflight_hi = UINT64_MAX;
  225. bbr->probe_rtt_expired = 0;
  226. bbr->probe_rtt_min_delay = UINT64_MAX;
  227. bbr->probe_rtt_min_stamp = initial_ts;
  228. bbr->in_loss_recovery = 0;
  229. bbr->round_count_at_recovery = UINT64_MAX;
  230. bbr->max_inflight = 0;
  231. bbr->congestion_recovery_start_ts = UINT64_MAX;
  232. }
  233. static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr) {
  234. bbr->loss_in_round = 0;
  235. bbr->bw_latest = 0;
  236. bbr->inflight_latest = 0;
  237. }
  238. static void bbr_reset_lower_bounds(ngtcp2_cc_bbr *bbr) {
  239. bbr->bw_lo = UINT64_MAX;
  240. bbr->inflight_lo = UINT64_MAX;
  241. }
  242. static void bbr_init_round_counting(ngtcp2_cc_bbr *bbr) {
  243. bbr->next_round_delivered = 0;
  244. bbr->round_start = 0;
  245. bbr->round_count = 0;
  246. }
  247. static void bbr_reset_full_bw(ngtcp2_cc_bbr *bbr) {
  248. bbr->full_bw = 0;
  249. bbr->full_bw_count = 0;
  250. bbr->full_bw_now = 0;
  251. }
  252. static void bbr_check_full_bw_reached(ngtcp2_cc_bbr *bbr,
  253. ngtcp2_conn_stat *cstat) {
  254. if (bbr->full_bw_now || bbr->rst->rs.is_app_limited) {
  255. return;
  256. }
  257. if (cstat->delivery_rate_sec * 100 >= bbr->full_bw * 125) {
  258. bbr_reset_full_bw(bbr);
  259. bbr->full_bw = cstat->delivery_rate_sec;
  260. return;
  261. }
  262. if (!bbr->round_start) {
  263. return;
  264. }
  265. ++bbr->full_bw_count;
  266. bbr->full_bw_now = bbr->full_bw_count >= 3;
  267. if (!bbr->full_bw_now) {
  268. return;
  269. }
  270. bbr->full_bw_reached = 1;
  271. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
  272. "bbr reached full bandwidth, full_bw=%" PRIu64, bbr->full_bw);
  273. }
  274. static void bbr_check_startup_high_loss(ngtcp2_cc_bbr *bbr) {
  275. if (bbr->full_bw_reached || bbr->loss_events_in_round <= 6 ||
  276. (bbr->in_loss_recovery &&
  277. bbr->round_count <= bbr->round_count_at_recovery) ||
  278. !is_inflight_too_high(&bbr->rst->rs)) {
  279. return;
  280. }
  281. bbr->full_bw_reached = 1;
  282. bbr->inflight_hi = ngtcp2_max_uint64(bbr_bdp_multiple(bbr, bbr->cwnd_gain_h),
  283. bbr->inflight_latest);
  284. }
  285. static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  286. cstat->pacing_interval = NGTCP2_MILLISECONDS * 100 /
  287. NGTCP2_BBR_STARTUP_PACING_GAIN_H / bbr->initial_cwnd;
  288. }
  289. static void bbr_set_pacing_rate_with_gain(ngtcp2_cc_bbr *bbr,
  290. ngtcp2_conn_stat *cstat,
  291. uint64_t pacing_gain_h) {
  292. ngtcp2_duration interval;
  293. if (bbr->bw == 0) {
  294. return;
  295. }
  296. interval = NGTCP2_SECONDS * 100 * 100 / pacing_gain_h / bbr->bw /
  297. (100 - NGTCP2_BBR_PACING_MARGIN_PERCENT);
  298. if (bbr->full_bw_reached || interval < cstat->pacing_interval) {
  299. cstat->pacing_interval = interval;
  300. }
  301. }
  302. static void bbr_set_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  303. bbr_set_pacing_rate_with_gain(bbr, cstat, bbr->pacing_gain_h);
  304. }
  305. static void bbr_enter_startup(ngtcp2_cc_bbr *bbr) {
  306. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr enter Startup");
  307. bbr->state = NGTCP2_BBR_STATE_STARTUP;
  308. bbr->pacing_gain_h = NGTCP2_BBR_STARTUP_PACING_GAIN_H;
  309. bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
  310. }
  311. static void bbr_check_startup_done(ngtcp2_cc_bbr *bbr) {
  312. bbr_check_startup_high_loss(bbr);
  313. if (bbr->state == NGTCP2_BBR_STATE_STARTUP && bbr->full_bw_reached) {
  314. bbr_enter_drain(bbr);
  315. }
  316. }
  317. static void bbr_on_transmit(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  318. ngtcp2_tstamp ts) {
  319. bbr_handle_restart_from_idle(bbr, cstat, ts);
  320. }
  321. static void bbr_update_on_ack(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  322. const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
  323. bbr_update_model_and_state(bbr, cstat, ack, ts);
  324. bbr_update_control_parameters(bbr, cstat, ack);
  325. }
  326. static void bbr_update_model_and_state(ngtcp2_cc_bbr *bbr,
  327. ngtcp2_conn_stat *cstat,
  328. const ngtcp2_cc_ack *ack,
  329. ngtcp2_tstamp ts) {
  330. bbr_update_latest_delivery_signals(bbr, cstat);
  331. bbr_update_congestion_signals(bbr, cstat, ack);
  332. bbr_update_ack_aggregation(bbr, cstat, ack, ts);
  333. bbr_check_full_bw_reached(bbr, cstat);
  334. bbr_check_startup_done(bbr);
  335. bbr_check_drain(bbr, cstat, ts);
  336. bbr_update_probe_bw_cycle_phase(bbr, cstat, ack, ts);
  337. bbr_update_min_rtt(bbr, ack, ts);
  338. bbr_check_probe_rtt(bbr, cstat, ts);
  339. bbr_advance_latest_delivery_signals(bbr, cstat);
  340. bbr_bound_bw_for_model(bbr);
  341. }
  342. static void bbr_update_control_parameters(ngtcp2_cc_bbr *bbr,
  343. ngtcp2_conn_stat *cstat,
  344. const ngtcp2_cc_ack *ack) {
  345. bbr_set_pacing_rate(bbr, cstat);
  346. bbr_set_send_quantum(bbr, cstat);
  347. bbr_set_cwnd(bbr, cstat, ack);
  348. }
  349. static void bbr_update_on_loss(ngtcp2_cc_bbr *cc, ngtcp2_conn_stat *cstat,
  350. const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
  351. bbr_handle_lost_packet(cc, cstat, pkt, ts);
  352. }
  353. static void bbr_update_latest_delivery_signals(ngtcp2_cc_bbr *bbr,
  354. ngtcp2_conn_stat *cstat) {
  355. bbr->loss_round_start = 0;
  356. bbr->bw_latest = ngtcp2_max_uint64(bbr->bw_latest, cstat->delivery_rate_sec);
  357. bbr->inflight_latest =
  358. ngtcp2_max_uint64(bbr->inflight_latest, bbr->rst->rs.delivered);
  359. if (bbr->rst->rs.prior_delivered >= bbr->loss_round_delivered) {
  360. bbr->loss_round_delivered = bbr->rst->delivered;
  361. bbr->loss_round_start = 1;
  362. }
  363. }
  364. static void bbr_advance_latest_delivery_signals(ngtcp2_cc_bbr *bbr,
  365. ngtcp2_conn_stat *cstat) {
  366. if (bbr->loss_round_start) {
  367. bbr->bw_latest = cstat->delivery_rate_sec;
  368. bbr->inflight_latest = bbr->rst->rs.delivered;
  369. }
  370. }
  371. static void bbr_update_congestion_signals(ngtcp2_cc_bbr *bbr,
  372. ngtcp2_conn_stat *cstat,
  373. const ngtcp2_cc_ack *ack) {
  374. bbr_update_max_bw(bbr, cstat, ack);
  375. if (ack->bytes_lost) {
  376. bbr->bytes_lost_in_round += ack->bytes_lost;
  377. ++bbr->loss_events_in_round;
  378. }
  379. if (!bbr->loss_round_start) {
  380. return;
  381. }
  382. bbr_adapt_lower_bounds_from_congestion(bbr, cstat);
  383. bbr->loss_in_round = 0;
  384. }
  385. static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_cc_bbr *bbr,
  386. ngtcp2_conn_stat *cstat) {
  387. if (bbr_is_in_probe_bw_state(bbr)) {
  388. return;
  389. }
  390. if (bbr->loss_in_round) {
  391. bbr_init_lower_bounds(bbr, cstat);
  392. bbr_loss_lower_bounds(bbr);
  393. }
  394. }
  395. static void bbr_init_lower_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  396. if (bbr->bw_lo == UINT64_MAX) {
  397. bbr->bw_lo = bbr->max_bw;
  398. }
  399. if (bbr->inflight_lo == UINT64_MAX) {
  400. bbr->inflight_lo = cstat->cwnd;
  401. }
  402. }
  403. static void bbr_loss_lower_bounds(ngtcp2_cc_bbr *bbr) {
  404. bbr->bw_lo = ngtcp2_max_uint64(
  405. bbr->bw_latest, bbr->bw_lo * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
  406. bbr->inflight_lo = ngtcp2_max_uint64(
  407. bbr->inflight_latest,
  408. bbr->inflight_lo * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
  409. }
  410. static void bbr_bound_bw_for_model(ngtcp2_cc_bbr *bbr) {
  411. bbr->bw = ngtcp2_min_uint64(bbr->max_bw, bbr->bw_lo);
  412. }
  413. static void bbr_update_max_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  414. const ngtcp2_cc_ack *ack) {
  415. bbr_update_round(bbr, ack);
  416. if (cstat->delivery_rate_sec >= bbr->max_bw || !bbr->rst->rs.is_app_limited) {
  417. ngtcp2_window_filter_update(&bbr->max_bw_filter, cstat->delivery_rate_sec,
  418. bbr->cycle_count);
  419. bbr->max_bw = ngtcp2_window_filter_get_best(&bbr->max_bw_filter);
  420. }
  421. }
  422. static void bbr_update_round(ngtcp2_cc_bbr *bbr, const ngtcp2_cc_ack *ack) {
  423. if (ack->pkt_delivered >= bbr->next_round_delivered) {
  424. bbr_start_round(bbr);
  425. ++bbr->round_count;
  426. ++bbr->rounds_since_bw_probe;
  427. bbr->round_start = 1;
  428. bbr->bytes_lost_in_round = 0;
  429. bbr->loss_events_in_round = 0;
  430. bbr->rst->is_cwnd_limited = 0;
  431. return;
  432. }
  433. bbr->round_start = 0;
  434. }
  435. static void bbr_start_round(ngtcp2_cc_bbr *bbr) {
  436. bbr->next_round_delivered = bbr->rst->delivered;
  437. }
  438. static int bbr_is_in_probe_bw_state(ngtcp2_cc_bbr *bbr) {
  439. switch (bbr->state) {
  440. case NGTCP2_BBR_STATE_PROBE_BW_DOWN:
  441. case NGTCP2_BBR_STATE_PROBE_BW_CRUISE:
  442. case NGTCP2_BBR_STATE_PROBE_BW_REFILL:
  443. case NGTCP2_BBR_STATE_PROBE_BW_UP:
  444. return 1;
  445. default:
  446. return 0;
  447. }
  448. }
  449. static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
  450. ngtcp2_conn_stat *cstat,
  451. const ngtcp2_cc_ack *ack,
  452. ngtcp2_tstamp ts) {
  453. ngtcp2_duration interval = ts - bbr->extra_acked_interval_start;
  454. uint64_t expected_delivered = bbr->bw * interval / NGTCP2_SECONDS;
  455. uint64_t extra;
  456. if (bbr->extra_acked_delivered <= expected_delivered) {
  457. bbr->extra_acked_delivered = 0;
  458. bbr->extra_acked_interval_start = ts;
  459. expected_delivered = 0;
  460. }
  461. bbr->extra_acked_delivered += ack->bytes_delivered;
  462. extra = bbr->extra_acked_delivered - expected_delivered;
  463. extra = ngtcp2_min_uint64(extra, cstat->cwnd);
  464. if (bbr->full_bw_reached) {
  465. bbr->extra_acked_filter.window_length = NGTCP2_BBR_EXTRA_ACKED_FILTERLEN;
  466. } else {
  467. bbr->extra_acked_filter.window_length = 1;
  468. }
  469. ngtcp2_window_filter_update(&bbr->extra_acked_filter, extra,
  470. bbr->round_count);
  471. bbr->extra_acked = ngtcp2_window_filter_get_best(&bbr->extra_acked_filter);
  472. }
  473. static void bbr_enter_drain(ngtcp2_cc_bbr *bbr) {
  474. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr enter Drain");
  475. bbr->state = NGTCP2_BBR_STATE_DRAIN;
  476. bbr->pacing_gain_h = NGTCP2_BBR_DRAIN_PACING_GAIN_H;
  477. bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
  478. }
  479. static void bbr_check_drain(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  480. ngtcp2_tstamp ts) {
  481. if (bbr->state == NGTCP2_BBR_STATE_DRAIN &&
  482. cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
  483. bbr_enter_probe_bw(bbr, ts);
  484. }
  485. }
  486. static void bbr_enter_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts) {
  487. bbr_start_probe_bw_down(bbr, ts);
  488. }
  489. static void bbr_start_probe_bw_down(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts) {
  490. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr start ProbeBW_DOWN");
  491. bbr_reset_congestion_signals(bbr);
  492. bbr->probe_up_cnt = UINT64_MAX;
  493. bbr_pick_probe_wait(bbr);
  494. bbr->cycle_stamp = ts;
  495. bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STOPPING;
  496. bbr_start_round(bbr);
  497. bbr->state = NGTCP2_BBR_STATE_PROBE_BW_DOWN;
  498. bbr->pacing_gain_h = 90;
  499. bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
  500. }
  501. static void bbr_start_probe_bw_cruise(ngtcp2_cc_bbr *bbr) {
  502. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
  503. "bbr start ProbeBW_CRUISE");
  504. bbr->state = NGTCP2_BBR_STATE_PROBE_BW_CRUISE;
  505. bbr->pacing_gain_h = 100;
  506. bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
  507. }
  508. static void bbr_start_probe_bw_refill(ngtcp2_cc_bbr *bbr) {
  509. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
  510. "bbr start ProbeBW_REFILL");
  511. bbr_reset_lower_bounds(bbr);
  512. bbr->bw_probe_up_rounds = 0;
  513. bbr->bw_probe_up_acks = 0;
  514. bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_REFILLING;
  515. bbr_start_round(bbr);
  516. bbr->state = NGTCP2_BBR_STATE_PROBE_BW_REFILL;
  517. bbr->pacing_gain_h = 100;
  518. bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
  519. }
  520. static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  521. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr start ProbeBW_UP");
  522. bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STARTING;
  523. bbr_start_round(bbr);
  524. bbr_reset_full_bw(bbr);
  525. bbr->full_bw = cstat->delivery_rate_sec;
  526. bbr->state = NGTCP2_BBR_STATE_PROBE_BW_UP;
  527. bbr->pacing_gain_h = 125;
  528. bbr->cwnd_gain_h = 225;
  529. bbr_raise_inflight_hi_slope(bbr, cstat);
  530. }
  531. static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
  532. ngtcp2_conn_stat *cstat,
  533. const ngtcp2_cc_ack *ack,
  534. ngtcp2_tstamp ts) {
  535. if (!bbr->full_bw_reached) {
  536. return;
  537. }
  538. bbr_adapt_upper_bounds(bbr, cstat, ack, ts);
  539. if (!bbr_is_in_probe_bw_state(bbr)) {
  540. return;
  541. }
  542. switch (bbr->state) {
  543. case NGTCP2_BBR_STATE_PROBE_BW_DOWN:
  544. if (bbr_is_time_to_probe_bw(bbr, cstat, ts)) {
  545. return;
  546. }
  547. if (bbr_is_time_to_cruise(bbr, cstat, ts)) {
  548. bbr_start_probe_bw_cruise(bbr);
  549. }
  550. break;
  551. case NGTCP2_BBR_STATE_PROBE_BW_CRUISE:
  552. if (bbr_is_time_to_probe_bw(bbr, cstat, ts)) {
  553. return;
  554. }
  555. break;
  556. case NGTCP2_BBR_STATE_PROBE_BW_REFILL:
  557. if (bbr->round_start) {
  558. bbr->bw_probe_samples = 1;
  559. bbr_start_probe_bw_up(bbr, cstat);
  560. }
  561. break;
  562. case NGTCP2_BBR_STATE_PROBE_BW_UP:
  563. if (bbr_is_time_to_go_down(bbr, cstat)) {
  564. bbr_start_probe_bw_down(bbr, ts);
  565. }
  566. break;
  567. default:
  568. break;
  569. }
  570. }
  571. static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  572. ngtcp2_tstamp ts) {
  573. (void)ts;
  574. if (cstat->bytes_in_flight > bbr_inflight_with_headroom(bbr, cstat)) {
  575. return 0;
  576. }
  577. if (cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
  578. return 1;
  579. }
  580. return 0;
  581. }
  582. static int bbr_is_time_to_go_down(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  583. if (bbr->rst->is_cwnd_limited && cstat->cwnd >= bbr->inflight_hi) {
  584. bbr_reset_full_bw(bbr);
  585. bbr->full_bw = cstat->delivery_rate_sec;
  586. } else if (bbr->full_bw_now) {
  587. return 1;
  588. }
  589. return 0;
  590. }
  591. static int bbr_has_elapsed_in_phase(ngtcp2_cc_bbr *bbr,
  592. ngtcp2_duration interval,
  593. ngtcp2_tstamp ts) {
  594. return ts > bbr->cycle_stamp + interval;
  595. }
  596. static uint64_t bbr_inflight_with_headroom(ngtcp2_cc_bbr *bbr,
  597. ngtcp2_conn_stat *cstat) {
  598. uint64_t headroom;
  599. uint64_t mpcwnd;
  600. if (bbr->inflight_hi == UINT64_MAX) {
  601. return UINT64_MAX;
  602. }
  603. headroom = ngtcp2_max_uint64(cstat->max_tx_udp_payload_size,
  604. bbr->inflight_hi * NGTCP2_BBR_HEADROOM_NUMER /
  605. NGTCP2_BBR_HEADROOM_DENOM);
  606. mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
  607. if (bbr->inflight_hi > headroom) {
  608. return ngtcp2_max_uint64(bbr->inflight_hi - headroom, mpcwnd);
  609. }
  610. return mpcwnd;
  611. }
  612. static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
  613. ngtcp2_conn_stat *cstat) {
  614. uint64_t growth_this_round = cstat->max_tx_udp_payload_size
  615. << bbr->bw_probe_up_rounds;
  616. bbr->bw_probe_up_rounds = ngtcp2_min_size(bbr->bw_probe_up_rounds + 1, 30);
  617. bbr->probe_up_cnt = ngtcp2_max_uint64(cstat->cwnd / growth_this_round, 1) *
  618. cstat->max_tx_udp_payload_size;
  619. }
  620. static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
  621. ngtcp2_conn_stat *cstat,
  622. const ngtcp2_cc_ack *ack) {
  623. uint64_t delta;
  624. if (!bbr->rst->is_cwnd_limited || cstat->cwnd < bbr->inflight_hi) {
  625. return;
  626. }
  627. bbr->bw_probe_up_acks += ack->bytes_delivered;
  628. if (bbr->bw_probe_up_acks >= bbr->probe_up_cnt) {
  629. delta = bbr->bw_probe_up_acks / bbr->probe_up_cnt;
  630. bbr->bw_probe_up_acks -= delta * bbr->probe_up_cnt;
  631. bbr->inflight_hi += delta * cstat->max_tx_udp_payload_size;
  632. }
  633. if (bbr->round_start) {
  634. bbr_raise_inflight_hi_slope(bbr, cstat);
  635. }
  636. }
  637. static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  638. const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
  639. if (bbr->ack_phase == NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STARTING &&
  640. bbr->round_start) {
  641. bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_FEEDBACK;
  642. }
  643. if (bbr->ack_phase == NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STOPPING &&
  644. bbr->round_start) {
  645. if (bbr_is_in_probe_bw_state(bbr) && !bbr->rst->rs.is_app_limited) {
  646. bbr_advance_max_bw_filter(bbr);
  647. }
  648. }
  649. if (!bbr_check_inflight_too_high(bbr, cstat, ts)) {
  650. if (bbr->inflight_hi == UINT64_MAX) {
  651. return;
  652. }
  653. if (bbr->rst->rs.tx_in_flight > bbr->inflight_hi) {
  654. bbr->inflight_hi = bbr->rst->rs.tx_in_flight;
  655. }
  656. if (bbr->state == NGTCP2_BBR_STATE_PROBE_BW_UP) {
  657. bbr_probe_inflight_hi_upward(bbr, cstat, ack);
  658. }
  659. }
  660. }
  661. static int bbr_is_time_to_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  662. ngtcp2_tstamp ts) {
  663. if (bbr_has_elapsed_in_phase(bbr, bbr->bw_probe_wait, ts) ||
  664. bbr_is_reno_coexistence_probe_time(bbr, cstat)) {
  665. bbr_start_probe_bw_refill(bbr);
  666. return 1;
  667. }
  668. return 0;
  669. }
  670. static void bbr_pick_probe_wait(ngtcp2_cc_bbr *bbr) {
  671. uint8_t rand;
  672. bbr->rand(&rand, 1, &bbr->rand_ctx);
  673. bbr->rounds_since_bw_probe = (uint64_t)(rand * 2 / 256);
  674. bbr->rand(&rand, 1, &bbr->rand_ctx);
  675. bbr->bw_probe_wait =
  676. 2 * NGTCP2_SECONDS + (ngtcp2_tstamp)(NGTCP2_SECONDS * rand / 255);
  677. }
  678. static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
  679. ngtcp2_conn_stat *cstat) {
  680. uint64_t reno_rounds =
  681. bbr_target_inflight(bbr, cstat) / cstat->max_tx_udp_payload_size;
  682. return bbr->rounds_since_bw_probe >= ngtcp2_min_uint64(reno_rounds, 63);
  683. }
  684. static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
  685. ngtcp2_conn_stat *cstat) {
  686. uint64_t bdp = bbr_bdp_multiple(bbr, bbr->cwnd_gain_h);
  687. return ngtcp2_min_uint64(bdp, cstat->cwnd);
  688. }
  689. static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr,
  690. ngtcp2_conn_stat *cstat,
  691. ngtcp2_tstamp ts) {
  692. if (is_inflight_too_high(&bbr->rst->rs)) {
  693. if (bbr->bw_probe_samples) {
  694. bbr_handle_inflight_too_high(bbr, cstat, &bbr->rst->rs, ts);
  695. }
  696. return 1;
  697. }
  698. return 0;
  699. }
  700. static int is_inflight_too_high(const ngtcp2_rs *rs) {
  701. return rs->lost * NGTCP2_BBR_LOSS_THRESH_DENOM >
  702. rs->tx_in_flight * NGTCP2_BBR_LOSS_THRESH_NUMER;
  703. }
  704. static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
  705. ngtcp2_conn_stat *cstat,
  706. const ngtcp2_rs *rs,
  707. ngtcp2_tstamp ts) {
  708. bbr->bw_probe_samples = 0;
  709. if (!rs->is_app_limited) {
  710. bbr->inflight_hi = ngtcp2_max_uint64(
  711. rs->tx_in_flight, bbr_target_inflight(bbr, cstat) *
  712. NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
  713. }
  714. if (bbr->state == NGTCP2_BBR_STATE_PROBE_BW_UP) {
  715. bbr_start_probe_bw_down(bbr, ts);
  716. }
  717. }
  718. static void bbr_note_loss(ngtcp2_cc_bbr *bbr) {
  719. if (bbr->loss_in_round) {
  720. return;
  721. }
  722. bbr->loss_in_round = 1;
  723. bbr->loss_round_delivered = bbr->rst->delivered;
  724. }
  725. static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  726. const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
  727. ngtcp2_rs rs = {0};
  728. bbr_note_loss(bbr);
  729. if (!bbr->bw_probe_samples) {
  730. return;
  731. }
  732. rs.tx_in_flight = pkt->tx_in_flight;
  733. /* bbr->rst->lost is not incremented for pkt yet */
  734. rs.lost = bbr->rst->lost + pkt->pktlen - pkt->lost;
  735. rs.is_app_limited = pkt->is_app_limited;
  736. if (is_inflight_too_high(&rs)) {
  737. rs.tx_in_flight = bbr_inflight_hi_from_lost_packet(bbr, &rs, pkt);
  738. bbr_handle_inflight_too_high(bbr, cstat, &rs, ts);
  739. }
  740. }
  741. static uint64_t bbr_inflight_hi_from_lost_packet(ngtcp2_cc_bbr *bbr,
  742. const ngtcp2_rs *rs,
  743. const ngtcp2_cc_pkt *pkt) {
  744. uint64_t inflight_prev, lost_prev, lost_prefix;
  745. (void)bbr;
  746. assert(rs->tx_in_flight >= pkt->pktlen);
  747. inflight_prev = rs->tx_in_flight - pkt->pktlen;
  748. assert(rs->lost >= pkt->pktlen);
  749. lost_prev = rs->lost - pkt->pktlen;
  750. if (inflight_prev * NGTCP2_BBR_LOSS_THRESH_NUMER <
  751. lost_prev * NGTCP2_BBR_LOSS_THRESH_DENOM) {
  752. return inflight_prev;
  753. }
  754. lost_prefix = (inflight_prev * NGTCP2_BBR_LOSS_THRESH_NUMER -
  755. lost_prev * NGTCP2_BBR_LOSS_THRESH_DENOM) /
  756. (NGTCP2_BBR_LOSS_THRESH_DENOM - NGTCP2_BBR_LOSS_THRESH_NUMER);
  757. return inflight_prev + lost_prefix;
  758. }
  759. static void bbr_update_min_rtt(ngtcp2_cc_bbr *bbr, const ngtcp2_cc_ack *ack,
  760. ngtcp2_tstamp ts) {
  761. int min_rtt_expired;
  762. bbr->probe_rtt_expired =
  763. ts > bbr->probe_rtt_min_stamp + NGTCP2_BBR_PROBE_RTT_INTERVAL;
  764. if (ack->rtt != UINT64_MAX &&
  765. (ack->rtt < bbr->probe_rtt_min_delay || bbr->probe_rtt_expired)) {
  766. bbr->probe_rtt_min_delay = ack->rtt;
  767. bbr->probe_rtt_min_stamp = ts;
  768. }
  769. min_rtt_expired = ts > bbr->min_rtt_stamp + NGTCP2_BBR_MIN_RTT_FILTERLEN;
  770. if (bbr->probe_rtt_min_delay < bbr->min_rtt || min_rtt_expired) {
  771. bbr->min_rtt = bbr->probe_rtt_min_delay;
  772. bbr->min_rtt_stamp = bbr->probe_rtt_min_stamp;
  773. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
  774. "bbr update min_rtt=%" PRIu64, bbr->min_rtt);
  775. }
  776. }
  777. static void bbr_check_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  778. ngtcp2_tstamp ts) {
  779. if (bbr->state != NGTCP2_BBR_STATE_PROBE_RTT && bbr->probe_rtt_expired &&
  780. !bbr->idle_restart) {
  781. bbr_enter_probe_rtt(bbr);
  782. bbr_save_cwnd(bbr, cstat);
  783. bbr->probe_rtt_done_stamp = UINT64_MAX;
  784. bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STOPPING;
  785. bbr_start_round(bbr);
  786. }
  787. if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT) {
  788. bbr_handle_probe_rtt(bbr, cstat, ts);
  789. }
  790. if (bbr->rst->rs.delivered) {
  791. bbr->idle_restart = 0;
  792. }
  793. }
  794. static void bbr_enter_probe_rtt(ngtcp2_cc_bbr *bbr) {
  795. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr enter ProbeRTT");
  796. bbr->state = NGTCP2_BBR_STATE_PROBE_RTT;
  797. bbr->pacing_gain_h = 100;
  798. bbr->cwnd_gain_h = NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H;
  799. }
  800. static void bbr_handle_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  801. ngtcp2_tstamp ts) {
  802. bbr_mark_connection_app_limited(bbr, cstat);
  803. if (bbr->probe_rtt_done_stamp == UINT64_MAX &&
  804. cstat->bytes_in_flight <= bbr_probe_rtt_cwnd(bbr, cstat)) {
  805. bbr->probe_rtt_done_stamp = ts + NGTCP2_BBR_PROBE_RTT_DURATION;
  806. bbr->probe_rtt_round_done = 0;
  807. bbr_start_round(bbr);
  808. return;
  809. }
  810. if (bbr->probe_rtt_done_stamp != UINT64_MAX) {
  811. if (bbr->round_start) {
  812. bbr->probe_rtt_round_done = 1;
  813. }
  814. if (bbr->probe_rtt_round_done) {
  815. bbr_check_probe_rtt_done(bbr, cstat, ts);
  816. }
  817. }
  818. }
  819. static void bbr_check_probe_rtt_done(ngtcp2_cc_bbr *bbr,
  820. ngtcp2_conn_stat *cstat,
  821. ngtcp2_tstamp ts) {
  822. if (bbr->probe_rtt_done_stamp != UINT64_MAX &&
  823. ts > bbr->probe_rtt_done_stamp) {
  824. bbr->probe_rtt_min_stamp = ts;
  825. bbr_restore_cwnd(bbr, cstat);
  826. bbr_exit_probe_rtt(bbr, ts);
  827. }
  828. }
  829. static void bbr_mark_connection_app_limited(ngtcp2_cc_bbr *bbr,
  830. ngtcp2_conn_stat *cstat) {
  831. uint64_t app_limited = bbr->rst->delivered + cstat->bytes_in_flight;
  832. if (app_limited) {
  833. bbr->rst->app_limited = app_limited;
  834. } else {
  835. bbr->rst->app_limited = cstat->max_tx_udp_payload_size;
  836. }
  837. }
  838. static void bbr_exit_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts) {
  839. bbr_reset_lower_bounds(bbr);
  840. if (bbr->full_bw_reached) {
  841. bbr_start_probe_bw_down(bbr, ts);
  842. bbr_start_probe_bw_cruise(bbr);
  843. } else {
  844. bbr_enter_startup(bbr);
  845. }
  846. }
  847. static void bbr_handle_restart_from_idle(ngtcp2_cc_bbr *bbr,
  848. ngtcp2_conn_stat *cstat,
  849. ngtcp2_tstamp ts) {
  850. if (cstat->bytes_in_flight == 0 && bbr->rst->app_limited) {
  851. ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr restart from idle");
  852. bbr->idle_restart = 1;
  853. bbr->extra_acked_interval_start = ts;
  854. if (bbr_is_in_probe_bw_state(bbr)) {
  855. bbr_set_pacing_rate_with_gain(bbr, cstat, 100);
  856. } else if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT) {
  857. bbr_check_probe_rtt_done(bbr, cstat, ts);
  858. }
  859. }
  860. }
  861. static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h) {
  862. uint64_t bdp;
  863. if (bbr->min_rtt == UINT64_MAX) {
  864. return bbr->initial_cwnd;
  865. }
  866. bdp = ngtcp2_max_uint64(bbr->bw * bbr->min_rtt / NGTCP2_SECONDS, 1);
  867. return (uint64_t)(bdp * gain_h / 100);
  868. }
  869. static uint64_t min_pipe_cwnd(size_t max_udp_payload_size) {
  870. return max_udp_payload_size * 4;
  871. }
  872. static uint64_t bbr_quantization_budget(ngtcp2_cc_bbr *bbr,
  873. ngtcp2_conn_stat *cstat,
  874. uint64_t inflight) {
  875. bbr_update_offload_budget(bbr, cstat);
  876. inflight = ngtcp2_max_uint64(inflight, bbr->offload_budget);
  877. inflight =
  878. ngtcp2_max_uint64(inflight, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
  879. if (bbr->state == NGTCP2_BBR_STATE_PROBE_BW_UP) {
  880. inflight += 2 * cstat->max_tx_udp_payload_size;
  881. }
  882. return inflight;
  883. }
  884. static uint64_t bbr_inflight(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  885. uint64_t gain_h) {
  886. uint64_t inflight = bbr_bdp_multiple(bbr, gain_h);
  887. return bbr_quantization_budget(bbr, cstat, inflight);
  888. }
  889. static void bbr_update_max_inflight(ngtcp2_cc_bbr *bbr,
  890. ngtcp2_conn_stat *cstat) {
  891. uint64_t inflight;
  892. /* Not documented */
  893. /* bbr_update_aggregation_budget(bbr); */
  894. inflight = bbr_bdp_multiple(bbr, bbr->cwnd_gain_h) + bbr->extra_acked;
  895. bbr->max_inflight = bbr_quantization_budget(bbr, cstat, inflight);
  896. }
  897. static void bbr_update_offload_budget(ngtcp2_cc_bbr *bbr,
  898. ngtcp2_conn_stat *cstat) {
  899. bbr->offload_budget = 3 * cstat->send_quantum;
  900. }
  901. static void bbr_advance_max_bw_filter(ngtcp2_cc_bbr *bbr) {
  902. ++bbr->cycle_count;
  903. }
  904. static void bbr_save_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  905. if (!bbr->in_loss_recovery && bbr->state != NGTCP2_BBR_STATE_PROBE_RTT) {
  906. bbr->prior_cwnd = cstat->cwnd;
  907. return;
  908. }
  909. bbr->prior_cwnd = ngtcp2_max_uint64(bbr->prior_cwnd, cstat->cwnd);
  910. }
  911. static void bbr_restore_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  912. cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, bbr->prior_cwnd);
  913. }
  914. static uint64_t bbr_probe_rtt_cwnd(ngtcp2_cc_bbr *bbr,
  915. ngtcp2_conn_stat *cstat) {
  916. uint64_t probe_rtt_cwnd =
  917. bbr_bdp_multiple(bbr, NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H);
  918. uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
  919. return ngtcp2_max_uint64(probe_rtt_cwnd, mpcwnd);
  920. }
  921. static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_cc_bbr *bbr,
  922. ngtcp2_conn_stat *cstat) {
  923. uint64_t probe_rtt_cwnd;
  924. if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT) {
  925. probe_rtt_cwnd = bbr_probe_rtt_cwnd(bbr, cstat);
  926. cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, probe_rtt_cwnd);
  927. }
  928. }
  929. static void bbr_set_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  930. const ngtcp2_cc_ack *ack) {
  931. uint64_t mpcwnd;
  932. bbr_update_max_inflight(bbr, cstat);
  933. if (bbr->full_bw_reached) {
  934. cstat->cwnd += ack->bytes_delivered;
  935. cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, bbr->max_inflight);
  936. } else if (cstat->cwnd < bbr->max_inflight ||
  937. bbr->rst->delivered < bbr->initial_cwnd) {
  938. cstat->cwnd += ack->bytes_delivered;
  939. }
  940. mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
  941. cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, mpcwnd);
  942. bbr_bound_cwnd_for_probe_rtt(bbr, cstat);
  943. bbr_bound_cwnd_for_model(bbr, cstat);
  944. }
  945. static void bbr_bound_cwnd_for_model(ngtcp2_cc_bbr *bbr,
  946. ngtcp2_conn_stat *cstat) {
  947. uint64_t cap = UINT64_MAX;
  948. uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
  949. if (bbr_is_in_probe_bw_state(bbr) &&
  950. bbr->state != NGTCP2_BBR_STATE_PROBE_BW_CRUISE) {
  951. cap = bbr->inflight_hi;
  952. } else if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT ||
  953. bbr->state == NGTCP2_BBR_STATE_PROBE_BW_CRUISE) {
  954. cap = bbr_inflight_with_headroom(bbr, cstat);
  955. }
  956. cap = ngtcp2_min_uint64(cap, bbr->inflight_lo);
  957. cap = ngtcp2_max_uint64(cap, mpcwnd);
  958. cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, cap);
  959. }
  960. static void bbr_set_send_quantum(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
  961. size_t send_quantum = 64 * 1024;
  962. (void)bbr;
  963. if (cstat->pacing_interval) {
  964. send_quantum = ngtcp2_min_size(
  965. send_quantum, (size_t)(NGTCP2_MILLISECONDS / cstat->pacing_interval));
  966. }
  967. cstat->send_quantum =
  968. ngtcp2_max_size(send_quantum, 2 * cstat->max_tx_udp_payload_size);
  969. }
  970. static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
  971. ngtcp2_tstamp sent_time) {
  972. return cstat->congestion_recovery_start_ts != UINT64_MAX &&
  973. sent_time <= cstat->congestion_recovery_start_ts;
  974. }
  975. static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
  976. const ngtcp2_cc_ack *ack) {
  977. if (bbr->in_loss_recovery) {
  978. if (ack->largest_pkt_sent_ts != UINT64_MAX &&
  979. !in_congestion_recovery(cstat, ack->largest_pkt_sent_ts)) {
  980. bbr->in_loss_recovery = 0;
  981. bbr->round_count_at_recovery = UINT64_MAX;
  982. bbr_restore_cwnd(bbr, cstat);
  983. }
  984. return;
  985. }
  986. if (bbr->congestion_recovery_start_ts != UINT64_MAX) {
  987. bbr->in_loss_recovery = 1;
  988. bbr->round_count_at_recovery =
  989. bbr->round_start ? bbr->round_count : bbr->round_count + 1;
  990. bbr_save_cwnd(bbr, cstat);
  991. cstat->cwnd =
  992. cstat->bytes_in_flight +
  993. ngtcp2_max_uint64(ack->bytes_delivered, cstat->max_tx_udp_payload_size);
  994. cstat->congestion_recovery_start_ts = bbr->congestion_recovery_start_ts;
  995. bbr->congestion_recovery_start_ts = UINT64_MAX;
  996. }
  997. }
  998. static void bbr_cc_on_pkt_lost(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
  999. const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
  1000. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1001. if (bbr->state == NGTCP2_BBR_STATE_STARTUP) {
  1002. return;
  1003. }
  1004. bbr_update_on_loss(bbr, cstat, pkt, ts);
  1005. }
  1006. static void bbr_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
  1007. ngtcp2_tstamp sent_ts, uint64_t bytes_lost,
  1008. ngtcp2_tstamp ts) {
  1009. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1010. (void)bytes_lost;
  1011. if (bbr->in_loss_recovery ||
  1012. bbr->congestion_recovery_start_ts != UINT64_MAX ||
  1013. in_congestion_recovery(cstat, sent_ts)) {
  1014. return;
  1015. }
  1016. bbr->congestion_recovery_start_ts = ts;
  1017. }
  1018. static void bbr_cc_on_spurious_congestion(ngtcp2_cc *cc,
  1019. ngtcp2_conn_stat *cstat,
  1020. ngtcp2_tstamp ts) {
  1021. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1022. (void)ts;
  1023. bbr->congestion_recovery_start_ts = UINT64_MAX;
  1024. cstat->congestion_recovery_start_ts = UINT64_MAX;
  1025. if (bbr->in_loss_recovery) {
  1026. bbr->in_loss_recovery = 0;
  1027. bbr->round_count_at_recovery = UINT64_MAX;
  1028. bbr_restore_cwnd(bbr, cstat);
  1029. }
  1030. }
  1031. static void bbr_cc_on_persistent_congestion(ngtcp2_cc *cc,
  1032. ngtcp2_conn_stat *cstat,
  1033. ngtcp2_tstamp ts) {
  1034. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1035. (void)ts;
  1036. cstat->congestion_recovery_start_ts = UINT64_MAX;
  1037. bbr->congestion_recovery_start_ts = UINT64_MAX;
  1038. bbr->in_loss_recovery = 0;
  1039. bbr->round_count_at_recovery = UINT64_MAX;
  1040. bbr_save_cwnd(bbr, cstat);
  1041. cstat->cwnd = cstat->bytes_in_flight + cstat->max_tx_udp_payload_size;
  1042. cstat->cwnd = ngtcp2_max_uint64(
  1043. cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
  1044. }
  1045. static void bbr_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
  1046. const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
  1047. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1048. bbr_handle_recovery(bbr, cstat, ack);
  1049. bbr_update_on_ack(bbr, cstat, ack, ts);
  1050. }
  1051. static void bbr_cc_on_pkt_sent(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
  1052. const ngtcp2_cc_pkt *pkt) {
  1053. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1054. bbr_on_transmit(bbr, cstat, pkt->sent_ts);
  1055. }
  1056. static void bbr_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
  1057. ngtcp2_tstamp ts) {
  1058. ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
  1059. bbr_on_init(bbr, cstat, ts);
  1060. }
  1061. void ngtcp2_cc_bbr_init(ngtcp2_cc_bbr *bbr, ngtcp2_log *log,
  1062. ngtcp2_conn_stat *cstat, ngtcp2_rst *rst,
  1063. ngtcp2_tstamp initial_ts, ngtcp2_rand rand,
  1064. const ngtcp2_rand_ctx *rand_ctx) {
  1065. memset(bbr, 0, sizeof(*bbr));
  1066. bbr->cc.log = log;
  1067. bbr->cc.on_pkt_lost = bbr_cc_on_pkt_lost;
  1068. bbr->cc.congestion_event = bbr_cc_congestion_event;
  1069. bbr->cc.on_spurious_congestion = bbr_cc_on_spurious_congestion;
  1070. bbr->cc.on_persistent_congestion = bbr_cc_on_persistent_congestion;
  1071. bbr->cc.on_ack_recv = bbr_cc_on_ack_recv;
  1072. bbr->cc.on_pkt_sent = bbr_cc_on_pkt_sent;
  1073. bbr->cc.reset = bbr_cc_reset;
  1074. bbr->rst = rst;
  1075. bbr->rand = rand;
  1076. bbr->rand_ctx = *rand_ctx;
  1077. bbr->initial_cwnd = cstat->cwnd;
  1078. bbr_on_init(bbr, cstat, initial_ts);
  1079. }