protocol-quic 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (343) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/ext/ngtcp2/AUTHORS +44 -0
  4. data/ext/ngtcp2/CMakeLists.txt +431 -0
  5. data/ext/ngtcp2/CMakeOptions.txt +17 -0
  6. data/ext/ngtcp2/COPYING +22 -0
  7. data/ext/ngtcp2/ChangeLog +0 -0
  8. data/ext/ngtcp2/Makefile.am +60 -0
  9. data/ext/ngtcp2/NEWS +0 -0
  10. data/ext/ngtcp2/README +1 -0
  11. data/ext/ngtcp2/README.rst +258 -0
  12. data/ext/ngtcp2/ci/build_boringssl.sh +10 -0
  13. data/ext/ngtcp2/ci/build_nghttp3.sh +9 -0
  14. data/ext/ngtcp2/ci/build_openssl1.sh +8 -0
  15. data/ext/ngtcp2/ci/build_openssl1_cross.sh +9 -0
  16. data/ext/ngtcp2/ci/build_openssl3.sh +8 -0
  17. data/ext/ngtcp2/ci/build_picotls.sh +26 -0
  18. data/ext/ngtcp2/ci/build_wolfssl.sh +9 -0
  19. data/ext/ngtcp2/ci/gen-certificate.sh +8 -0
  20. data/ext/ngtcp2/cmake/ExtractValidFlags.cmake +31 -0
  21. data/ext/ngtcp2/cmake/FindCUnit.cmake +40 -0
  22. data/ext/ngtcp2/cmake/FindJemalloc.cmake +40 -0
  23. data/ext/ngtcp2/cmake/FindLibev.cmake +38 -0
  24. data/ext/ngtcp2/cmake/FindLibnghttp3.cmake +41 -0
  25. data/ext/ngtcp2/cmake/Findwolfssl.cmake +41 -0
  26. data/ext/ngtcp2/cmake/Version.cmake +11 -0
  27. data/ext/ngtcp2/cmakeconfig.h.in +36 -0
  28. data/ext/ngtcp2/configure.ac +755 -0
  29. data/ext/ngtcp2/crypto/CMakeLists.txt +56 -0
  30. data/ext/ngtcp2/crypto/Makefile.am +49 -0
  31. data/ext/ngtcp2/crypto/boringssl/CMakeLists.txt +64 -0
  32. data/ext/ngtcp2/crypto/boringssl/Makefile.am +39 -0
  33. data/ext/ngtcp2/crypto/boringssl/boringssl.c +630 -0
  34. data/ext/ngtcp2/crypto/boringssl/libngtcp2_crypto_boringssl.pc.in +33 -0
  35. data/ext/ngtcp2/crypto/gnutls/CMakeLists.txt +86 -0
  36. data/ext/ngtcp2/crypto/gnutls/Makefile.am +43 -0
  37. data/ext/ngtcp2/crypto/gnutls/gnutls.c +644 -0
  38. data/ext/ngtcp2/crypto/gnutls/libngtcp2_crypto_gnutls.pc.in +33 -0
  39. data/ext/ngtcp2/crypto/includes/CMakeLists.txt +56 -0
  40. data/ext/ngtcp2/crypto/includes/Makefile.am +45 -0
  41. data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto.h +893 -0
  42. data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_boringssl.h +104 -0
  43. data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_gnutls.h +107 -0
  44. data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_openssl.h +132 -0
  45. data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_picotls.h +246 -0
  46. data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_wolfssl.h +106 -0
  47. data/ext/ngtcp2/crypto/openssl/CMakeLists.txt +86 -0
  48. data/ext/ngtcp2/crypto/openssl/Makefile.am +43 -0
  49. data/ext/ngtcp2/crypto/openssl/libngtcp2_crypto_openssl.pc.in +33 -0
  50. data/ext/ngtcp2/crypto/openssl/openssl.c +807 -0
  51. data/ext/ngtcp2/crypto/picotls/CMakeLists.txt +65 -0
  52. data/ext/ngtcp2/crypto/picotls/Makefile.am +39 -0
  53. data/ext/ngtcp2/crypto/picotls/libngtcp2_crypto_picotls.pc.in +33 -0
  54. data/ext/ngtcp2/crypto/picotls/picotls.c +707 -0
  55. data/ext/ngtcp2/crypto/shared.c +1431 -0
  56. data/ext/ngtcp2/crypto/shared.h +350 -0
  57. data/ext/ngtcp2/crypto/wolfssl/CMakeLists.txt +84 -0
  58. data/ext/ngtcp2/crypto/wolfssl/Makefile.am +43 -0
  59. data/ext/ngtcp2/crypto/wolfssl/libngtcp2_crypto_wolfssl.pc.in +33 -0
  60. data/ext/ngtcp2/crypto/wolfssl/wolfssl.c +534 -0
  61. data/ext/ngtcp2/doc/Makefile.am +65 -0
  62. data/ext/ngtcp2/doc/make.bat +35 -0
  63. data/ext/ngtcp2/doc/mkapiref.py +356 -0
  64. data/ext/ngtcp2/doc/source/conf.py.in +94 -0
  65. data/ext/ngtcp2/doc/source/index.rst +22 -0
  66. data/ext/ngtcp2/doc/source/programmers-guide.rst +476 -0
  67. data/ext/ngtcp2/docker/Dockerfile +39 -0
  68. data/ext/ngtcp2/examples/CMakeLists.txt +361 -0
  69. data/ext/ngtcp2/examples/Makefile.am +228 -0
  70. data/ext/ngtcp2/examples/client.cc +3049 -0
  71. data/ext/ngtcp2/examples/client.h +192 -0
  72. data/ext/ngtcp2/examples/client_base.cc +202 -0
  73. data/ext/ngtcp2/examples/client_base.h +213 -0
  74. data/ext/ngtcp2/examples/debug.cc +298 -0
  75. data/ext/ngtcp2/examples/debug.h +124 -0
  76. data/ext/ngtcp2/examples/examplestest.cc +84 -0
  77. data/ext/ngtcp2/examples/gtlssimpleclient.c +720 -0
  78. data/ext/ngtcp2/examples/h09client.cc +2601 -0
  79. data/ext/ngtcp2/examples/h09client.h +196 -0
  80. data/ext/ngtcp2/examples/h09server.cc +3024 -0
  81. data/ext/ngtcp2/examples/h09server.h +237 -0
  82. data/ext/ngtcp2/examples/http.cc +138 -0
  83. data/ext/ngtcp2/examples/http.h +44 -0
  84. data/ext/ngtcp2/examples/network.h +80 -0
  85. data/ext/ngtcp2/examples/server.cc +3731 -0
  86. data/ext/ngtcp2/examples/server.h +256 -0
  87. data/ext/ngtcp2/examples/server_base.cc +58 -0
  88. data/ext/ngtcp2/examples/server_base.h +195 -0
  89. data/ext/ngtcp2/examples/shared.cc +385 -0
  90. data/ext/ngtcp2/examples/shared.h +96 -0
  91. data/ext/ngtcp2/examples/simpleclient.c +683 -0
  92. data/ext/ngtcp2/examples/template.h +71 -0
  93. data/ext/ngtcp2/examples/tests/README.rst +60 -0
  94. data/ext/ngtcp2/examples/tests/__init__.py +0 -0
  95. data/ext/ngtcp2/examples/tests/config.ini.in +32 -0
  96. data/ext/ngtcp2/examples/tests/conftest.py +28 -0
  97. data/ext/ngtcp2/examples/tests/ngtcp2test/__init__.py +6 -0
  98. data/ext/ngtcp2/examples/tests/ngtcp2test/certs.py +476 -0
  99. data/ext/ngtcp2/examples/tests/ngtcp2test/client.py +187 -0
  100. data/ext/ngtcp2/examples/tests/ngtcp2test/env.py +191 -0
  101. data/ext/ngtcp2/examples/tests/ngtcp2test/log.py +101 -0
  102. data/ext/ngtcp2/examples/tests/ngtcp2test/server.py +137 -0
  103. data/ext/ngtcp2/examples/tests/ngtcp2test/tls.py +983 -0
  104. data/ext/ngtcp2/examples/tests/test_01_handshake.py +30 -0
  105. data/ext/ngtcp2/examples/tests/test_02_resume.py +46 -0
  106. data/ext/ngtcp2/examples/tests/test_03_earlydata.py +56 -0
  107. data/ext/ngtcp2/examples/tests/test_04_clientcert.py +57 -0
  108. data/ext/ngtcp2/examples/tests/test_05_ciphers.py +46 -0
  109. data/ext/ngtcp2/examples/tls_client_context.h +52 -0
  110. data/ext/ngtcp2/examples/tls_client_context_boringssl.cc +126 -0
  111. data/ext/ngtcp2/examples/tls_client_context_boringssl.h +49 -0
  112. data/ext/ngtcp2/examples/tls_client_context_gnutls.cc +74 -0
  113. data/ext/ngtcp2/examples/tls_client_context_gnutls.h +50 -0
  114. data/ext/ngtcp2/examples/tls_client_context_openssl.cc +137 -0
  115. data/ext/ngtcp2/examples/tls_client_context_openssl.h +49 -0
  116. data/ext/ngtcp2/examples/tls_client_context_picotls.cc +158 -0
  117. data/ext/ngtcp2/examples/tls_client_context_picotls.h +53 -0
  118. data/ext/ngtcp2/examples/tls_client_context_wolfssl.cc +177 -0
  119. data/ext/ngtcp2/examples/tls_client_context_wolfssl.h +51 -0
  120. data/ext/ngtcp2/examples/tls_client_session.h +52 -0
  121. data/ext/ngtcp2/examples/tls_client_session_boringssl.cc +110 -0
  122. data/ext/ngtcp2/examples/tls_client_session_boringssl.h +52 -0
  123. data/ext/ngtcp2/examples/tls_client_session_gnutls.cc +190 -0
  124. data/ext/ngtcp2/examples/tls_client_session_gnutls.h +52 -0
  125. data/ext/ngtcp2/examples/tls_client_session_openssl.cc +113 -0
  126. data/ext/ngtcp2/examples/tls_client_session_openssl.h +52 -0
  127. data/ext/ngtcp2/examples/tls_client_session_picotls.cc +147 -0
  128. data/ext/ngtcp2/examples/tls_client_session_picotls.h +52 -0
  129. data/ext/ngtcp2/examples/tls_client_session_wolfssl.cc +160 -0
  130. data/ext/ngtcp2/examples/tls_client_session_wolfssl.h +52 -0
  131. data/ext/ngtcp2/examples/tls_server_context.h +52 -0
  132. data/ext/ngtcp2/examples/tls_server_context_boringssl.cc +257 -0
  133. data/ext/ngtcp2/examples/tls_server_context_boringssl.h +54 -0
  134. data/ext/ngtcp2/examples/tls_server_context_gnutls.cc +99 -0
  135. data/ext/ngtcp2/examples/tls_server_context_gnutls.h +59 -0
  136. data/ext/ngtcp2/examples/tls_server_context_openssl.cc +338 -0
  137. data/ext/ngtcp2/examples/tls_server_context_openssl.h +54 -0
  138. data/ext/ngtcp2/examples/tls_server_context_picotls.cc +321 -0
  139. data/ext/ngtcp2/examples/tls_server_context_picotls.h +58 -0
  140. data/ext/ngtcp2/examples/tls_server_context_wolfssl.cc +284 -0
  141. data/ext/ngtcp2/examples/tls_server_context_wolfssl.h +55 -0
  142. data/ext/ngtcp2/examples/tls_server_session.h +52 -0
  143. data/ext/ngtcp2/examples/tls_server_session_boringssl.cc +84 -0
  144. data/ext/ngtcp2/examples/tls_server_session_boringssl.h +47 -0
  145. data/ext/ngtcp2/examples/tls_server_session_gnutls.cc +155 -0
  146. data/ext/ngtcp2/examples/tls_server_session_gnutls.h +46 -0
  147. data/ext/ngtcp2/examples/tls_server_session_openssl.cc +54 -0
  148. data/ext/ngtcp2/examples/tls_server_session_openssl.h +47 -0
  149. data/ext/ngtcp2/examples/tls_server_session_picotls.cc +70 -0
  150. data/ext/ngtcp2/examples/tls_server_session_picotls.h +47 -0
  151. data/ext/ngtcp2/examples/tls_server_session_wolfssl.cc +55 -0
  152. data/ext/ngtcp2/examples/tls_server_session_wolfssl.h +47 -0
  153. data/ext/ngtcp2/examples/tls_session_base_gnutls.cc +87 -0
  154. data/ext/ngtcp2/examples/tls_session_base_gnutls.h +51 -0
  155. data/ext/ngtcp2/examples/tls_session_base_openssl.cc +54 -0
  156. data/ext/ngtcp2/examples/tls_session_base_openssl.h +52 -0
  157. data/ext/ngtcp2/examples/tls_session_base_picotls.cc +56 -0
  158. data/ext/ngtcp2/examples/tls_session_base_picotls.h +54 -0
  159. data/ext/ngtcp2/examples/tls_session_base_wolfssl.cc +54 -0
  160. data/ext/ngtcp2/examples/tls_session_base_wolfssl.h +54 -0
  161. data/ext/ngtcp2/examples/tls_shared_picotls.cc +59 -0
  162. data/ext/ngtcp2/examples/tls_shared_picotls.h +36 -0
  163. data/ext/ngtcp2/examples/util.cc +646 -0
  164. data/ext/ngtcp2/examples/util.h +361 -0
  165. data/ext/ngtcp2/examples/util_gnutls.cc +136 -0
  166. data/ext/ngtcp2/examples/util_openssl.cc +131 -0
  167. data/ext/ngtcp2/examples/util_test.cc +237 -0
  168. data/ext/ngtcp2/examples/util_test.h +45 -0
  169. data/ext/ngtcp2/examples/util_wolfssl.cc +130 -0
  170. data/ext/ngtcp2/fuzz/corpus/decode_frame/ack +0 -0
  171. data/ext/ngtcp2/fuzz/corpus/decode_frame/ack_ecn +0 -0
  172. data/ext/ngtcp2/fuzz/corpus/decode_frame/connection_close +0 -0
  173. data/ext/ngtcp2/fuzz/corpus/decode_frame/crypto +1 -0
  174. data/ext/ngtcp2/fuzz/corpus/decode_frame/data_blocked +1 -0
  175. data/ext/ngtcp2/fuzz/corpus/decode_frame/datagram +1 -0
  176. data/ext/ngtcp2/fuzz/corpus/decode_frame/datagram_len +1 -0
  177. data/ext/ngtcp2/fuzz/corpus/decode_frame/max_data +1 -0
  178. data/ext/ngtcp2/fuzz/corpus/decode_frame/max_stream_data +0 -0
  179. data/ext/ngtcp2/fuzz/corpus/decode_frame/max_streams +0 -0
  180. data/ext/ngtcp2/fuzz/corpus/decode_frame/new_connection_id +1 -0
  181. data/ext/ngtcp2/fuzz/corpus/decode_frame/new_token +1 -0
  182. data/ext/ngtcp2/fuzz/corpus/decode_frame/path_challenge +1 -0
  183. data/ext/ngtcp2/fuzz/corpus/decode_frame/path_response +1 -0
  184. data/ext/ngtcp2/fuzz/corpus/decode_frame/reset_stream +0 -0
  185. data/ext/ngtcp2/fuzz/corpus/decode_frame/retire_connection_id +1 -0
  186. data/ext/ngtcp2/fuzz/corpus/decode_frame/stop_sending +0 -0
  187. data/ext/ngtcp2/fuzz/corpus/decode_frame/stream +0 -0
  188. data/ext/ngtcp2/fuzz/corpus/decode_frame/stream_data_blocked +0 -0
  189. data/ext/ngtcp2/fuzz/corpus/decode_frame/stream_len +0 -0
  190. data/ext/ngtcp2/fuzz/corpus/decode_frame/streams_blocked +0 -0
  191. data/ext/ngtcp2/fuzz/corpus/ksl/random +0 -0
  192. data/ext/ngtcp2/fuzz/decode_frame.cc +25 -0
  193. data/ext/ngtcp2/fuzz/ksl.cc +77 -0
  194. data/ext/ngtcp2/interop/Dockerfile +39 -0
  195. data/ext/ngtcp2/interop/run_endpoint.sh +93 -0
  196. data/ext/ngtcp2/lib/CMakeLists.txt +110 -0
  197. data/ext/ngtcp2/lib/Makefile.am +122 -0
  198. data/ext/ngtcp2/lib/includes/CMakeLists.txt +4 -0
  199. data/ext/ngtcp2/lib/includes/Makefile.am +25 -0
  200. data/ext/ngtcp2/lib/includes/ngtcp2/ngtcp2.h +5843 -0
  201. data/ext/ngtcp2/lib/includes/ngtcp2/version.h.in +51 -0
  202. data/ext/ngtcp2/lib/libngtcp2.pc.in +33 -0
  203. data/ext/ngtcp2/lib/ngtcp2_acktr.c +335 -0
  204. data/ext/ngtcp2/lib/ngtcp2_acktr.h +221 -0
  205. data/ext/ngtcp2/lib/ngtcp2_addr.c +117 -0
  206. data/ext/ngtcp2/lib/ngtcp2_addr.h +69 -0
  207. data/ext/ngtcp2/lib/ngtcp2_balloc.c +90 -0
  208. data/ext/ngtcp2/lib/ngtcp2_balloc.h +91 -0
  209. data/ext/ngtcp2/lib/ngtcp2_bbr.c +693 -0
  210. data/ext/ngtcp2/lib/ngtcp2_bbr.h +157 -0
  211. data/ext/ngtcp2/lib/ngtcp2_bbr2.c +1490 -0
  212. data/ext/ngtcp2/lib/ngtcp2_bbr2.h +149 -0
  213. data/ext/ngtcp2/lib/ngtcp2_buf.c +56 -0
  214. data/ext/ngtcp2/lib/ngtcp2_buf.h +108 -0
  215. data/ext/ngtcp2/lib/ngtcp2_cc.c +616 -0
  216. data/ext/ngtcp2/lib/ngtcp2_cc.h +422 -0
  217. data/ext/ngtcp2/lib/ngtcp2_cid.c +147 -0
  218. data/ext/ngtcp2/lib/ngtcp2_cid.h +175 -0
  219. data/ext/ngtcp2/lib/ngtcp2_conn.c +13731 -0
  220. data/ext/ngtcp2/lib/ngtcp2_conn.h +1119 -0
  221. data/ext/ngtcp2/lib/ngtcp2_conn_stat.h +131 -0
  222. data/ext/ngtcp2/lib/ngtcp2_conv.c +291 -0
  223. data/ext/ngtcp2/lib/ngtcp2_conv.h +208 -0
  224. data/ext/ngtcp2/lib/ngtcp2_crypto.c +895 -0
  225. data/ext/ngtcp2/lib/ngtcp2_crypto.h +148 -0
  226. data/ext/ngtcp2/lib/ngtcp2_err.c +154 -0
  227. data/ext/ngtcp2/lib/ngtcp2_err.h +34 -0
  228. data/ext/ngtcp2/lib/ngtcp2_gaptr.c +167 -0
  229. data/ext/ngtcp2/lib/ngtcp2_gaptr.h +98 -0
  230. data/ext/ngtcp2/lib/ngtcp2_idtr.c +79 -0
  231. data/ext/ngtcp2/lib/ngtcp2_idtr.h +89 -0
  232. data/ext/ngtcp2/lib/ngtcp2_ksl.c +819 -0
  233. data/ext/ngtcp2/lib/ngtcp2_ksl.h +345 -0
  234. data/ext/ngtcp2/lib/ngtcp2_log.c +822 -0
  235. data/ext/ngtcp2/lib/ngtcp2_log.h +123 -0
  236. data/ext/ngtcp2/lib/ngtcp2_macro.h +58 -0
  237. data/ext/ngtcp2/lib/ngtcp2_map.c +336 -0
  238. data/ext/ngtcp2/lib/ngtcp2_map.h +136 -0
  239. data/ext/ngtcp2/lib/ngtcp2_mem.c +113 -0
  240. data/ext/ngtcp2/lib/ngtcp2_mem.h +72 -0
  241. data/ext/ngtcp2/lib/ngtcp2_net.h +136 -0
  242. data/ext/ngtcp2/lib/ngtcp2_objalloc.c +40 -0
  243. data/ext/ngtcp2/lib/ngtcp2_objalloc.h +140 -0
  244. data/ext/ngtcp2/lib/ngtcp2_opl.c +46 -0
  245. data/ext/ngtcp2/lib/ngtcp2_opl.h +65 -0
  246. data/ext/ngtcp2/lib/ngtcp2_path.c +77 -0
  247. data/ext/ngtcp2/lib/ngtcp2_path.h +49 -0
  248. data/ext/ngtcp2/lib/ngtcp2_pkt.c +2527 -0
  249. data/ext/ngtcp2/lib/ngtcp2_pkt.h +1235 -0
  250. data/ext/ngtcp2/lib/ngtcp2_pmtud.c +160 -0
  251. data/ext/ngtcp2/lib/ngtcp2_pmtud.h +123 -0
  252. data/ext/ngtcp2/lib/ngtcp2_ppe.c +230 -0
  253. data/ext/ngtcp2/lib/ngtcp2_ppe.h +153 -0
  254. data/ext/ngtcp2/lib/ngtcp2_pq.c +164 -0
  255. data/ext/ngtcp2/lib/ngtcp2_pq.h +126 -0
  256. data/ext/ngtcp2/lib/ngtcp2_pv.c +172 -0
  257. data/ext/ngtcp2/lib/ngtcp2_pv.h +194 -0
  258. data/ext/ngtcp2/lib/ngtcp2_qlog.c +1219 -0
  259. data/ext/ngtcp2/lib/ngtcp2_qlog.h +161 -0
  260. data/ext/ngtcp2/lib/ngtcp2_range.c +61 -0
  261. data/ext/ngtcp2/lib/ngtcp2_range.h +80 -0
  262. data/ext/ngtcp2/lib/ngtcp2_rcvry.h +40 -0
  263. data/ext/ngtcp2/lib/ngtcp2_ringbuf.c +121 -0
  264. data/ext/ngtcp2/lib/ngtcp2_ringbuf.h +132 -0
  265. data/ext/ngtcp2/lib/ngtcp2_rob.c +319 -0
  266. data/ext/ngtcp2/lib/ngtcp2_rob.h +197 -0
  267. data/ext/ngtcp2/lib/ngtcp2_rst.c +138 -0
  268. data/ext/ngtcp2/lib/ngtcp2_rst.h +86 -0
  269. data/ext/ngtcp2/lib/ngtcp2_rtb.c +1676 -0
  270. data/ext/ngtcp2/lib/ngtcp2_rtb.h +468 -0
  271. data/ext/ngtcp2/lib/ngtcp2_str.c +233 -0
  272. data/ext/ngtcp2/lib/ngtcp2_str.h +94 -0
  273. data/ext/ngtcp2/lib/ngtcp2_strm.c +698 -0
  274. data/ext/ngtcp2/lib/ngtcp2_strm.h +310 -0
  275. data/ext/ngtcp2/lib/ngtcp2_unreachable.c +71 -0
  276. data/ext/ngtcp2/lib/ngtcp2_unreachable.h +46 -0
  277. data/ext/ngtcp2/lib/ngtcp2_vec.c +243 -0
  278. data/ext/ngtcp2/lib/ngtcp2_vec.h +120 -0
  279. data/ext/ngtcp2/lib/ngtcp2_version.c +39 -0
  280. data/ext/ngtcp2/lib/ngtcp2_window_filter.c +99 -0
  281. data/ext/ngtcp2/lib/ngtcp2_window_filter.h +65 -0
  282. data/ext/ngtcp2/m4/ax_check_compile_flag.m4 +74 -0
  283. data/ext/ngtcp2/m4/ax_cxx_compile_stdcxx.m4 +1009 -0
  284. data/ext/ngtcp2/tests/CMakeLists.txt +68 -0
  285. data/ext/ngtcp2/tests/Makefile.am +94 -0
  286. data/ext/ngtcp2/tests/main.c +358 -0
  287. data/ext/ngtcp2/tests/ngtcp2_acktr_test.c +367 -0
  288. data/ext/ngtcp2/tests/ngtcp2_acktr_test.h +37 -0
  289. data/ext/ngtcp2/tests/ngtcp2_conn_test.c +9821 -0
  290. data/ext/ngtcp2/tests/ngtcp2_conn_test.h +104 -0
  291. data/ext/ngtcp2/tests/ngtcp2_conv_test.c +430 -0
  292. data/ext/ngtcp2/tests/ngtcp2_conv_test.h +46 -0
  293. data/ext/ngtcp2/tests/ngtcp2_crypto_test.c +667 -0
  294. data/ext/ngtcp2/tests/ngtcp2_crypto_test.h +35 -0
  295. data/ext/ngtcp2/tests/ngtcp2_gaptr_test.c +127 -0
  296. data/ext/ngtcp2/tests/ngtcp2_gaptr_test.h +36 -0
  297. data/ext/ngtcp2/tests/ngtcp2_idtr_test.c +79 -0
  298. data/ext/ngtcp2/tests/ngtcp2_idtr_test.h +34 -0
  299. data/ext/ngtcp2/tests/ngtcp2_ksl_test.c +502 -0
  300. data/ext/ngtcp2/tests/ngtcp2_ksl_test.h +39 -0
  301. data/ext/ngtcp2/tests/ngtcp2_map_test.c +206 -0
  302. data/ext/ngtcp2/tests/ngtcp2_map_test.h +38 -0
  303. data/ext/ngtcp2/tests/ngtcp2_pkt_test.c +1645 -0
  304. data/ext/ngtcp2/tests/ngtcp2_pkt_test.h +68 -0
  305. data/ext/ngtcp2/tests/ngtcp2_pmtud_test.c +153 -0
  306. data/ext/ngtcp2/tests/ngtcp2_pmtud_test.h +34 -0
  307. data/ext/ngtcp2/tests/ngtcp2_pv_test.c +129 -0
  308. data/ext/ngtcp2/tests/ngtcp2_pv_test.h +35 -0
  309. data/ext/ngtcp2/tests/ngtcp2_range_test.c +105 -0
  310. data/ext/ngtcp2/tests/ngtcp2_range_test.h +36 -0
  311. data/ext/ngtcp2/tests/ngtcp2_ringbuf_test.c +91 -0
  312. data/ext/ngtcp2/tests/ngtcp2_ringbuf_test.h +35 -0
  313. data/ext/ngtcp2/tests/ngtcp2_rob_test.c +552 -0
  314. data/ext/ngtcp2/tests/ngtcp2_rob_test.h +37 -0
  315. data/ext/ngtcp2/tests/ngtcp2_rtb_test.c +470 -0
  316. data/ext/ngtcp2/tests/ngtcp2_rtb_test.h +38 -0
  317. data/ext/ngtcp2/tests/ngtcp2_str_test.c +96 -0
  318. data/ext/ngtcp2/tests/ngtcp2_str_test.h +36 -0
  319. data/ext/ngtcp2/tests/ngtcp2_strm_test.c +575 -0
  320. data/ext/ngtcp2/tests/ngtcp2_strm_test.h +36 -0
  321. data/ext/ngtcp2/tests/ngtcp2_test_helper.c +404 -0
  322. data/ext/ngtcp2/tests/ngtcp2_test_helper.h +191 -0
  323. data/ext/ngtcp2/tests/ngtcp2_vec_test.c +426 -0
  324. data/ext/ngtcp2/tests/ngtcp2_vec_test.h +36 -0
  325. data/ext/ngtcp2/third-party/CMakeLists.txt +34 -0
  326. data/ext/ngtcp2/third-party/Makefile.am +31 -0
  327. data/ext/ngtcp2/third-party/http-parser/AUTHORS +68 -0
  328. data/ext/ngtcp2/third-party/http-parser/LICENSE-MIT +23 -0
  329. data/ext/ngtcp2/third-party/http-parser/Makefile +157 -0
  330. data/ext/ngtcp2/third-party/http-parser/README.md +246 -0
  331. data/ext/ngtcp2/third-party/http-parser/bench.c +111 -0
  332. data/ext/ngtcp2/third-party/http-parser/contrib/parsertrace.c +160 -0
  333. data/ext/ngtcp2/third-party/http-parser/contrib/url_parser.c +47 -0
  334. data/ext/ngtcp2/third-party/http-parser/http_parser.c +2419 -0
  335. data/ext/ngtcp2/third-party/http-parser/http_parser.gyp +111 -0
  336. data/ext/ngtcp2/third-party/http-parser/http_parser.h +431 -0
  337. data/ext/ngtcp2/third-party/http-parser/test.c +4411 -0
  338. data/lib/protocol/quic/version.rb +10 -0
  339. data/lib/protocol/quic.rb +9 -0
  340. data/license.md +21 -0
  341. data.tar.gz.sig +1 -0
  342. metadata +424 -0
  343. metadata.gz.sig +1 -0
@@ -0,0 +1,1490 @@
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_bbr2.h"
26
+
27
+ #include <assert.h>
28
+
29
+ #include "ngtcp2_log.h"
30
+ #include "ngtcp2_macro.h"
31
+ #include "ngtcp2_mem.h"
32
+ #include "ngtcp2_rcvry.h"
33
+ #include "ngtcp2_rst.h"
34
+ #include "ngtcp2_conn_stat.h"
35
+
36
+ #define NGTCP2_BBR_MAX_BW_FILTERLEN 2
37
+
38
+ #define NGTCP2_BBR_EXTRA_ACKED_FILTERLEN 10
39
+
40
+ #define NGTCP2_BBR_STARTUP_PACING_GAIN ((double)2.77)
41
+
42
+ #define NGTCP2_BBR_STARTUP_CWND_GAIN 2
43
+
44
+ #define NGTCP2_BBR_PROBE_RTT_CWND_GAIN ((double)0.5)
45
+
46
+ #define NGTCP2_BBR_BETA_NUMER 7
47
+ #define NGTCP2_BBR_BETA_DENOM 10
48
+
49
+ #define NGTCP2_BBR_LOSS_THRESH_NUMER 2
50
+ #define NGTCP2_BBR_LOSS_THRESH_DENOM 100
51
+
52
+ #define NGTCP2_BBR_HEADROOM_NUMER 15
53
+ #define NGTCP2_BBR_HEADROOM_DENOM 100
54
+
55
+ #define NGTCP2_BBR_PROBE_RTT_INTERVAL (5 * NGTCP2_SECONDS)
56
+ #define NGTCP2_BBR_MIN_RTT_FILTERLEN (10 * NGTCP2_SECONDS)
57
+
58
+ #define NGTCP2_BBR_PROBE_RTT_DURATION (200 * NGTCP2_MILLISECONDS)
59
+
60
+ #define NGTCP2_BBR_PACING_MARGIN_PERCENT 1
61
+
62
+ static void bbr_on_init(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
63
+ ngtcp2_tstamp initial_ts);
64
+
65
+ static void bbr_on_transmit(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
66
+ ngtcp2_tstamp ts);
67
+
68
+ static void bbr_reset_congestion_signals(ngtcp2_bbr2_cc *bbr);
69
+
70
+ static void bbr_reset_lower_bounds(ngtcp2_bbr2_cc *bbr);
71
+
72
+ static void bbr_init_round_counting(ngtcp2_bbr2_cc *bbr);
73
+
74
+ static void bbr_init_full_pipe(ngtcp2_bbr2_cc *bbr);
75
+
76
+ static void bbr_init_pacing_rate(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat);
77
+
78
+ static void bbr_set_pacing_rate_with_gain(ngtcp2_bbr2_cc *bbr,
79
+ ngtcp2_conn_stat *cstat,
80
+ double pacing_gain);
81
+
82
+ static void bbr_set_pacing_rate(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat);
83
+
84
+ static void bbr_enter_startup(ngtcp2_bbr2_cc *bbr);
85
+
86
+ static void bbr_check_startup_done(ngtcp2_bbr2_cc *bbr,
87
+ const ngtcp2_cc_ack *ack);
88
+
89
+ static void bbr_update_on_ack(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
90
+ const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
91
+
92
+ static void bbr_update_model_and_state(ngtcp2_bbr2_cc *cc,
93
+ ngtcp2_conn_stat *cstat,
94
+ const ngtcp2_cc_ack *ack,
95
+ ngtcp2_tstamp ts);
96
+
97
+ static void bbr_update_control_parameters(ngtcp2_bbr2_cc *cc,
98
+ ngtcp2_conn_stat *cstat,
99
+ const ngtcp2_cc_ack *ack);
100
+
101
+ static void bbr_update_on_loss(ngtcp2_bbr2_cc *cc, ngtcp2_conn_stat *cstat,
102
+ const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
103
+
104
+ static void bbr_update_latest_delivery_signals(ngtcp2_bbr2_cc *bbr,
105
+ ngtcp2_conn_stat *cstat);
106
+
107
+ static void bbr_advance_latest_delivery_signals(ngtcp2_bbr2_cc *bbr,
108
+ ngtcp2_conn_stat *cstat);
109
+
110
+ static void bbr_update_congestion_signals(ngtcp2_bbr2_cc *bbr,
111
+ ngtcp2_conn_stat *cstat,
112
+ const ngtcp2_cc_ack *ack);
113
+
114
+ static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_bbr2_cc *bbr,
115
+ ngtcp2_conn_stat *cstat);
116
+
117
+ static void bbr_init_lower_bounds(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat);
118
+
119
+ static void bbr_loss_lower_bounds(ngtcp2_bbr2_cc *bbr);
120
+
121
+ static void bbr_bound_bw_for_model(ngtcp2_bbr2_cc *bbr);
122
+
123
+ static void bbr_update_max_bw(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
124
+ const ngtcp2_cc_ack *ack);
125
+
126
+ static void bbr_update_round(ngtcp2_bbr2_cc *bbr, const ngtcp2_cc_ack *ack);
127
+
128
+ static void bbr_start_round(ngtcp2_bbr2_cc *bbr);
129
+
130
+ static int bbr_is_in_probe_bw_state(ngtcp2_bbr2_cc *bbr);
131
+
132
+ static void bbr_update_ack_aggregation(ngtcp2_bbr2_cc *bbr,
133
+ ngtcp2_conn_stat *cstat,
134
+ const ngtcp2_cc_ack *ack,
135
+ ngtcp2_tstamp ts);
136
+
137
+ static void bbr_enter_drain(ngtcp2_bbr2_cc *bbr);
138
+
139
+ static void bbr_check_drain(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
140
+ ngtcp2_tstamp ts);
141
+
142
+ static void bbr_enter_probe_bw(ngtcp2_bbr2_cc *bbr, ngtcp2_tstamp ts);
143
+
144
+ static void bbr_start_probe_bw_down(ngtcp2_bbr2_cc *bbr, ngtcp2_tstamp ts);
145
+
146
+ static void bbr_start_probe_bw_cruise(ngtcp2_bbr2_cc *bbr);
147
+
148
+ static void bbr_start_probe_bw_refill(ngtcp2_bbr2_cc *bbr);
149
+
150
+ static void bbr_start_probe_bw_up(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
151
+ ngtcp2_tstamp ts);
152
+
153
+ static void bbr_update_probe_bw_cycle_phase(ngtcp2_bbr2_cc *bbr,
154
+ ngtcp2_conn_stat *cstat,
155
+ const ngtcp2_cc_ack *ack,
156
+ ngtcp2_tstamp ts);
157
+
158
+ static int bbr_check_time_to_cruise(ngtcp2_bbr2_cc *bbr,
159
+ ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts);
160
+
161
+ static int bbr_has_elapsed_in_phase(ngtcp2_bbr2_cc *bbr,
162
+ ngtcp2_duration interval, ngtcp2_tstamp ts);
163
+
164
+ static uint64_t bbr_inflight_with_headroom(ngtcp2_bbr2_cc *bbr,
165
+ ngtcp2_conn_stat *cstat);
166
+
167
+ static void bbr_raise_inflight_hi_slope(ngtcp2_bbr2_cc *bbr,
168
+ ngtcp2_conn_stat *cstat);
169
+
170
+ static void bbr_probe_inflight_hi_upward(ngtcp2_bbr2_cc *bbr,
171
+ ngtcp2_conn_stat *cstat,
172
+ const ngtcp2_cc_ack *ack);
173
+
174
+ static void bbr_adapt_upper_bounds(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
175
+ const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
176
+
177
+ static int bbr_check_time_to_probe_bw(ngtcp2_bbr2_cc *bbr,
178
+ ngtcp2_conn_stat *cstat,
179
+ ngtcp2_tstamp ts);
180
+
181
+ static void bbr_pick_probe_wait(ngtcp2_bbr2_cc *bbr);
182
+
183
+ static int bbr_is_reno_coexistence_probe_time(ngtcp2_bbr2_cc *bbr,
184
+ ngtcp2_conn_stat *cstat);
185
+
186
+ static uint64_t bbr_target_inflight(ngtcp2_bbr2_cc *bbr,
187
+ ngtcp2_conn_stat *cstat);
188
+
189
+ static int bbr_check_inflight_too_high(ngtcp2_bbr2_cc *bbr,
190
+ ngtcp2_conn_stat *cstat,
191
+ ngtcp2_tstamp ts);
192
+
193
+ static int is_inflight_too_high(const ngtcp2_rs *rs);
194
+
195
+ static void bbr_handle_inflight_too_high(ngtcp2_bbr2_cc *bbr,
196
+ ngtcp2_conn_stat *cstat,
197
+ const ngtcp2_rs *rs, ngtcp2_tstamp ts);
198
+
199
+ static void bbr_handle_lost_packet(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
200
+ const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
201
+
202
+ static uint64_t bbr_inflight_hi_from_lost_packet(ngtcp2_bbr2_cc *bbr,
203
+ const ngtcp2_rs *rs,
204
+ const ngtcp2_cc_pkt *pkt);
205
+
206
+ static void bbr_update_min_rtt(ngtcp2_bbr2_cc *bbr, const ngtcp2_cc_ack *ack,
207
+ ngtcp2_tstamp ts);
208
+
209
+ static void bbr_check_probe_rtt(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
210
+ ngtcp2_tstamp ts);
211
+
212
+ static void bbr_enter_probe_rtt(ngtcp2_bbr2_cc *bbr);
213
+
214
+ static void bbr_handle_probe_rtt(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
215
+ ngtcp2_tstamp ts);
216
+
217
+ static void bbr_check_probe_rtt_done(ngtcp2_bbr2_cc *bbr,
218
+ ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts);
219
+
220
+ static void bbr_mark_connection_app_limited(ngtcp2_bbr2_cc *bbr,
221
+ ngtcp2_conn_stat *cstat);
222
+
223
+ static void bbr_exit_probe_rtt(ngtcp2_bbr2_cc *bbr, ngtcp2_tstamp ts);
224
+
225
+ static void bbr_handle_restart_from_idle(ngtcp2_bbr2_cc *bbr,
226
+ ngtcp2_conn_stat *cstat,
227
+ ngtcp2_tstamp ts);
228
+
229
+ static uint64_t bbr_bdp_multiple(ngtcp2_bbr2_cc *bbr, uint64_t bw, double gain);
230
+
231
+ static uint64_t bbr_quantization_budget(ngtcp2_bbr2_cc *bbr,
232
+ ngtcp2_conn_stat *cstat,
233
+ uint64_t inflight);
234
+
235
+ static uint64_t bbr_inflight(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
236
+ uint64_t bw, double gain);
237
+
238
+ static void bbr_update_max_inflight(ngtcp2_bbr2_cc *bbr,
239
+ ngtcp2_conn_stat *cstat);
240
+
241
+ static void bbr_update_offload_budget(ngtcp2_bbr2_cc *bbr,
242
+ ngtcp2_conn_stat *cstat);
243
+
244
+ static uint64_t min_pipe_cwnd(size_t max_udp_payload_size);
245
+
246
+ static void bbr_advance_max_bw_filter(ngtcp2_bbr2_cc *bbr);
247
+
248
+ static void bbr_modulate_cwnd_for_recovery(ngtcp2_bbr2_cc *bbr,
249
+ ngtcp2_conn_stat *cstat,
250
+ const ngtcp2_cc_ack *ack);
251
+
252
+ static void bbr_save_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat);
253
+
254
+ static void bbr_restore_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat);
255
+
256
+ static uint64_t bbr_probe_rtt_cwnd(ngtcp2_bbr2_cc *bbr,
257
+ ngtcp2_conn_stat *cstat);
258
+
259
+ static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_bbr2_cc *bbr,
260
+ ngtcp2_conn_stat *cstat);
261
+
262
+ static void bbr_set_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
263
+ const ngtcp2_cc_ack *ack);
264
+
265
+ static void bbr_bound_cwnd_for_model(ngtcp2_bbr2_cc *bbr,
266
+ ngtcp2_conn_stat *cstat);
267
+
268
+ static void bbr_set_send_quantum(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat);
269
+
270
+ static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
271
+ ngtcp2_tstamp sent_time);
272
+
273
+ static void bbr_handle_recovery(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
274
+ const ngtcp2_cc_ack *ack);
275
+
276
+ static void bbr_on_init(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
277
+ ngtcp2_tstamp initial_ts) {
278
+ ngtcp2_window_filter_init(&bbr->max_bw_filter, NGTCP2_BBR_MAX_BW_FILTERLEN);
279
+ ngtcp2_window_filter_init(&bbr->extra_acked_filter,
280
+ NGTCP2_BBR_EXTRA_ACKED_FILTERLEN);
281
+
282
+ bbr->min_rtt = UINT64_MAX;
283
+ bbr->min_rtt_stamp = initial_ts;
284
+ /* remark: Use UINT64_MAX instead of 0 for consistency. */
285
+ bbr->probe_rtt_done_stamp = UINT64_MAX;
286
+ bbr->probe_rtt_round_done = 0;
287
+ bbr->prior_cwnd = 0;
288
+ bbr->idle_restart = 0;
289
+ bbr->extra_acked_interval_start = initial_ts;
290
+ bbr->extra_acked_delivered = 0;
291
+
292
+ bbr_reset_congestion_signals(bbr);
293
+ bbr_reset_lower_bounds(bbr);
294
+ bbr_init_round_counting(bbr);
295
+ bbr_init_full_pipe(bbr);
296
+ bbr_init_pacing_rate(bbr, cstat);
297
+ bbr_enter_startup(bbr);
298
+
299
+ cstat->send_quantum = cstat->max_tx_udp_payload_size * 10;
300
+
301
+ /* Missing in documentation */
302
+ bbr->loss_round_start = 0;
303
+ bbr->loss_round_delivered = UINT64_MAX;
304
+
305
+ bbr->rounds_since_bw_probe = 0;
306
+
307
+ bbr->max_bw = 0;
308
+ bbr->bw = 0;
309
+
310
+ bbr->cycle_count = 0;
311
+
312
+ bbr->extra_acked = 0;
313
+
314
+ bbr->bytes_lost_in_round = 0;
315
+ bbr->loss_events_in_round = 0;
316
+
317
+ bbr->offload_budget = 0;
318
+
319
+ bbr->probe_up_cnt = UINT64_MAX;
320
+ bbr->cycle_stamp = UINT64_MAX;
321
+ bbr->ack_phase = 0;
322
+ bbr->bw_probe_wait = 0;
323
+ bbr->bw_probe_samples = 0;
324
+ bbr->bw_probe_up_rounds = 0;
325
+ bbr->bw_probe_up_acks = 0;
326
+
327
+ bbr->inflight_hi = UINT64_MAX;
328
+ bbr->bw_hi = UINT64_MAX;
329
+
330
+ bbr->probe_rtt_expired = 0;
331
+ bbr->probe_rtt_min_delay = UINT64_MAX;
332
+ bbr->probe_rtt_min_stamp = initial_ts;
333
+
334
+ bbr->in_loss_recovery = 0;
335
+ bbr->packet_conservation = 0;
336
+
337
+ bbr->max_inflight = 0;
338
+
339
+ bbr->congestion_recovery_start_ts = UINT64_MAX;
340
+ bbr->congestion_recovery_next_round_delivered = 0;
341
+
342
+ bbr->prior_inflight_lo = 0;
343
+ bbr->prior_inflight_hi = 0;
344
+ bbr->prior_bw_lo = 0;
345
+ }
346
+
347
+ static void bbr_reset_congestion_signals(ngtcp2_bbr2_cc *bbr) {
348
+ bbr->loss_in_round = 0;
349
+ bbr->bw_latest = 0;
350
+ bbr->inflight_latest = 0;
351
+ }
352
+
353
+ static void bbr_reset_lower_bounds(ngtcp2_bbr2_cc *bbr) {
354
+ bbr->bw_lo = UINT64_MAX;
355
+ bbr->inflight_lo = UINT64_MAX;
356
+ }
357
+
358
+ static void bbr_init_round_counting(ngtcp2_bbr2_cc *bbr) {
359
+ bbr->next_round_delivered = 0;
360
+ bbr->round_start = 0;
361
+ bbr->round_count = 0;
362
+ }
363
+
364
+ static void bbr_init_full_pipe(ngtcp2_bbr2_cc *bbr) {
365
+ bbr->filled_pipe = 0;
366
+ bbr->full_bw = 0;
367
+ bbr->full_bw_count = 0;
368
+ }
369
+
370
+ static void bbr_check_startup_full_bandwidth(ngtcp2_bbr2_cc *bbr) {
371
+ if (bbr->filled_pipe || !bbr->round_start || bbr->rst->rs.is_app_limited) {
372
+ return;
373
+ }
374
+
375
+ if (bbr->max_bw * 100 >= bbr->full_bw * 125) {
376
+ bbr->full_bw = bbr->max_bw;
377
+ bbr->full_bw_count = 0;
378
+ }
379
+
380
+ ++bbr->full_bw_count;
381
+
382
+ if (bbr->full_bw_count >= 3) {
383
+ bbr->filled_pipe = 1;
384
+
385
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV,
386
+ "bbr2 filled pipe, full_bw=%" PRIu64, bbr->full_bw);
387
+ }
388
+ }
389
+
390
+ static void bbr_check_startup_high_loss(ngtcp2_bbr2_cc *bbr,
391
+ const ngtcp2_cc_ack *ack) {
392
+ if (bbr->filled_pipe || !bbr->round_start || bbr->rst->rs.is_app_limited) {
393
+ return;
394
+ }
395
+
396
+ if (bbr->loss_events_in_round <= 3) {
397
+ return;
398
+ }
399
+
400
+ /* loss_thresh = 2% */
401
+ if (bbr->bytes_lost_in_round * 100 <= ack->prior_bytes_in_flight * 2) {
402
+ return;
403
+ }
404
+
405
+ bbr->filled_pipe = 1;
406
+ }
407
+
408
+ static void bbr_init_pacing_rate(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat) {
409
+ double nominal_bandwidth = (double)bbr->initial_cwnd;
410
+
411
+ cstat->pacing_rate = NGTCP2_BBR_STARTUP_PACING_GAIN * nominal_bandwidth /
412
+ (double)NGTCP2_MILLISECONDS;
413
+ }
414
+
415
+ static void bbr_set_pacing_rate_with_gain(ngtcp2_bbr2_cc *bbr,
416
+ ngtcp2_conn_stat *cstat,
417
+ double pacing_gain) {
418
+ double rate = pacing_gain * (double)bbr->bw *
419
+ (100 - NGTCP2_BBR_PACING_MARGIN_PERCENT) / 100 / NGTCP2_SECONDS;
420
+
421
+ if (bbr->filled_pipe || rate > cstat->pacing_rate) {
422
+ cstat->pacing_rate = rate;
423
+ }
424
+ }
425
+
426
+ static void bbr_set_pacing_rate(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat) {
427
+ bbr_set_pacing_rate_with_gain(bbr, cstat, bbr->pacing_gain);
428
+ }
429
+
430
+ static void bbr_enter_startup(ngtcp2_bbr2_cc *bbr) {
431
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV, "bbr2 enter Startup");
432
+
433
+ bbr->state = NGTCP2_BBR2_STATE_STARTUP;
434
+ bbr->pacing_gain = NGTCP2_BBR_STARTUP_PACING_GAIN;
435
+ bbr->cwnd_gain = NGTCP2_BBR_STARTUP_CWND_GAIN;
436
+ }
437
+
438
+ static void bbr_check_startup_done(ngtcp2_bbr2_cc *bbr,
439
+ const ngtcp2_cc_ack *ack) {
440
+ bbr_check_startup_full_bandwidth(bbr);
441
+ bbr_check_startup_high_loss(bbr, ack);
442
+
443
+ if (bbr->state == NGTCP2_BBR2_STATE_STARTUP && bbr->filled_pipe) {
444
+ bbr_enter_drain(bbr);
445
+ }
446
+ }
447
+
448
+ static void bbr_on_transmit(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
449
+ ngtcp2_tstamp ts) {
450
+ bbr_handle_restart_from_idle(bbr, cstat, ts);
451
+ }
452
+
453
+ static void bbr_update_on_ack(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
454
+ const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
455
+ bbr_update_model_and_state(bbr, cstat, ack, ts);
456
+ bbr_update_control_parameters(bbr, cstat, ack);
457
+ }
458
+
459
+ static void bbr_update_model_and_state(ngtcp2_bbr2_cc *bbr,
460
+ ngtcp2_conn_stat *cstat,
461
+ const ngtcp2_cc_ack *ack,
462
+ ngtcp2_tstamp ts) {
463
+ bbr_update_latest_delivery_signals(bbr, cstat);
464
+ bbr_update_congestion_signals(bbr, cstat, ack);
465
+ bbr_update_ack_aggregation(bbr, cstat, ack, ts);
466
+ bbr_check_startup_done(bbr, ack);
467
+ bbr_check_drain(bbr, cstat, ts);
468
+ bbr_update_probe_bw_cycle_phase(bbr, cstat, ack, ts);
469
+ bbr_update_min_rtt(bbr, ack, ts);
470
+ bbr_check_probe_rtt(bbr, cstat, ts);
471
+ bbr_advance_latest_delivery_signals(bbr, cstat);
472
+ bbr_bound_bw_for_model(bbr);
473
+ }
474
+
475
+ static void bbr_update_control_parameters(ngtcp2_bbr2_cc *bbr,
476
+ ngtcp2_conn_stat *cstat,
477
+ const ngtcp2_cc_ack *ack) {
478
+ bbr_set_pacing_rate(bbr, cstat);
479
+ bbr_set_send_quantum(bbr, cstat);
480
+ bbr_set_cwnd(bbr, cstat, ack);
481
+ }
482
+
483
+ static void bbr_update_on_loss(ngtcp2_bbr2_cc *cc, ngtcp2_conn_stat *cstat,
484
+ const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
485
+ bbr_handle_lost_packet(cc, cstat, pkt, ts);
486
+ }
487
+
488
+ static void bbr_update_latest_delivery_signals(ngtcp2_bbr2_cc *bbr,
489
+ ngtcp2_conn_stat *cstat) {
490
+ bbr->loss_round_start = 0;
491
+ bbr->bw_latest = ngtcp2_max(bbr->bw_latest, cstat->delivery_rate_sec);
492
+ bbr->inflight_latest =
493
+ ngtcp2_max(bbr->inflight_latest, bbr->rst->rs.delivered);
494
+
495
+ if (bbr->rst->rs.prior_delivered >= bbr->loss_round_delivered) {
496
+ bbr->loss_round_delivered = bbr->rst->delivered;
497
+ bbr->loss_round_start = 1;
498
+ }
499
+ }
500
+
501
+ static void bbr_advance_latest_delivery_signals(ngtcp2_bbr2_cc *bbr,
502
+ ngtcp2_conn_stat *cstat) {
503
+ if (bbr->loss_round_start) {
504
+ bbr->bw_latest = cstat->delivery_rate_sec;
505
+ bbr->inflight_latest = bbr->rst->rs.delivered;
506
+ }
507
+ }
508
+
509
+ static void bbr_update_congestion_signals(ngtcp2_bbr2_cc *bbr,
510
+ ngtcp2_conn_stat *cstat,
511
+ const ngtcp2_cc_ack *ack) {
512
+ bbr_update_max_bw(bbr, cstat, ack);
513
+
514
+ if (ack->bytes_lost) {
515
+ bbr->bytes_lost_in_round += ack->bytes_lost;
516
+ ++bbr->loss_events_in_round;
517
+
518
+ if (!bbr->loss_in_round) {
519
+ bbr->loss_in_round = 1;
520
+ bbr->loss_round_delivered = bbr->rst->delivered;
521
+ }
522
+ }
523
+
524
+ if (!bbr->loss_round_start) {
525
+ return;
526
+ }
527
+
528
+ bbr_adapt_lower_bounds_from_congestion(bbr, cstat);
529
+
530
+ bbr->loss_in_round = 0;
531
+ }
532
+
533
+ static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_bbr2_cc *bbr,
534
+ ngtcp2_conn_stat *cstat) {
535
+ if (!bbr->filled_pipe || bbr_is_in_probe_bw_state(bbr)) {
536
+ return;
537
+ }
538
+
539
+ if (bbr->loss_in_round) {
540
+ bbr_init_lower_bounds(bbr, cstat);
541
+ bbr_loss_lower_bounds(bbr);
542
+ }
543
+ }
544
+
545
+ static void bbr_init_lower_bounds(ngtcp2_bbr2_cc *bbr,
546
+ ngtcp2_conn_stat *cstat) {
547
+ if (bbr->bw_lo == UINT64_MAX) {
548
+ bbr->bw_lo = bbr->max_bw;
549
+ }
550
+
551
+ if (bbr->inflight_lo == UINT64_MAX) {
552
+ bbr->inflight_lo = cstat->cwnd;
553
+ }
554
+ }
555
+
556
+ static void bbr_loss_lower_bounds(ngtcp2_bbr2_cc *bbr) {
557
+ bbr->bw_lo = ngtcp2_max(bbr->bw_latest, bbr->bw_lo * NGTCP2_BBR_BETA_NUMER /
558
+ NGTCP2_BBR_BETA_DENOM);
559
+ bbr->inflight_lo = ngtcp2_max(bbr->inflight_latest,
560
+ bbr->inflight_lo * NGTCP2_BBR_BETA_NUMER /
561
+ NGTCP2_BBR_BETA_DENOM);
562
+ }
563
+
564
+ static void bbr_bound_bw_for_model(ngtcp2_bbr2_cc *bbr) {
565
+ bbr->bw = ngtcp2_min(bbr->max_bw, bbr->bw_lo);
566
+ bbr->bw = ngtcp2_min(bbr->bw, bbr->bw_hi);
567
+ }
568
+
569
+ static void bbr_update_max_bw(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
570
+ const ngtcp2_cc_ack *ack) {
571
+ bbr_update_round(bbr, ack);
572
+ bbr_handle_recovery(bbr, cstat, ack);
573
+
574
+ if (cstat->delivery_rate_sec >= bbr->max_bw || !bbr->rst->rs.is_app_limited) {
575
+ ngtcp2_window_filter_update(&bbr->max_bw_filter, cstat->delivery_rate_sec,
576
+ bbr->cycle_count);
577
+
578
+ bbr->max_bw = ngtcp2_window_filter_get_best(&bbr->max_bw_filter);
579
+ }
580
+ }
581
+
582
+ static void bbr_update_round(ngtcp2_bbr2_cc *bbr, const ngtcp2_cc_ack *ack) {
583
+ if (ack->pkt_delivered >= bbr->next_round_delivered) {
584
+ bbr_start_round(bbr);
585
+
586
+ ++bbr->round_count;
587
+ ++bbr->rounds_since_bw_probe;
588
+ bbr->round_start = 1;
589
+
590
+ bbr->bytes_lost_in_round = 0;
591
+ bbr->loss_events_in_round = 0;
592
+
593
+ bbr->rst->is_cwnd_limited = 0;
594
+
595
+ return;
596
+ }
597
+
598
+ bbr->round_start = 0;
599
+ }
600
+
601
+ static void bbr_start_round(ngtcp2_bbr2_cc *bbr) {
602
+ bbr->next_round_delivered = bbr->rst->delivered;
603
+ }
604
+
605
+ static int bbr_is_in_probe_bw_state(ngtcp2_bbr2_cc *bbr) {
606
+ switch (bbr->state) {
607
+ case NGTCP2_BBR2_STATE_PROBE_BW_DOWN:
608
+ case NGTCP2_BBR2_STATE_PROBE_BW_CRUISE:
609
+ case NGTCP2_BBR2_STATE_PROBE_BW_REFILL:
610
+ case NGTCP2_BBR2_STATE_PROBE_BW_UP:
611
+ return 1;
612
+ default:
613
+ return 0;
614
+ }
615
+ }
616
+
617
+ static void bbr_update_ack_aggregation(ngtcp2_bbr2_cc *bbr,
618
+ ngtcp2_conn_stat *cstat,
619
+ const ngtcp2_cc_ack *ack,
620
+ ngtcp2_tstamp ts) {
621
+ ngtcp2_duration interval = ts - bbr->extra_acked_interval_start;
622
+ uint64_t expected_delivered = bbr->bw * interval / NGTCP2_SECONDS;
623
+ uint64_t extra;
624
+
625
+ if (bbr->extra_acked_delivered <= expected_delivered) {
626
+ bbr->extra_acked_delivered = 0;
627
+ bbr->extra_acked_interval_start = ts;
628
+ expected_delivered = 0;
629
+ }
630
+
631
+ bbr->extra_acked_delivered += ack->bytes_delivered;
632
+ extra = bbr->extra_acked_delivered - expected_delivered;
633
+ extra = ngtcp2_min(extra, cstat->cwnd);
634
+
635
+ ngtcp2_window_filter_update(&bbr->extra_acked_filter, extra,
636
+ bbr->round_count);
637
+
638
+ bbr->extra_acked = ngtcp2_window_filter_get_best(&bbr->extra_acked_filter);
639
+ }
640
+
641
+ static void bbr_enter_drain(ngtcp2_bbr2_cc *bbr) {
642
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV, "bbr2 enter Drain");
643
+
644
+ bbr->state = NGTCP2_BBR2_STATE_DRAIN;
645
+ bbr->pacing_gain = 1. / NGTCP2_BBR_STARTUP_CWND_GAIN;
646
+ bbr->cwnd_gain = NGTCP2_BBR_STARTUP_CWND_GAIN;
647
+ }
648
+
649
+ static void bbr_check_drain(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
650
+ ngtcp2_tstamp ts) {
651
+ if (bbr->state == NGTCP2_BBR2_STATE_DRAIN &&
652
+ cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, bbr->bw, 1.0)) {
653
+ bbr_enter_probe_bw(bbr, ts);
654
+ }
655
+ }
656
+
657
+ static void bbr_enter_probe_bw(ngtcp2_bbr2_cc *bbr, ngtcp2_tstamp ts) {
658
+ bbr_start_probe_bw_down(bbr, ts);
659
+ }
660
+
661
+ static void bbr_start_probe_bw_down(ngtcp2_bbr2_cc *bbr, ngtcp2_tstamp ts) {
662
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV,
663
+ "bbr2 start ProbeBW_DOWN");
664
+
665
+ bbr_reset_congestion_signals(bbr);
666
+
667
+ bbr->probe_up_cnt = UINT64_MAX;
668
+
669
+ bbr_pick_probe_wait(bbr);
670
+
671
+ bbr->cycle_stamp = ts;
672
+ bbr->ack_phase = NGTCP2_BBR2_ACK_PHASE_ACKS_PROBE_STOPPING;
673
+
674
+ bbr_start_round(bbr);
675
+
676
+ bbr->state = NGTCP2_BBR2_STATE_PROBE_BW_DOWN;
677
+ bbr->pacing_gain = 0.9;
678
+ bbr->cwnd_gain = 2;
679
+ }
680
+
681
+ static void bbr_start_probe_bw_cruise(ngtcp2_bbr2_cc *bbr) {
682
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV,
683
+ "bbr2 start ProbeBW_CRUISE");
684
+
685
+ bbr->state = NGTCP2_BBR2_STATE_PROBE_BW_CRUISE;
686
+ bbr->pacing_gain = 1.0;
687
+ bbr->cwnd_gain = 2;
688
+ }
689
+
690
+ static void bbr_start_probe_bw_refill(ngtcp2_bbr2_cc *bbr) {
691
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV,
692
+ "bbr2 start ProbeBW_REFILL");
693
+
694
+ bbr_reset_lower_bounds(bbr);
695
+
696
+ bbr->bw_probe_up_rounds = 0;
697
+ bbr->bw_probe_up_acks = 0;
698
+ bbr->ack_phase = NGTCP2_BBR2_ACK_PHASE_ACKS_REFILLING;
699
+
700
+ bbr_start_round(bbr);
701
+
702
+ bbr->state = NGTCP2_BBR2_STATE_PROBE_BW_REFILL;
703
+ bbr->pacing_gain = 1.0;
704
+ bbr->cwnd_gain = 2;
705
+ }
706
+
707
+ static void bbr_start_probe_bw_up(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
708
+ ngtcp2_tstamp ts) {
709
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV, "bbr2 start ProbeBW_UP");
710
+
711
+ bbr->ack_phase = NGTCP2_BBR2_ACK_PHASE_ACKS_PROBE_STARTING;
712
+
713
+ bbr_start_round(bbr);
714
+
715
+ bbr->cycle_stamp = ts;
716
+ bbr->state = NGTCP2_BBR2_STATE_PROBE_BW_UP;
717
+ bbr->pacing_gain = 1.25;
718
+ bbr->cwnd_gain = 2;
719
+
720
+ bbr_raise_inflight_hi_slope(bbr, cstat);
721
+ }
722
+
723
+ static void bbr_update_probe_bw_cycle_phase(ngtcp2_bbr2_cc *bbr,
724
+ ngtcp2_conn_stat *cstat,
725
+ const ngtcp2_cc_ack *ack,
726
+ ngtcp2_tstamp ts) {
727
+ if (!bbr->filled_pipe) {
728
+ return;
729
+ }
730
+
731
+ bbr_adapt_upper_bounds(bbr, cstat, ack, ts);
732
+
733
+ if (!bbr_is_in_probe_bw_state(bbr)) {
734
+ return;
735
+ }
736
+
737
+ switch (bbr->state) {
738
+ case NGTCP2_BBR2_STATE_PROBE_BW_DOWN:
739
+ if (bbr_check_time_to_probe_bw(bbr, cstat, ts)) {
740
+ return;
741
+ }
742
+
743
+ if (bbr_check_time_to_cruise(bbr, cstat, ts)) {
744
+ bbr_start_probe_bw_cruise(bbr);
745
+ }
746
+
747
+ break;
748
+ case NGTCP2_BBR2_STATE_PROBE_BW_CRUISE:
749
+ if (bbr_check_time_to_probe_bw(bbr, cstat, ts)) {
750
+ return;
751
+ }
752
+
753
+ break;
754
+ case NGTCP2_BBR2_STATE_PROBE_BW_REFILL:
755
+ if (bbr->round_start) {
756
+ bbr->bw_probe_samples = 1;
757
+ bbr_start_probe_bw_up(bbr, cstat, ts);
758
+ }
759
+
760
+ break;
761
+ case NGTCP2_BBR2_STATE_PROBE_BW_UP:
762
+ if (bbr_has_elapsed_in_phase(bbr, bbr->min_rtt, ts) &&
763
+ cstat->bytes_in_flight > bbr_inflight(bbr, cstat, bbr->max_bw, 1.25)) {
764
+ bbr_start_probe_bw_down(bbr, ts);
765
+ }
766
+
767
+ break;
768
+ default:
769
+ break;
770
+ }
771
+ }
772
+
773
+ static int bbr_check_time_to_cruise(ngtcp2_bbr2_cc *bbr,
774
+ ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts) {
775
+ (void)ts;
776
+
777
+ if (cstat->bytes_in_flight > bbr_inflight_with_headroom(bbr, cstat)) {
778
+ return 0;
779
+ }
780
+
781
+ if (cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, bbr->max_bw, 1.0)) {
782
+ return 1;
783
+ }
784
+
785
+ return 0;
786
+ }
787
+
788
+ static int bbr_has_elapsed_in_phase(ngtcp2_bbr2_cc *bbr,
789
+ ngtcp2_duration interval,
790
+ ngtcp2_tstamp ts) {
791
+ return ts > bbr->cycle_stamp + interval;
792
+ }
793
+
794
+ static uint64_t bbr_inflight_with_headroom(ngtcp2_bbr2_cc *bbr,
795
+ ngtcp2_conn_stat *cstat) {
796
+ uint64_t headroom;
797
+ uint64_t mpcwnd;
798
+ if (bbr->inflight_hi == UINT64_MAX) {
799
+ return UINT64_MAX;
800
+ }
801
+
802
+ headroom = ngtcp2_max(cstat->max_tx_udp_payload_size,
803
+ bbr->inflight_hi * NGTCP2_BBR_HEADROOM_NUMER /
804
+ NGTCP2_BBR_HEADROOM_DENOM);
805
+ mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
806
+
807
+ if (bbr->inflight_hi > headroom) {
808
+ return ngtcp2_max(bbr->inflight_hi - headroom, mpcwnd);
809
+ }
810
+
811
+ return mpcwnd;
812
+ }
813
+
814
+ static void bbr_raise_inflight_hi_slope(ngtcp2_bbr2_cc *bbr,
815
+ ngtcp2_conn_stat *cstat) {
816
+ uint64_t growth_this_round = cstat->max_tx_udp_payload_size
817
+ << bbr->bw_probe_up_rounds;
818
+
819
+ bbr->bw_probe_up_rounds = ngtcp2_min(bbr->bw_probe_up_rounds + 1, 30);
820
+ bbr->probe_up_cnt = ngtcp2_max(cstat->cwnd / growth_this_round, 1) *
821
+ cstat->max_tx_udp_payload_size;
822
+ }
823
+
824
+ static void bbr_probe_inflight_hi_upward(ngtcp2_bbr2_cc *bbr,
825
+ ngtcp2_conn_stat *cstat,
826
+ const ngtcp2_cc_ack *ack) {
827
+ uint64_t delta;
828
+
829
+ if (!bbr->rst->is_cwnd_limited || cstat->cwnd < bbr->inflight_hi) {
830
+ return;
831
+ }
832
+
833
+ bbr->bw_probe_up_acks += ack->bytes_delivered;
834
+
835
+ if (bbr->bw_probe_up_acks >= bbr->probe_up_cnt) {
836
+ delta = bbr->bw_probe_up_acks / bbr->probe_up_cnt;
837
+ bbr->bw_probe_up_acks -= delta * bbr->probe_up_cnt;
838
+ bbr->inflight_hi += delta * cstat->max_tx_udp_payload_size;
839
+ }
840
+
841
+ if (bbr->round_start) {
842
+ bbr_raise_inflight_hi_slope(bbr, cstat);
843
+ }
844
+ }
845
+
846
+ static void bbr_adapt_upper_bounds(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
847
+ const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
848
+ if (bbr->ack_phase == NGTCP2_BBR2_ACK_PHASE_ACKS_PROBE_STARTING &&
849
+ bbr->round_start) {
850
+ bbr->ack_phase = NGTCP2_BBR2_ACK_PHASE_ACKS_PROBE_FEEDBACK;
851
+ }
852
+
853
+ if (bbr->ack_phase == NGTCP2_BBR2_ACK_PHASE_ACKS_PROBE_STOPPING &&
854
+ bbr->round_start) {
855
+ if (bbr_is_in_probe_bw_state(bbr) && !bbr->rst->rs.is_app_limited) {
856
+ bbr_advance_max_bw_filter(bbr);
857
+ }
858
+ }
859
+
860
+ if (!bbr_check_inflight_too_high(bbr, cstat, ts)) {
861
+ /* bbr->bw_hi never be updated */
862
+ if (bbr->inflight_hi == UINT64_MAX /* || bbr->bw_hi == UINT64_MAX */) {
863
+ return;
864
+ }
865
+
866
+ if (bbr->rst->rs.tx_in_flight > bbr->inflight_hi) {
867
+ bbr->inflight_hi = bbr->rst->rs.tx_in_flight;
868
+ }
869
+
870
+ if (cstat->delivery_rate_sec > bbr->bw_hi) {
871
+ bbr->bw_hi = cstat->delivery_rate_sec;
872
+ }
873
+
874
+ if (bbr->state == NGTCP2_BBR2_STATE_PROBE_BW_UP) {
875
+ bbr_probe_inflight_hi_upward(bbr, cstat, ack);
876
+ }
877
+ }
878
+ }
879
+
880
+ static int bbr_check_time_to_probe_bw(ngtcp2_bbr2_cc *bbr,
881
+ ngtcp2_conn_stat *cstat,
882
+ ngtcp2_tstamp ts) {
883
+ if (bbr_has_elapsed_in_phase(bbr, bbr->bw_probe_wait, ts) ||
884
+ bbr_is_reno_coexistence_probe_time(bbr, cstat)) {
885
+ bbr_start_probe_bw_refill(bbr);
886
+
887
+ return 1;
888
+ }
889
+
890
+ return 0;
891
+ }
892
+
893
+ static void bbr_pick_probe_wait(ngtcp2_bbr2_cc *bbr) {
894
+ uint8_t rand;
895
+
896
+ bbr->rand(&rand, 1, &bbr->rand_ctx);
897
+
898
+ bbr->rounds_since_bw_probe = (uint64_t)(rand * 2 / 256);
899
+
900
+ bbr->rand(&rand, 1, &bbr->rand_ctx);
901
+
902
+ bbr->bw_probe_wait = 2 * NGTCP2_SECONDS +
903
+ (ngtcp2_tstamp)((double)rand / 255. * NGTCP2_SECONDS);
904
+ }
905
+
906
+ static int bbr_is_reno_coexistence_probe_time(ngtcp2_bbr2_cc *bbr,
907
+ ngtcp2_conn_stat *cstat) {
908
+ uint64_t reno_rounds =
909
+ bbr_target_inflight(bbr, cstat) / cstat->max_tx_udp_payload_size;
910
+
911
+ return bbr->rounds_since_bw_probe >= ngtcp2_min(reno_rounds, 63);
912
+ }
913
+
914
+ static uint64_t bbr_target_inflight(ngtcp2_bbr2_cc *bbr,
915
+ ngtcp2_conn_stat *cstat) {
916
+ uint64_t bdp = bbr_inflight(bbr, cstat, bbr->bw, 1.0);
917
+
918
+ return ngtcp2_min(bdp, cstat->cwnd);
919
+ }
920
+
921
+ static int bbr_check_inflight_too_high(ngtcp2_bbr2_cc *bbr,
922
+ ngtcp2_conn_stat *cstat,
923
+ ngtcp2_tstamp ts) {
924
+ if (is_inflight_too_high(&bbr->rst->rs)) {
925
+ if (bbr->bw_probe_samples) {
926
+ bbr_handle_inflight_too_high(bbr, cstat, &bbr->rst->rs, ts);
927
+ }
928
+
929
+ return 1;
930
+ }
931
+
932
+ return 0;
933
+ }
934
+
935
+ static int is_inflight_too_high(const ngtcp2_rs *rs) {
936
+ return rs->lost * NGTCP2_BBR_LOSS_THRESH_DENOM >
937
+ rs->tx_in_flight * NGTCP2_BBR_LOSS_THRESH_NUMER;
938
+ }
939
+
940
+ static void bbr_handle_inflight_too_high(ngtcp2_bbr2_cc *bbr,
941
+ ngtcp2_conn_stat *cstat,
942
+ const ngtcp2_rs *rs,
943
+ ngtcp2_tstamp ts) {
944
+ bbr->bw_probe_samples = 0;
945
+
946
+ if (!rs->is_app_limited) {
947
+ bbr->prior_inflight_hi = bbr->inflight_hi;
948
+
949
+ bbr->inflight_hi = ngtcp2_max(
950
+ rs->tx_in_flight, bbr_target_inflight(bbr, cstat) *
951
+ NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
952
+ }
953
+
954
+ if (bbr->state == NGTCP2_BBR2_STATE_PROBE_BW_UP) {
955
+ bbr_start_probe_bw_down(bbr, ts);
956
+ }
957
+ }
958
+
959
+ static void bbr_handle_lost_packet(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
960
+ const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
961
+ ngtcp2_rs rs = {0};
962
+
963
+ if (!bbr->bw_probe_samples) {
964
+ return;
965
+ }
966
+
967
+ rs.tx_in_flight = pkt->tx_in_flight;
968
+ /* bbr->rst->lost is not incremented for pkt yet */
969
+ rs.lost = bbr->rst->lost + pkt->pktlen - pkt->lost;
970
+ rs.is_app_limited = pkt->is_app_limited;
971
+
972
+ if (is_inflight_too_high(&rs)) {
973
+ rs.tx_in_flight = bbr_inflight_hi_from_lost_packet(bbr, &rs, pkt);
974
+
975
+ bbr_handle_inflight_too_high(bbr, cstat, &rs, ts);
976
+ }
977
+ }
978
+
979
+ static uint64_t bbr_inflight_hi_from_lost_packet(ngtcp2_bbr2_cc *bbr,
980
+ const ngtcp2_rs *rs,
981
+ const ngtcp2_cc_pkt *pkt) {
982
+ uint64_t inflight_prev, lost_prev, lost_prefix;
983
+ (void)bbr;
984
+
985
+ assert(rs->tx_in_flight >= pkt->pktlen);
986
+
987
+ inflight_prev = rs->tx_in_flight - pkt->pktlen;
988
+
989
+ assert(rs->lost >= pkt->pktlen);
990
+
991
+ lost_prev = rs->lost - pkt->pktlen;
992
+
993
+ if (inflight_prev * NGTCP2_BBR_LOSS_THRESH_NUMER <
994
+ lost_prev * NGTCP2_BBR_LOSS_THRESH_DENOM) {
995
+ return inflight_prev;
996
+ }
997
+
998
+ lost_prefix = (inflight_prev * NGTCP2_BBR_LOSS_THRESH_NUMER -
999
+ lost_prev * NGTCP2_BBR_LOSS_THRESH_DENOM) /
1000
+ (NGTCP2_BBR_LOSS_THRESH_DENOM - NGTCP2_BBR_LOSS_THRESH_NUMER);
1001
+
1002
+ return inflight_prev + lost_prefix;
1003
+ }
1004
+
1005
+ static void bbr_update_min_rtt(ngtcp2_bbr2_cc *bbr, const ngtcp2_cc_ack *ack,
1006
+ ngtcp2_tstamp ts) {
1007
+ int min_rtt_expired;
1008
+
1009
+ bbr->probe_rtt_expired =
1010
+ ts > bbr->probe_rtt_min_stamp + NGTCP2_BBR_PROBE_RTT_INTERVAL;
1011
+
1012
+ if (ack->rtt != UINT64_MAX &&
1013
+ (ack->rtt < bbr->probe_rtt_min_delay || bbr->probe_rtt_expired)) {
1014
+ bbr->probe_rtt_min_delay = ack->rtt;
1015
+ bbr->probe_rtt_min_stamp = ts;
1016
+ }
1017
+
1018
+ min_rtt_expired = ts > bbr->min_rtt_stamp + NGTCP2_BBR_MIN_RTT_FILTERLEN;
1019
+
1020
+ if (bbr->probe_rtt_min_delay < bbr->min_rtt || min_rtt_expired) {
1021
+ bbr->min_rtt = bbr->probe_rtt_min_delay;
1022
+ bbr->min_rtt_stamp = bbr->probe_rtt_min_stamp;
1023
+
1024
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV,
1025
+ "bbr2 update min_rtt=%" PRIu64, bbr->min_rtt);
1026
+ }
1027
+ }
1028
+
1029
+ static void bbr_check_probe_rtt(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
1030
+ ngtcp2_tstamp ts) {
1031
+ if (bbr->state != NGTCP2_BBR2_STATE_PROBE_RTT && bbr->probe_rtt_expired &&
1032
+ !bbr->idle_restart) {
1033
+ bbr_enter_probe_rtt(bbr);
1034
+ bbr_save_cwnd(bbr, cstat);
1035
+
1036
+ bbr->probe_rtt_done_stamp = UINT64_MAX;
1037
+ bbr->ack_phase = NGTCP2_BBR2_ACK_PHASE_ACKS_PROBE_STOPPING;
1038
+
1039
+ bbr_start_round(bbr);
1040
+ }
1041
+
1042
+ if (bbr->state == NGTCP2_BBR2_STATE_PROBE_RTT) {
1043
+ bbr_handle_probe_rtt(bbr, cstat, ts);
1044
+ }
1045
+
1046
+ if (bbr->rst->rs.delivered) {
1047
+ bbr->idle_restart = 0;
1048
+ }
1049
+ }
1050
+
1051
+ static void bbr_enter_probe_rtt(ngtcp2_bbr2_cc *bbr) {
1052
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV, "bbr2 enter ProbeRTT");
1053
+
1054
+ bbr->state = NGTCP2_BBR2_STATE_PROBE_RTT;
1055
+ bbr->pacing_gain = 1;
1056
+ bbr->cwnd_gain = NGTCP2_BBR_PROBE_RTT_CWND_GAIN;
1057
+ }
1058
+
1059
+ static void bbr_handle_probe_rtt(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
1060
+ ngtcp2_tstamp ts) {
1061
+ bbr_mark_connection_app_limited(bbr, cstat);
1062
+
1063
+ if (bbr->probe_rtt_done_stamp == UINT64_MAX &&
1064
+ cstat->bytes_in_flight <= bbr_probe_rtt_cwnd(bbr, cstat)) {
1065
+ bbr->probe_rtt_done_stamp = ts + NGTCP2_BBR_PROBE_RTT_DURATION;
1066
+ bbr->probe_rtt_round_done = 0;
1067
+
1068
+ bbr_start_round(bbr);
1069
+
1070
+ return;
1071
+ }
1072
+
1073
+ if (bbr->probe_rtt_done_stamp != UINT64_MAX) {
1074
+ if (bbr->round_start) {
1075
+ bbr->probe_rtt_round_done = 1;
1076
+ }
1077
+
1078
+ if (bbr->probe_rtt_round_done) {
1079
+ bbr_check_probe_rtt_done(bbr, cstat, ts);
1080
+ }
1081
+ }
1082
+ }
1083
+
1084
+ static void bbr_check_probe_rtt_done(ngtcp2_bbr2_cc *bbr,
1085
+ ngtcp2_conn_stat *cstat,
1086
+ ngtcp2_tstamp ts) {
1087
+ if (bbr->probe_rtt_done_stamp != UINT64_MAX &&
1088
+ ts > bbr->probe_rtt_done_stamp) {
1089
+ bbr->probe_rtt_min_stamp = ts;
1090
+ bbr_restore_cwnd(bbr, cstat);
1091
+ bbr_exit_probe_rtt(bbr, ts);
1092
+ }
1093
+ }
1094
+
1095
+ static void bbr_mark_connection_app_limited(ngtcp2_bbr2_cc *bbr,
1096
+ ngtcp2_conn_stat *cstat) {
1097
+ uint64_t app_limited = bbr->rst->delivered + cstat->bytes_in_flight;
1098
+
1099
+ if (app_limited) {
1100
+ bbr->rst->app_limited = app_limited;
1101
+ } else {
1102
+ bbr->rst->app_limited = cstat->max_tx_udp_payload_size;
1103
+ }
1104
+ }
1105
+
1106
+ static void bbr_exit_probe_rtt(ngtcp2_bbr2_cc *bbr, ngtcp2_tstamp ts) {
1107
+ bbr_reset_lower_bounds(bbr);
1108
+
1109
+ if (bbr->filled_pipe) {
1110
+ bbr_start_probe_bw_down(bbr, ts);
1111
+ bbr_start_probe_bw_cruise(bbr);
1112
+ } else {
1113
+ bbr_enter_startup(bbr);
1114
+ }
1115
+ }
1116
+
1117
+ static void bbr_handle_restart_from_idle(ngtcp2_bbr2_cc *bbr,
1118
+ ngtcp2_conn_stat *cstat,
1119
+ ngtcp2_tstamp ts) {
1120
+ if (cstat->bytes_in_flight == 0 && bbr->rst->app_limited) {
1121
+ ngtcp2_log_info(bbr->ccb.log, NGTCP2_LOG_EVENT_RCV,
1122
+ "bbr2 restart from idle");
1123
+
1124
+ bbr->idle_restart = 1;
1125
+ bbr->extra_acked_interval_start = ts;
1126
+
1127
+ if (bbr_is_in_probe_bw_state(bbr)) {
1128
+ bbr_set_pacing_rate_with_gain(bbr, cstat, 1);
1129
+ } else if (bbr->state == NGTCP2_BBR2_STATE_PROBE_RTT) {
1130
+ bbr_check_probe_rtt_done(bbr, cstat, ts);
1131
+ }
1132
+ }
1133
+ }
1134
+
1135
+ static uint64_t bbr_bdp_multiple(ngtcp2_bbr2_cc *bbr, uint64_t bw,
1136
+ double gain) {
1137
+ uint64_t bdp;
1138
+
1139
+ if (bbr->min_rtt == UINT64_MAX) {
1140
+ return bbr->initial_cwnd;
1141
+ }
1142
+
1143
+ bdp = bw * bbr->min_rtt / NGTCP2_SECONDS;
1144
+
1145
+ return (uint64_t)(gain * (double)bdp);
1146
+ }
1147
+
1148
+ static uint64_t min_pipe_cwnd(size_t max_udp_payload_size) {
1149
+ return max_udp_payload_size * 4;
1150
+ }
1151
+
1152
+ static uint64_t bbr_quantization_budget(ngtcp2_bbr2_cc *bbr,
1153
+ ngtcp2_conn_stat *cstat,
1154
+ uint64_t inflight) {
1155
+ bbr_update_offload_budget(bbr, cstat);
1156
+
1157
+ inflight = ngtcp2_max(inflight, bbr->offload_budget);
1158
+ inflight =
1159
+ ngtcp2_max(inflight, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
1160
+
1161
+ if (bbr->state == NGTCP2_BBR2_STATE_PROBE_BW_UP) {
1162
+ inflight += 2 * cstat->max_tx_udp_payload_size;
1163
+ }
1164
+
1165
+ return inflight;
1166
+ }
1167
+
1168
+ static uint64_t bbr_inflight(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
1169
+ uint64_t bw, double gain) {
1170
+ uint64_t inflight = bbr_bdp_multiple(bbr, bw, gain);
1171
+
1172
+ return bbr_quantization_budget(bbr, cstat, inflight);
1173
+ }
1174
+
1175
+ static void bbr_update_max_inflight(ngtcp2_bbr2_cc *bbr,
1176
+ ngtcp2_conn_stat *cstat) {
1177
+ uint64_t inflight;
1178
+
1179
+ /* Not documented */
1180
+ /* bbr_update_aggregation_budget(bbr); */
1181
+
1182
+ inflight = bbr_bdp_multiple(bbr, bbr->bw, bbr->cwnd_gain) + bbr->extra_acked;
1183
+ bbr->max_inflight = bbr_quantization_budget(bbr, cstat, inflight);
1184
+ }
1185
+
1186
+ static void bbr_update_offload_budget(ngtcp2_bbr2_cc *bbr,
1187
+ ngtcp2_conn_stat *cstat) {
1188
+ bbr->offload_budget = 3 * cstat->send_quantum;
1189
+ }
1190
+
1191
+ static void bbr_advance_max_bw_filter(ngtcp2_bbr2_cc *bbr) {
1192
+ ++bbr->cycle_count;
1193
+ }
1194
+
1195
+ static void bbr_modulate_cwnd_for_recovery(ngtcp2_bbr2_cc *bbr,
1196
+ ngtcp2_conn_stat *cstat,
1197
+ const ngtcp2_cc_ack *ack) {
1198
+ if (ack->bytes_lost > 0) {
1199
+ if (cstat->cwnd > ack->bytes_lost) {
1200
+ cstat->cwnd -= ack->bytes_lost;
1201
+ cstat->cwnd = ngtcp2_max(cstat->cwnd, 2 * cstat->max_tx_udp_payload_size);
1202
+ } else {
1203
+ cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
1204
+ }
1205
+ }
1206
+
1207
+ if (bbr->packet_conservation) {
1208
+ cstat->cwnd =
1209
+ ngtcp2_max(cstat->cwnd, cstat->bytes_in_flight + ack->bytes_delivered);
1210
+ }
1211
+ }
1212
+
1213
+ static void bbr_save_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat) {
1214
+ if (!bbr->in_loss_recovery && bbr->state != NGTCP2_BBR2_STATE_PROBE_RTT) {
1215
+ bbr->prior_cwnd = cstat->cwnd;
1216
+ return;
1217
+ }
1218
+
1219
+ bbr->prior_cwnd = ngtcp2_max(bbr->prior_cwnd, cstat->cwnd);
1220
+ }
1221
+
1222
+ static void bbr_restore_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat) {
1223
+ cstat->cwnd = ngtcp2_max(cstat->cwnd, bbr->prior_cwnd);
1224
+ }
1225
+
1226
+ static uint64_t bbr_probe_rtt_cwnd(ngtcp2_bbr2_cc *bbr,
1227
+ ngtcp2_conn_stat *cstat) {
1228
+ uint64_t probe_rtt_cwnd =
1229
+ bbr_bdp_multiple(bbr, bbr->bw, NGTCP2_BBR_PROBE_RTT_CWND_GAIN);
1230
+ uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
1231
+
1232
+ return ngtcp2_max(probe_rtt_cwnd, mpcwnd);
1233
+ }
1234
+
1235
+ static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_bbr2_cc *bbr,
1236
+ ngtcp2_conn_stat *cstat) {
1237
+ uint64_t probe_rtt_cwnd;
1238
+
1239
+ if (bbr->state == NGTCP2_BBR2_STATE_PROBE_RTT) {
1240
+ probe_rtt_cwnd = bbr_probe_rtt_cwnd(bbr, cstat);
1241
+
1242
+ cstat->cwnd = ngtcp2_min(cstat->cwnd, probe_rtt_cwnd);
1243
+ }
1244
+ }
1245
+
1246
+ static void bbr_set_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
1247
+ const ngtcp2_cc_ack *ack) {
1248
+ uint64_t mpcwnd;
1249
+
1250
+ bbr_update_max_inflight(bbr, cstat);
1251
+ bbr_modulate_cwnd_for_recovery(bbr, cstat, ack);
1252
+
1253
+ if (!bbr->packet_conservation) {
1254
+ if (bbr->filled_pipe) {
1255
+ cstat->cwnd += ack->bytes_delivered;
1256
+ cstat->cwnd = ngtcp2_min(cstat->cwnd, bbr->max_inflight);
1257
+ } else if (cstat->cwnd < bbr->max_inflight ||
1258
+ bbr->rst->delivered < bbr->initial_cwnd) {
1259
+ cstat->cwnd += ack->bytes_delivered;
1260
+ }
1261
+
1262
+ mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
1263
+ cstat->cwnd = ngtcp2_max(cstat->cwnd, mpcwnd);
1264
+ }
1265
+
1266
+ bbr_bound_cwnd_for_probe_rtt(bbr, cstat);
1267
+ bbr_bound_cwnd_for_model(bbr, cstat);
1268
+ }
1269
+
1270
+ static void bbr_bound_cwnd_for_model(ngtcp2_bbr2_cc *bbr,
1271
+ ngtcp2_conn_stat *cstat) {
1272
+ uint64_t cap = UINT64_MAX;
1273
+ uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
1274
+
1275
+ if (bbr_is_in_probe_bw_state(bbr) &&
1276
+ bbr->state != NGTCP2_BBR2_STATE_PROBE_BW_CRUISE) {
1277
+ cap = bbr->inflight_hi;
1278
+ } else if (bbr->state == NGTCP2_BBR2_STATE_PROBE_RTT ||
1279
+ bbr->state == NGTCP2_BBR2_STATE_PROBE_BW_CRUISE) {
1280
+ cap = bbr_inflight_with_headroom(bbr, cstat);
1281
+ }
1282
+
1283
+ cap = ngtcp2_min(cap, bbr->inflight_lo);
1284
+ cap = ngtcp2_max(cap, mpcwnd);
1285
+
1286
+ cstat->cwnd = ngtcp2_min(cstat->cwnd, cap);
1287
+ }
1288
+
1289
+ static void bbr_set_send_quantum(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat) {
1290
+ size_t send_quantum =
1291
+ (size_t)(cstat->pacing_rate * (double)(bbr->min_rtt == UINT64_MAX
1292
+ ? NGTCP2_MILLISECONDS
1293
+ : bbr->min_rtt));
1294
+ (void)bbr;
1295
+
1296
+ cstat->send_quantum = ngtcp2_min(send_quantum, 64 * 1024);
1297
+ cstat->send_quantum =
1298
+ ngtcp2_max(cstat->send_quantum, cstat->max_tx_udp_payload_size * 10);
1299
+ }
1300
+
1301
+ static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
1302
+ ngtcp2_tstamp sent_time) {
1303
+ return cstat->congestion_recovery_start_ts != UINT64_MAX &&
1304
+ sent_time <= cstat->congestion_recovery_start_ts;
1305
+ }
1306
+
1307
+ static void bbr_handle_recovery(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
1308
+ const ngtcp2_cc_ack *ack) {
1309
+ if (bbr->in_loss_recovery) {
1310
+ if (ack->pkt_delivered >= bbr->congestion_recovery_next_round_delivered) {
1311
+ bbr->packet_conservation = 0;
1312
+ }
1313
+
1314
+ if (!in_congestion_recovery(cstat, ack->largest_acked_sent_ts)) {
1315
+ bbr->in_loss_recovery = 0;
1316
+ bbr->packet_conservation = 0;
1317
+ bbr_restore_cwnd(bbr, cstat);
1318
+ }
1319
+
1320
+ return;
1321
+ }
1322
+
1323
+ if (bbr->congestion_recovery_start_ts != UINT64_MAX) {
1324
+ bbr->in_loss_recovery = 1;
1325
+ bbr_save_cwnd(bbr, cstat);
1326
+ cstat->cwnd =
1327
+ cstat->bytes_in_flight +
1328
+ ngtcp2_max(ack->bytes_delivered, cstat->max_tx_udp_payload_size);
1329
+
1330
+ cstat->congestion_recovery_start_ts = bbr->congestion_recovery_start_ts;
1331
+ bbr->congestion_recovery_start_ts = UINT64_MAX;
1332
+ bbr->packet_conservation = 1;
1333
+ bbr->congestion_recovery_next_round_delivered = bbr->rst->delivered;
1334
+ bbr->prior_inflight_lo = bbr->inflight_lo;
1335
+ bbr->prior_bw_lo = bbr->bw_lo;
1336
+ }
1337
+ }
1338
+
1339
+ static void bbr2_cc_init(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
1340
+ ngtcp2_rst *rst, ngtcp2_tstamp initial_ts,
1341
+ ngtcp2_rand rand, const ngtcp2_rand_ctx *rand_ctx,
1342
+ ngtcp2_log *log) {
1343
+ bbr->ccb.log = log;
1344
+ bbr->rst = rst;
1345
+ bbr->rand = rand;
1346
+ bbr->rand_ctx = *rand_ctx;
1347
+ bbr->initial_cwnd = cstat->cwnd;
1348
+
1349
+ bbr_on_init(bbr, cstat, initial_ts);
1350
+ }
1351
+
1352
+ static void bbr2_cc_free(ngtcp2_bbr2_cc *bbr) { (void)bbr; }
1353
+
1354
+ static void bbr2_cc_on_pkt_acked(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1355
+ const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
1356
+ (void)ccx;
1357
+ (void)cstat;
1358
+ (void)pkt;
1359
+ (void)ts;
1360
+ }
1361
+
1362
+ static void bbr2_cc_on_pkt_lost(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1363
+ const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
1364
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1365
+
1366
+ bbr_update_on_loss(bbr, cstat, pkt, ts);
1367
+ }
1368
+
1369
+ static void bbr2_cc_congestion_event(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1370
+ ngtcp2_tstamp sent_ts, ngtcp2_tstamp ts) {
1371
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1372
+
1373
+ if (!bbr->filled_pipe || bbr->in_loss_recovery ||
1374
+ bbr->congestion_recovery_start_ts != UINT64_MAX ||
1375
+ in_congestion_recovery(cstat, sent_ts)) {
1376
+ return;
1377
+ }
1378
+
1379
+ bbr->congestion_recovery_start_ts = ts;
1380
+ }
1381
+
1382
+ static void bbr2_cc_on_spurious_congestion(ngtcp2_cc *ccx,
1383
+ ngtcp2_conn_stat *cstat,
1384
+ ngtcp2_tstamp ts) {
1385
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1386
+ (void)ts;
1387
+
1388
+ bbr->congestion_recovery_start_ts = UINT64_MAX;
1389
+ cstat->congestion_recovery_start_ts = UINT64_MAX;
1390
+
1391
+ if (bbr->in_loss_recovery) {
1392
+ bbr->in_loss_recovery = 0;
1393
+ bbr->packet_conservation = 0;
1394
+ bbr_restore_cwnd(bbr, cstat);
1395
+ bbr->full_bw_count = 0;
1396
+ bbr->loss_in_round = 0;
1397
+ bbr->inflight_lo = ngtcp2_max(bbr->inflight_lo, bbr->prior_inflight_lo);
1398
+ bbr->inflight_hi = ngtcp2_max(bbr->inflight_hi, bbr->prior_inflight_hi);
1399
+ bbr->bw_lo = ngtcp2_max(bbr->bw_lo, bbr->prior_bw_lo);
1400
+ }
1401
+ }
1402
+
1403
+ static void bbr2_cc_on_persistent_congestion(ngtcp2_cc *ccx,
1404
+ ngtcp2_conn_stat *cstat,
1405
+ ngtcp2_tstamp ts) {
1406
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1407
+ (void)ts;
1408
+
1409
+ cstat->congestion_recovery_start_ts = UINT64_MAX;
1410
+ bbr->congestion_recovery_start_ts = UINT64_MAX;
1411
+ bbr->in_loss_recovery = 0;
1412
+ bbr->packet_conservation = 0;
1413
+
1414
+ bbr_save_cwnd(bbr, cstat);
1415
+ cstat->cwnd = cstat->bytes_in_flight + cstat->max_tx_udp_payload_size;
1416
+ cstat->cwnd =
1417
+ ngtcp2_max(cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
1418
+ }
1419
+
1420
+ static void bbr2_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1421
+ const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
1422
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1423
+
1424
+ bbr_update_on_ack(bbr, cstat, ack, ts);
1425
+ }
1426
+
1427
+ static void bbr2_cc_on_pkt_sent(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1428
+ const ngtcp2_cc_pkt *pkt) {
1429
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1430
+
1431
+ bbr_on_transmit(bbr, cstat, pkt->sent_ts);
1432
+ }
1433
+
1434
+ static void bbr2_cc_new_rtt_sample(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1435
+ ngtcp2_tstamp ts) {
1436
+ (void)ccx;
1437
+ (void)cstat;
1438
+ (void)ts;
1439
+ }
1440
+
1441
+ static void bbr2_cc_reset(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1442
+ ngtcp2_tstamp ts) {
1443
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(ccx->ccb, ngtcp2_bbr2_cc, ccb);
1444
+
1445
+ bbr_on_init(bbr, cstat, ts);
1446
+ }
1447
+
1448
+ static void bbr2_cc_event(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
1449
+ ngtcp2_cc_event_type event, ngtcp2_tstamp ts) {
1450
+ (void)ccx;
1451
+ (void)cstat;
1452
+ (void)event;
1453
+ (void)ts;
1454
+ }
1455
+
1456
+ int ngtcp2_cc_bbr2_cc_init(ngtcp2_cc *cc, ngtcp2_log *log,
1457
+ ngtcp2_conn_stat *cstat, ngtcp2_rst *rst,
1458
+ ngtcp2_tstamp initial_ts, ngtcp2_rand rand,
1459
+ const ngtcp2_rand_ctx *rand_ctx,
1460
+ const ngtcp2_mem *mem) {
1461
+ ngtcp2_bbr2_cc *bbr;
1462
+
1463
+ bbr = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_bbr2_cc));
1464
+ if (bbr == NULL) {
1465
+ return NGTCP2_ERR_NOMEM;
1466
+ }
1467
+
1468
+ bbr2_cc_init(bbr, cstat, rst, initial_ts, rand, rand_ctx, log);
1469
+
1470
+ cc->ccb = &bbr->ccb;
1471
+ cc->on_pkt_acked = bbr2_cc_on_pkt_acked;
1472
+ cc->on_pkt_lost = bbr2_cc_on_pkt_lost;
1473
+ cc->congestion_event = bbr2_cc_congestion_event;
1474
+ cc->on_spurious_congestion = bbr2_cc_on_spurious_congestion;
1475
+ cc->on_persistent_congestion = bbr2_cc_on_persistent_congestion;
1476
+ cc->on_ack_recv = bbr2_cc_on_ack_recv;
1477
+ cc->on_pkt_sent = bbr2_cc_on_pkt_sent;
1478
+ cc->new_rtt_sample = bbr2_cc_new_rtt_sample;
1479
+ cc->reset = bbr2_cc_reset;
1480
+ cc->event = bbr2_cc_event;
1481
+
1482
+ return 0;
1483
+ }
1484
+
1485
+ void ngtcp2_cc_bbr2_cc_free(ngtcp2_cc *cc, const ngtcp2_mem *mem) {
1486
+ ngtcp2_bbr2_cc *bbr = ngtcp2_struct_of(cc->ccb, ngtcp2_bbr2_cc, ccb);
1487
+
1488
+ bbr2_cc_free(bbr);
1489
+ ngtcp2_mem_free(mem, bbr);
1490
+ }