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,1676 @@
1
+ /*
2
+ * ngtcp2
3
+ *
4
+ * Copyright (c) 2017 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_rtb.h"
26
+
27
+ #include <assert.h>
28
+ #include <string.h>
29
+
30
+ #include "ngtcp2_macro.h"
31
+ #include "ngtcp2_conn.h"
32
+ #include "ngtcp2_log.h"
33
+ #include "ngtcp2_vec.h"
34
+ #include "ngtcp2_cc.h"
35
+ #include "ngtcp2_rcvry.h"
36
+ #include "ngtcp2_rst.h"
37
+ #include "ngtcp2_unreachable.h"
38
+
39
+ int ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem) {
40
+ *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain));
41
+ if (*pfrc == NULL) {
42
+ return NGTCP2_ERR_NOMEM;
43
+ }
44
+
45
+ ngtcp2_frame_chain_init(*pfrc);
46
+
47
+ return 0;
48
+ }
49
+
50
+ int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
51
+ ngtcp2_objalloc *objalloc) {
52
+ *pfrc = ngtcp2_objalloc_frame_chain_get(objalloc);
53
+ if (*pfrc == NULL) {
54
+ return NGTCP2_ERR_NOMEM;
55
+ }
56
+
57
+ ngtcp2_frame_chain_init(*pfrc);
58
+
59
+ return 0;
60
+ }
61
+
62
+ int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen,
63
+ const ngtcp2_mem *mem) {
64
+ *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain) + extralen);
65
+ if (*pfrc == NULL) {
66
+ return NGTCP2_ERR_NOMEM;
67
+ }
68
+
69
+ ngtcp2_frame_chain_init(*pfrc);
70
+
71
+ return 0;
72
+ }
73
+
74
+ int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc,
75
+ size_t datacnt,
76
+ ngtcp2_objalloc *objalloc,
77
+ const ngtcp2_mem *mem) {
78
+ size_t need, avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_stream);
79
+
80
+ if (datacnt > 1) {
81
+ need = sizeof(ngtcp2_vec) * (datacnt - 1);
82
+
83
+ if (need > avail) {
84
+ return ngtcp2_frame_chain_extralen_new(pfrc, need - avail, mem);
85
+ }
86
+ }
87
+
88
+ return ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
89
+ }
90
+
91
+ int ngtcp2_frame_chain_crypto_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc,
92
+ size_t datacnt,
93
+ ngtcp2_objalloc *objalloc,
94
+ const ngtcp2_mem *mem) {
95
+ size_t need, avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_crypto);
96
+
97
+ if (datacnt > 1) {
98
+ need = sizeof(ngtcp2_vec) * (datacnt - 1);
99
+
100
+ if (need > avail) {
101
+ return ngtcp2_frame_chain_extralen_new(pfrc, need - avail, mem);
102
+ }
103
+ }
104
+
105
+ return ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
106
+ }
107
+
108
+ int ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc,
109
+ const uint8_t *token,
110
+ size_t tokenlen,
111
+ ngtcp2_objalloc *objalloc,
112
+ const ngtcp2_mem *mem) {
113
+ size_t avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token);
114
+ int rv;
115
+ uint8_t *p;
116
+ ngtcp2_frame *fr;
117
+
118
+ if (tokenlen > avail) {
119
+ rv = ngtcp2_frame_chain_extralen_new(pfrc, tokenlen - avail, mem);
120
+ } else {
121
+ rv = ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
122
+ }
123
+ if (rv != 0) {
124
+ return rv;
125
+ }
126
+
127
+ fr = &(*pfrc)->fr;
128
+ fr->type = NGTCP2_FRAME_NEW_TOKEN;
129
+
130
+ p = (uint8_t *)fr + sizeof(ngtcp2_new_token);
131
+ memcpy(p, token, tokenlen);
132
+
133
+ fr->new_token.token = p;
134
+ fr->new_token.tokenlen = tokenlen;
135
+
136
+ return 0;
137
+ }
138
+
139
+ void ngtcp2_frame_chain_del(ngtcp2_frame_chain *frc, const ngtcp2_mem *mem) {
140
+ ngtcp2_frame_chain_binder *binder;
141
+
142
+ if (frc == NULL) {
143
+ return;
144
+ }
145
+
146
+ binder = frc->binder;
147
+ if (binder && --binder->refcount == 0) {
148
+ ngtcp2_mem_free(mem, binder);
149
+ }
150
+
151
+ ngtcp2_mem_free(mem, frc);
152
+ }
153
+
154
+ void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc,
155
+ ngtcp2_objalloc *objalloc,
156
+ const ngtcp2_mem *mem) {
157
+ ngtcp2_frame_chain_binder *binder;
158
+
159
+ if (frc == NULL) {
160
+ return;
161
+ }
162
+
163
+ switch (frc->fr.type) {
164
+ case NGTCP2_FRAME_STREAM:
165
+ if (frc->fr.stream.datacnt &&
166
+ sizeof(ngtcp2_vec) * (frc->fr.stream.datacnt - 1) >
167
+ sizeof(ngtcp2_frame) - sizeof(ngtcp2_stream)) {
168
+ ngtcp2_frame_chain_del(frc, mem);
169
+
170
+ return;
171
+ }
172
+
173
+ break;
174
+ case NGTCP2_FRAME_CRYPTO:
175
+ if (frc->fr.crypto.datacnt &&
176
+ sizeof(ngtcp2_vec) * (frc->fr.crypto.datacnt - 1) >
177
+ sizeof(ngtcp2_frame) - sizeof(ngtcp2_crypto)) {
178
+ ngtcp2_frame_chain_del(frc, mem);
179
+
180
+ return;
181
+ }
182
+
183
+ break;
184
+ case NGTCP2_FRAME_NEW_TOKEN:
185
+ if (frc->fr.new_token.tokenlen >
186
+ sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token)) {
187
+ ngtcp2_frame_chain_del(frc, mem);
188
+
189
+ return;
190
+ }
191
+
192
+ break;
193
+ }
194
+
195
+ binder = frc->binder;
196
+ if (binder && --binder->refcount == 0) {
197
+ ngtcp2_mem_free(mem, binder);
198
+ }
199
+
200
+ frc->binder = NULL;
201
+
202
+ ngtcp2_objalloc_frame_chain_release(objalloc, frc);
203
+ }
204
+
205
+ void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc) {
206
+ frc->next = NULL;
207
+ frc->binder = NULL;
208
+ }
209
+
210
+ void ngtcp2_frame_chain_list_objalloc_del(ngtcp2_frame_chain *frc,
211
+ ngtcp2_objalloc *objalloc,
212
+ const ngtcp2_mem *mem) {
213
+ ngtcp2_frame_chain *next;
214
+
215
+ for (; frc; frc = next) {
216
+ next = frc->next;
217
+
218
+ ngtcp2_frame_chain_objalloc_del(frc, objalloc, mem);
219
+ }
220
+ }
221
+
222
+ int ngtcp2_frame_chain_binder_new(ngtcp2_frame_chain_binder **pbinder,
223
+ const ngtcp2_mem *mem) {
224
+ *pbinder = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_frame_chain_binder));
225
+ if (*pbinder == NULL) {
226
+ return NGTCP2_ERR_NOMEM;
227
+ }
228
+
229
+ return 0;
230
+ }
231
+
232
+ int ngtcp2_bind_frame_chains(ngtcp2_frame_chain *a, ngtcp2_frame_chain *b,
233
+ const ngtcp2_mem *mem) {
234
+ ngtcp2_frame_chain_binder *binder;
235
+ int rv;
236
+
237
+ assert(b->binder == NULL);
238
+
239
+ if (a->binder == NULL) {
240
+ rv = ngtcp2_frame_chain_binder_new(&binder, mem);
241
+ if (rv != 0) {
242
+ return rv;
243
+ }
244
+
245
+ a->binder = binder;
246
+ ++a->binder->refcount;
247
+ }
248
+
249
+ b->binder = a->binder;
250
+ ++b->binder->refcount;
251
+
252
+ return 0;
253
+ }
254
+
255
+ static void rtb_entry_init(ngtcp2_rtb_entry *ent, const ngtcp2_pkt_hd *hd,
256
+ ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
257
+ size_t pktlen, uint16_t flags) {
258
+ memset(ent, 0, sizeof(*ent));
259
+
260
+ ent->hd.pkt_num = hd->pkt_num;
261
+ ent->hd.type = hd->type;
262
+ ent->hd.flags = hd->flags;
263
+ ent->frc = frc;
264
+ ent->ts = ts;
265
+ ent->lost_ts = UINT64_MAX;
266
+ ent->pktlen = pktlen;
267
+ ent->flags = flags;
268
+ ent->next = NULL;
269
+ }
270
+
271
+ int ngtcp2_rtb_entry_objalloc_new(ngtcp2_rtb_entry **pent,
272
+ const ngtcp2_pkt_hd *hd,
273
+ ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
274
+ size_t pktlen, uint16_t flags,
275
+ ngtcp2_objalloc *objalloc) {
276
+ *pent = ngtcp2_objalloc_rtb_entry_get(objalloc);
277
+ if (*pent == NULL) {
278
+ return NGTCP2_ERR_NOMEM;
279
+ }
280
+
281
+ rtb_entry_init(*pent, hd, frc, ts, pktlen, flags);
282
+
283
+ return 0;
284
+ }
285
+
286
+ void ngtcp2_rtb_entry_objalloc_del(ngtcp2_rtb_entry *ent,
287
+ ngtcp2_objalloc *objalloc,
288
+ ngtcp2_objalloc *frc_objalloc,
289
+ const ngtcp2_mem *mem) {
290
+ ngtcp2_frame_chain_list_objalloc_del(ent->frc, frc_objalloc, mem);
291
+
292
+ ent->frc = NULL;
293
+
294
+ ngtcp2_objalloc_rtb_entry_release(objalloc, ent);
295
+ }
296
+
297
+ static int greater(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
298
+ return *(int64_t *)lhs > *(int64_t *)rhs;
299
+ }
300
+
301
+ void ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_pktns_id pktns_id,
302
+ ngtcp2_strm *crypto, ngtcp2_rst *rst, ngtcp2_cc *cc,
303
+ ngtcp2_log *log, ngtcp2_qlog *qlog,
304
+ ngtcp2_objalloc *rtb_entry_objalloc,
305
+ ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
306
+ rtb->rtb_entry_objalloc = rtb_entry_objalloc;
307
+ rtb->frc_objalloc = frc_objalloc;
308
+ ngtcp2_ksl_init(&rtb->ents, greater, sizeof(int64_t), mem);
309
+ rtb->crypto = crypto;
310
+ rtb->rst = rst;
311
+ rtb->cc = cc;
312
+ rtb->log = log;
313
+ rtb->qlog = qlog;
314
+ rtb->mem = mem;
315
+ rtb->largest_acked_tx_pkt_num = -1;
316
+ rtb->num_ack_eliciting = 0;
317
+ rtb->num_retransmittable = 0;
318
+ rtb->num_pto_eliciting = 0;
319
+ rtb->probe_pkt_left = 0;
320
+ rtb->pktns_id = pktns_id;
321
+ rtb->cc_pkt_num = 0;
322
+ rtb->cc_bytes_in_flight = 0;
323
+ rtb->persistent_congestion_start_ts = UINT64_MAX;
324
+ rtb->num_lost_pkts = 0;
325
+ rtb->num_lost_pmtud_pkts = 0;
326
+ }
327
+
328
+ void ngtcp2_rtb_free(ngtcp2_rtb *rtb) {
329
+ ngtcp2_ksl_it it;
330
+
331
+ if (rtb == NULL) {
332
+ return;
333
+ }
334
+
335
+ it = ngtcp2_ksl_begin(&rtb->ents);
336
+
337
+ for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
338
+ ngtcp2_rtb_entry_objalloc_del(ngtcp2_ksl_it_get(&it),
339
+ rtb->rtb_entry_objalloc, rtb->frc_objalloc,
340
+ rtb->mem);
341
+ }
342
+
343
+ ngtcp2_ksl_free(&rtb->ents);
344
+ }
345
+
346
+ static void rtb_on_add(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
347
+ ngtcp2_conn_stat *cstat) {
348
+ ngtcp2_rst_on_pkt_sent(rtb->rst, ent, cstat);
349
+
350
+ assert(rtb->cc_pkt_num <= ent->hd.pkt_num);
351
+
352
+ cstat->bytes_in_flight += ent->pktlen;
353
+ rtb->cc_bytes_in_flight += ent->pktlen;
354
+
355
+ ngtcp2_rst_update_app_limited(rtb->rst, cstat);
356
+
357
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
358
+ ++rtb->num_ack_eliciting;
359
+ }
360
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) {
361
+ ++rtb->num_retransmittable;
362
+ }
363
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING) {
364
+ ++rtb->num_pto_eliciting;
365
+ }
366
+ }
367
+
368
+ static size_t rtb_on_remove(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
369
+ ngtcp2_conn_stat *cstat) {
370
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
371
+ assert(rtb->num_lost_pkts);
372
+ --rtb->num_lost_pkts;
373
+
374
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
375
+ assert(rtb->num_lost_pmtud_pkts);
376
+ --rtb->num_lost_pmtud_pkts;
377
+ }
378
+
379
+ return 0;
380
+ }
381
+
382
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
383
+ assert(rtb->num_ack_eliciting);
384
+ --rtb->num_ack_eliciting;
385
+ }
386
+
387
+ if ((ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) &&
388
+ !(ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED)) {
389
+ assert(rtb->num_retransmittable);
390
+ --rtb->num_retransmittable;
391
+ }
392
+
393
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING) {
394
+ assert(rtb->num_pto_eliciting);
395
+ --rtb->num_pto_eliciting;
396
+ }
397
+
398
+ if (rtb->cc_pkt_num <= ent->hd.pkt_num) {
399
+ assert(cstat->bytes_in_flight >= ent->pktlen);
400
+ cstat->bytes_in_flight -= ent->pktlen;
401
+
402
+ assert(rtb->cc_bytes_in_flight >= ent->pktlen);
403
+ rtb->cc_bytes_in_flight -= ent->pktlen;
404
+
405
+ /* If PMTUD packet is lost, we do not report the lost bytes to the
406
+ caller in order to ignore loss of PMTUD packet. */
407
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
408
+ return 0;
409
+ }
410
+
411
+ return ent->pktlen;
412
+ }
413
+
414
+ return 0;
415
+ }
416
+
417
+ /* NGTCP2_RECLAIM_FLAG_NONE indicates that no flag is set. */
418
+ #define NGTCP2_RECLAIM_FLAG_NONE 0x00u
419
+ /* NGTCP2_RECLAIM_FLAG_ON_LOSS indicates that frames are reclaimed
420
+ because of the packet loss.*/
421
+ #define NGTCP2_RECLAIM_FLAG_ON_LOSS 0x01u
422
+
423
+ /*
424
+ * rtb_reclaim_frame queues unacknowledged frames included in |ent|
425
+ * for retransmission. The re-queued frames are not deleted from
426
+ * |ent|. It returns the number of frames queued. |flags| is bitwise
427
+ * OR of 0 or more of NGTCP2_RECLAIM_FLAG_*.
428
+ */
429
+ static ngtcp2_ssize rtb_reclaim_frame(ngtcp2_rtb *rtb, uint8_t flags,
430
+ ngtcp2_conn *conn, ngtcp2_pktns *pktns,
431
+ ngtcp2_rtb_entry *ent) {
432
+ ngtcp2_frame_chain *frc, *nfrc, **pfrc = &pktns->tx.frq;
433
+ ngtcp2_frame *fr;
434
+ ngtcp2_strm *strm;
435
+ ngtcp2_range gap, range;
436
+ size_t num_reclaimed = 0;
437
+ int rv;
438
+ int streamfrq_empty;
439
+
440
+ assert(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE);
441
+
442
+ /* TODO Reconsider the order of pfrc */
443
+ for (frc = ent->frc; frc; frc = frc->next) {
444
+ fr = &frc->fr;
445
+ /* Check that a late ACK acknowledged this frame. */
446
+ if (frc->binder &&
447
+ (frc->binder->flags & NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK)) {
448
+ continue;
449
+ }
450
+ switch (frc->fr.type) {
451
+ case NGTCP2_FRAME_STREAM:
452
+ strm = ngtcp2_conn_find_stream(conn, fr->stream.stream_id);
453
+ if (strm == NULL) {
454
+ continue;
455
+ }
456
+
457
+ gap = ngtcp2_strm_get_unacked_range_after(strm, fr->stream.offset);
458
+
459
+ range.begin = fr->stream.offset;
460
+ range.end = fr->stream.offset +
461
+ ngtcp2_vec_len(fr->stream.data, fr->stream.datacnt);
462
+ range = ngtcp2_range_intersect(&range, &gap);
463
+ if (ngtcp2_range_len(&range) == 0) {
464
+ if (!fr->stream.fin) {
465
+ /* 0 length STREAM frame with offset == 0 must be
466
+ retransmitted if no non-empty data is sent to this stream
467
+ and no data in this stream is acknowledged. */
468
+ if (fr->stream.offset != 0 || fr->stream.datacnt != 0 ||
469
+ strm->tx.offset || (strm->flags & NGTCP2_STRM_FLAG_ANY_ACKED)) {
470
+ continue;
471
+ }
472
+ } else if (strm->flags & NGTCP2_STRM_FLAG_FIN_ACKED) {
473
+ continue;
474
+ }
475
+ }
476
+
477
+ if ((flags & NGTCP2_RECLAIM_FLAG_ON_LOSS) &&
478
+ ent->hd.pkt_num != strm->tx.last_lost_pkt_num) {
479
+ strm->tx.last_lost_pkt_num = ent->hd.pkt_num;
480
+ ++strm->tx.loss_count;
481
+ }
482
+
483
+ rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
484
+ &nfrc, fr->stream.datacnt, rtb->frc_objalloc, rtb->mem);
485
+ if (rv != 0) {
486
+ return rv;
487
+ }
488
+
489
+ nfrc->fr = *fr;
490
+ ngtcp2_vec_copy(nfrc->fr.stream.data, fr->stream.data,
491
+ fr->stream.datacnt);
492
+
493
+ streamfrq_empty = ngtcp2_strm_streamfrq_empty(strm);
494
+ rv = ngtcp2_strm_streamfrq_push(strm, nfrc);
495
+ if (rv != 0) {
496
+ ngtcp2_frame_chain_objalloc_del(nfrc, rtb->frc_objalloc, rtb->mem);
497
+ return rv;
498
+ }
499
+ if (!ngtcp2_strm_is_tx_queued(strm)) {
500
+ strm->cycle = ngtcp2_conn_tx_strmq_first_cycle(conn);
501
+ rv = ngtcp2_conn_tx_strmq_push(conn, strm);
502
+ if (rv != 0) {
503
+ return rv;
504
+ }
505
+ }
506
+ if (streamfrq_empty) {
507
+ ++conn->tx.strmq_nretrans;
508
+ }
509
+
510
+ ++num_reclaimed;
511
+
512
+ continue;
513
+ case NGTCP2_FRAME_CRYPTO:
514
+ /* Don't resend CRYPTO frame if the whole region it contains has
515
+ been acknowledged */
516
+ gap = ngtcp2_strm_get_unacked_range_after(rtb->crypto, fr->crypto.offset);
517
+
518
+ range.begin = fr->crypto.offset;
519
+ range.end = fr->crypto.offset +
520
+ ngtcp2_vec_len(fr->crypto.data, fr->crypto.datacnt);
521
+ range = ngtcp2_range_intersect(&range, &gap);
522
+ if (ngtcp2_range_len(&range) == 0) {
523
+ continue;
524
+ }
525
+
526
+ rv = ngtcp2_frame_chain_crypto_datacnt_objalloc_new(
527
+ &nfrc, fr->crypto.datacnt, rtb->frc_objalloc, rtb->mem);
528
+ if (rv != 0) {
529
+ return rv;
530
+ }
531
+
532
+ nfrc->fr = *fr;
533
+ ngtcp2_vec_copy(nfrc->fr.crypto.data, fr->crypto.data,
534
+ fr->crypto.datacnt);
535
+
536
+ rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL,
537
+ &nfrc->fr.crypto.offset, nfrc);
538
+ if (rv != 0) {
539
+ assert(ngtcp2_err_is_fatal(rv));
540
+ ngtcp2_frame_chain_objalloc_del(nfrc, rtb->frc_objalloc, rtb->mem);
541
+ return rv;
542
+ }
543
+
544
+ ++num_reclaimed;
545
+
546
+ continue;
547
+ case NGTCP2_FRAME_NEW_TOKEN:
548
+ rv = ngtcp2_frame_chain_new_token_objalloc_new(
549
+ &nfrc, fr->new_token.token, fr->new_token.tokenlen, rtb->frc_objalloc,
550
+ rtb->mem);
551
+ if (rv != 0) {
552
+ return rv;
553
+ }
554
+
555
+ rv = ngtcp2_bind_frame_chains(frc, nfrc, rtb->mem);
556
+ if (rv != 0) {
557
+ return rv;
558
+ }
559
+
560
+ break;
561
+ case NGTCP2_FRAME_DATAGRAM:
562
+ case NGTCP2_FRAME_DATAGRAM_LEN:
563
+ continue;
564
+ default:
565
+ rv = ngtcp2_frame_chain_objalloc_new(&nfrc, rtb->frc_objalloc);
566
+ if (rv != 0) {
567
+ return rv;
568
+ }
569
+
570
+ nfrc->fr = *fr;
571
+
572
+ rv = ngtcp2_bind_frame_chains(frc, nfrc, rtb->mem);
573
+ if (rv != 0) {
574
+ return rv;
575
+ }
576
+
577
+ break;
578
+ }
579
+
580
+ ++num_reclaimed;
581
+
582
+ nfrc->next = *pfrc;
583
+ *pfrc = nfrc;
584
+ pfrc = &nfrc->next;
585
+ }
586
+
587
+ return (ngtcp2_ssize)num_reclaimed;
588
+ }
589
+
590
+ /*
591
+ * conn_process_lost_datagram calls ngtcp2_lost_datagram callback for
592
+ * lost DATAGRAM frames.
593
+ */
594
+ static int conn_process_lost_datagram(ngtcp2_conn *conn,
595
+ ngtcp2_rtb_entry *ent) {
596
+ ngtcp2_frame_chain *frc;
597
+ int rv;
598
+
599
+ for (frc = ent->frc; frc; frc = frc->next) {
600
+ switch (frc->fr.type) {
601
+ case NGTCP2_FRAME_DATAGRAM:
602
+ case NGTCP2_FRAME_DATAGRAM_LEN:
603
+ assert(conn->callbacks.lost_datagram);
604
+
605
+ rv = conn->callbacks.lost_datagram(conn, frc->fr.datagram.dgram_id,
606
+ conn->user_data);
607
+ if (rv != 0) {
608
+ return NGTCP2_ERR_CALLBACK_FAILURE;
609
+ }
610
+ break;
611
+ }
612
+ }
613
+
614
+ return 0;
615
+ }
616
+
617
+ static int rtb_on_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_ksl_it *it,
618
+ ngtcp2_rtb_entry *ent, ngtcp2_conn_stat *cstat,
619
+ ngtcp2_conn *conn, ngtcp2_pktns *pktns,
620
+ ngtcp2_tstamp ts) {
621
+ int rv;
622
+ ngtcp2_ssize reclaimed;
623
+ ngtcp2_cc *cc = rtb->cc;
624
+ ngtcp2_cc_pkt pkt;
625
+
626
+ ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type, ent->hd.flags,
627
+ ent->ts);
628
+
629
+ if (rtb->qlog) {
630
+ ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
631
+ }
632
+
633
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
634
+ ++rtb->num_lost_pmtud_pkts;
635
+ } else if (rtb->cc->on_pkt_lost) {
636
+ cc->on_pkt_lost(cc, cstat,
637
+ ngtcp2_cc_pkt_init(&pkt, ent->hd.pkt_num, ent->pktlen,
638
+ rtb->pktns_id, ent->ts, ent->rst.lost,
639
+ ent->rst.tx_in_flight,
640
+ ent->rst.is_app_limited),
641
+ ts);
642
+ }
643
+
644
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
645
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
646
+ "pkn=%" PRId64 " has already been reclaimed on PTO",
647
+ ent->hd.pkt_num);
648
+ assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED));
649
+ assert(UINT64_MAX == ent->lost_ts);
650
+
651
+ ent->flags |= NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED;
652
+ ent->lost_ts = ts;
653
+
654
+ ++rtb->num_lost_pkts;
655
+
656
+ ngtcp2_ksl_it_next(it);
657
+
658
+ return 0;
659
+ }
660
+
661
+ if (conn->callbacks.lost_datagram &&
662
+ (ent->flags & NGTCP2_RTB_ENTRY_FLAG_DATAGRAM)) {
663
+ rv = conn_process_lost_datagram(conn, ent);
664
+ if (rv != 0) {
665
+ return rv;
666
+ }
667
+ }
668
+
669
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) {
670
+ assert(ent->frc);
671
+ assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED));
672
+ assert(UINT64_MAX == ent->lost_ts);
673
+
674
+ reclaimed =
675
+ rtb_reclaim_frame(rtb, NGTCP2_RECLAIM_FLAG_ON_LOSS, conn, pktns, ent);
676
+ if (reclaimed < 0) {
677
+ return (int)reclaimed;
678
+ }
679
+ }
680
+
681
+ ent->flags |= NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED;
682
+ ent->lost_ts = ts;
683
+
684
+ ++rtb->num_lost_pkts;
685
+
686
+ ngtcp2_ksl_it_next(it);
687
+
688
+ return 0;
689
+ }
690
+
691
+ int ngtcp2_rtb_add(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
692
+ ngtcp2_conn_stat *cstat) {
693
+ int rv;
694
+
695
+ rv = ngtcp2_ksl_insert(&rtb->ents, NULL, &ent->hd.pkt_num, ent);
696
+ if (rv != 0) {
697
+ return rv;
698
+ }
699
+
700
+ rtb_on_add(rtb, ent, cstat);
701
+
702
+ return 0;
703
+ }
704
+
705
+ ngtcp2_ksl_it ngtcp2_rtb_head(ngtcp2_rtb *rtb) {
706
+ return ngtcp2_ksl_begin(&rtb->ents);
707
+ }
708
+
709
+ static void rtb_remove(ngtcp2_rtb *rtb, ngtcp2_ksl_it *it,
710
+ ngtcp2_rtb_entry **pent, ngtcp2_rtb_entry *ent,
711
+ ngtcp2_conn_stat *cstat) {
712
+ int rv;
713
+ (void)rv;
714
+
715
+ rv = ngtcp2_ksl_remove_hint(&rtb->ents, it, it, &ent->hd.pkt_num);
716
+ assert(0 == rv);
717
+ rtb_on_remove(rtb, ent, cstat);
718
+
719
+ assert(ent->next == NULL);
720
+
721
+ ngtcp2_list_insert(ent, pent);
722
+ }
723
+
724
+ static void conn_ack_crypto_data(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
725
+ uint64_t datalen) {
726
+ ngtcp2_buf_chain **pbufchain, *bufchain;
727
+ size_t left;
728
+
729
+ for (pbufchain = &pktns->crypto.tx.data; *pbufchain;) {
730
+ left = ngtcp2_buf_len(&(*pbufchain)->buf);
731
+ if (left > datalen) {
732
+ (*pbufchain)->buf.pos += datalen;
733
+ return;
734
+ }
735
+
736
+ bufchain = *pbufchain;
737
+ *pbufchain = bufchain->next;
738
+
739
+ ngtcp2_mem_free(conn->mem, bufchain);
740
+
741
+ datalen -= left;
742
+
743
+ if (datalen == 0) {
744
+ return;
745
+ }
746
+ }
747
+
748
+ assert(datalen == 0);
749
+
750
+ return;
751
+ }
752
+
753
+ static int rtb_process_acked_pkt(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
754
+ ngtcp2_conn *conn) {
755
+ ngtcp2_frame_chain *frc;
756
+ uint64_t prev_stream_offset, stream_offset;
757
+ ngtcp2_strm *strm;
758
+ int rv;
759
+ uint64_t datalen;
760
+ ngtcp2_strm *crypto = rtb->crypto;
761
+ ngtcp2_pktns *pktns = NULL;
762
+
763
+ if ((ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) && conn->pmtud &&
764
+ conn->pmtud->tx_pkt_num <= ent->hd.pkt_num) {
765
+ ngtcp2_pmtud_probe_success(conn->pmtud, ent->pktlen);
766
+
767
+ conn->dcid.current.max_udp_payload_size =
768
+ ngtcp2_max(conn->dcid.current.max_udp_payload_size, ent->pktlen);
769
+
770
+ if (ngtcp2_pmtud_finished(conn->pmtud)) {
771
+ ngtcp2_conn_stop_pmtud(conn);
772
+ }
773
+ }
774
+
775
+ for (frc = ent->frc; frc; frc = frc->next) {
776
+ if (frc->binder) {
777
+ frc->binder->flags |= NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK;
778
+ }
779
+
780
+ switch (frc->fr.type) {
781
+ case NGTCP2_FRAME_STREAM:
782
+ strm = ngtcp2_conn_find_stream(conn, frc->fr.stream.stream_id);
783
+ if (strm == NULL) {
784
+ break;
785
+ }
786
+
787
+ strm->flags |= NGTCP2_STRM_FLAG_ANY_ACKED;
788
+
789
+ if (frc->fr.stream.fin) {
790
+ strm->flags |= NGTCP2_STRM_FLAG_FIN_ACKED;
791
+ }
792
+
793
+ prev_stream_offset = ngtcp2_strm_get_acked_offset(strm);
794
+ rv = ngtcp2_strm_ack_data(
795
+ strm, frc->fr.stream.offset,
796
+ ngtcp2_vec_len(frc->fr.stream.data, frc->fr.stream.datacnt));
797
+ if (rv != 0) {
798
+ return rv;
799
+ }
800
+
801
+ if (conn->callbacks.acked_stream_data_offset) {
802
+ stream_offset = ngtcp2_strm_get_acked_offset(strm);
803
+ datalen = stream_offset - prev_stream_offset;
804
+ if (datalen == 0 && !frc->fr.stream.fin) {
805
+ break;
806
+ }
807
+
808
+ rv = conn->callbacks.acked_stream_data_offset(
809
+ conn, strm->stream_id, prev_stream_offset, datalen, conn->user_data,
810
+ strm->stream_user_data);
811
+ if (rv != 0) {
812
+ return NGTCP2_ERR_CALLBACK_FAILURE;
813
+ }
814
+ }
815
+
816
+ rv = ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
817
+ if (rv != 0) {
818
+ return rv;
819
+ }
820
+ break;
821
+ case NGTCP2_FRAME_CRYPTO:
822
+ prev_stream_offset = ngtcp2_strm_get_acked_offset(crypto);
823
+ rv = ngtcp2_strm_ack_data(
824
+ crypto, frc->fr.crypto.offset,
825
+ ngtcp2_vec_len(frc->fr.crypto.data, frc->fr.crypto.datacnt));
826
+ if (rv != 0) {
827
+ return rv;
828
+ }
829
+
830
+ stream_offset = ngtcp2_strm_get_acked_offset(crypto);
831
+ datalen = stream_offset - prev_stream_offset;
832
+ if (datalen == 0) {
833
+ break;
834
+ }
835
+
836
+ switch (rtb->pktns_id) {
837
+ case NGTCP2_PKTNS_ID_INITIAL:
838
+ pktns = conn->in_pktns;
839
+ break;
840
+ case NGTCP2_PKTNS_ID_HANDSHAKE:
841
+ pktns = conn->hs_pktns;
842
+ break;
843
+ case NGTCP2_PKTNS_ID_APPLICATION:
844
+ pktns = &conn->pktns;
845
+ break;
846
+ default:
847
+ ngtcp2_unreachable();
848
+ }
849
+
850
+ conn_ack_crypto_data(conn, pktns, datalen);
851
+
852
+ break;
853
+ case NGTCP2_FRAME_RESET_STREAM:
854
+ strm = ngtcp2_conn_find_stream(conn, frc->fr.reset_stream.stream_id);
855
+ if (strm == NULL) {
856
+ break;
857
+ }
858
+ strm->flags |= NGTCP2_STRM_FLAG_RST_ACKED;
859
+ rv = ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
860
+ if (rv != 0) {
861
+ return rv;
862
+ }
863
+ break;
864
+ case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
865
+ ngtcp2_conn_untrack_retired_dcid_seq(conn,
866
+ frc->fr.retire_connection_id.seq);
867
+ break;
868
+ case NGTCP2_FRAME_DATAGRAM:
869
+ case NGTCP2_FRAME_DATAGRAM_LEN:
870
+ if (!conn->callbacks.ack_datagram) {
871
+ break;
872
+ }
873
+
874
+ rv = conn->callbacks.ack_datagram(conn, frc->fr.datagram.dgram_id,
875
+ conn->user_data);
876
+ if (rv != 0) {
877
+ return NGTCP2_ERR_CALLBACK_FAILURE;
878
+ }
879
+ break;
880
+ }
881
+ }
882
+ return 0;
883
+ }
884
+
885
+ static void rtb_on_pkt_acked(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
886
+ ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts) {
887
+ ngtcp2_cc *cc = rtb->cc;
888
+ ngtcp2_cc_pkt pkt;
889
+
890
+ ngtcp2_rst_update_rate_sample(rtb->rst, ent, ts);
891
+
892
+ cc->on_pkt_acked(cc, cstat,
893
+ ngtcp2_cc_pkt_init(&pkt, ent->hd.pkt_num, ent->pktlen,
894
+ rtb->pktns_id, ent->ts, ent->rst.lost,
895
+ ent->rst.tx_in_flight,
896
+ ent->rst.is_app_limited),
897
+ ts);
898
+
899
+ if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_PROBE) &&
900
+ (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
901
+ cstat->pto_count = 0;
902
+ }
903
+ }
904
+
905
+ static void conn_verify_ecn(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
906
+ ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
907
+ const ngtcp2_ack *fr, size_t ecn_acked,
908
+ ngtcp2_tstamp largest_acked_sent_ts,
909
+ ngtcp2_tstamp ts) {
910
+ if (conn->tx.ecn.state == NGTCP2_ECN_STATE_FAILED) {
911
+ return;
912
+ }
913
+
914
+ if ((ecn_acked && fr->type == NGTCP2_FRAME_ACK) ||
915
+ (fr->type == NGTCP2_FRAME_ACK_ECN &&
916
+ (pktns->rx.ecn.ack.ect0 > fr->ecn.ect0 ||
917
+ pktns->rx.ecn.ack.ect1 > fr->ecn.ect1 ||
918
+ pktns->rx.ecn.ack.ce > fr->ecn.ce ||
919
+ (fr->ecn.ect0 - pktns->rx.ecn.ack.ect0) +
920
+ (fr->ecn.ce - pktns->rx.ecn.ack.ce) <
921
+ ecn_acked ||
922
+ fr->ecn.ect0 > pktns->tx.ecn.ect0 || fr->ecn.ect1))) {
923
+ ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
924
+ "path is not ECN capable");
925
+ conn->tx.ecn.state = NGTCP2_ECN_STATE_FAILED;
926
+ return;
927
+ }
928
+
929
+ if (conn->tx.ecn.state != NGTCP2_ECN_STATE_CAPABLE && ecn_acked) {
930
+ ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "path is ECN capable");
931
+ conn->tx.ecn.state = NGTCP2_ECN_STATE_CAPABLE;
932
+ }
933
+
934
+ if (fr->type == NGTCP2_FRAME_ACK_ECN) {
935
+ if (largest_acked_sent_ts != UINT64_MAX &&
936
+ fr->ecn.ce > pktns->rx.ecn.ack.ce) {
937
+ cc->congestion_event(cc, cstat, largest_acked_sent_ts, ts);
938
+ }
939
+
940
+ pktns->rx.ecn.ack.ect0 = fr->ecn.ect0;
941
+ pktns->rx.ecn.ack.ect1 = fr->ecn.ect1;
942
+ pktns->rx.ecn.ack.ce = fr->ecn.ce;
943
+ }
944
+ }
945
+
946
+ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
947
+ ngtcp2_conn *conn, ngtcp2_pktns *pktns,
948
+ ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts);
949
+
950
+ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
951
+ ngtcp2_conn_stat *cstat, ngtcp2_conn *conn,
952
+ ngtcp2_pktns *pktns, ngtcp2_tstamp pkt_ts,
953
+ ngtcp2_tstamp ts) {
954
+ ngtcp2_rtb_entry *ent;
955
+ int64_t largest_ack = fr->largest_ack, min_ack;
956
+ size_t i;
957
+ int rv;
958
+ ngtcp2_ksl_it it;
959
+ ngtcp2_ssize num_acked = 0;
960
+ ngtcp2_tstamp largest_pkt_sent_ts = UINT64_MAX;
961
+ ngtcp2_tstamp largest_acked_sent_ts = UINT64_MAX;
962
+ int64_t pkt_num;
963
+ ngtcp2_cc *cc = rtb->cc;
964
+ ngtcp2_rtb_entry *acked_ent = NULL;
965
+ int ack_eliciting_pkt_acked = 0;
966
+ size_t ecn_acked = 0;
967
+ int verify_ecn = 0;
968
+ ngtcp2_cc_ack cc_ack = {0};
969
+ size_t num_lost_pkts = rtb->num_lost_pkts - rtb->num_lost_pmtud_pkts;
970
+
971
+ cc_ack.prior_bytes_in_flight = cstat->bytes_in_flight;
972
+ cc_ack.rtt = UINT64_MAX;
973
+
974
+ if (conn && (conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED) &&
975
+ (conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_INITIATOR) &&
976
+ largest_ack >= conn->pktns.crypto.tx.ckm->pkt_num) {
977
+ conn->flags &= (uint32_t) ~(NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED |
978
+ NGTCP2_CONN_FLAG_KEY_UPDATE_INITIATOR);
979
+ conn->crypto.key_update.confirmed_ts = ts;
980
+
981
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_CRY, "key update confirmed");
982
+ }
983
+
984
+ if (rtb->largest_acked_tx_pkt_num < largest_ack) {
985
+ rtb->largest_acked_tx_pkt_num = largest_ack;
986
+ verify_ecn = 1;
987
+ }
988
+
989
+ /* Assume that ngtcp2_pkt_validate_ack(fr) returns 0 */
990
+ it = ngtcp2_ksl_lower_bound(&rtb->ents, &largest_ack);
991
+ if (ngtcp2_ksl_it_end(&it)) {
992
+ if (conn && verify_ecn) {
993
+ conn_verify_ecn(conn, pktns, rtb->cc, cstat, fr, ecn_acked,
994
+ largest_acked_sent_ts, ts);
995
+ }
996
+ return 0;
997
+ }
998
+
999
+ min_ack = largest_ack - (int64_t)fr->first_ack_range;
1000
+
1001
+ for (; !ngtcp2_ksl_it_end(&it);) {
1002
+ pkt_num = *(int64_t *)ngtcp2_ksl_it_key(&it);
1003
+
1004
+ assert(pkt_num <= largest_ack);
1005
+
1006
+ if (pkt_num < min_ack) {
1007
+ break;
1008
+ }
1009
+
1010
+ ent = ngtcp2_ksl_it_get(&it);
1011
+
1012
+ if (largest_ack == pkt_num) {
1013
+ largest_pkt_sent_ts = ent->ts;
1014
+ }
1015
+
1016
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
1017
+ ack_eliciting_pkt_acked = 1;
1018
+ }
1019
+
1020
+ rtb_remove(rtb, &it, &acked_ent, ent, cstat);
1021
+ ++num_acked;
1022
+ }
1023
+
1024
+ for (i = 0; i < fr->rangecnt;) {
1025
+ largest_ack = min_ack - (int64_t)fr->ranges[i].gap - 2;
1026
+ min_ack = largest_ack - (int64_t)fr->ranges[i].len;
1027
+
1028
+ it = ngtcp2_ksl_lower_bound(&rtb->ents, &largest_ack);
1029
+ if (ngtcp2_ksl_it_end(&it)) {
1030
+ break;
1031
+ }
1032
+
1033
+ for (; !ngtcp2_ksl_it_end(&it);) {
1034
+ pkt_num = *(int64_t *)ngtcp2_ksl_it_key(&it);
1035
+ if (pkt_num < min_ack) {
1036
+ break;
1037
+ }
1038
+ ent = ngtcp2_ksl_it_get(&it);
1039
+
1040
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
1041
+ ack_eliciting_pkt_acked = 1;
1042
+ }
1043
+
1044
+ rtb_remove(rtb, &it, &acked_ent, ent, cstat);
1045
+ ++num_acked;
1046
+ }
1047
+
1048
+ ++i;
1049
+ }
1050
+
1051
+ if (largest_pkt_sent_ts != UINT64_MAX && ack_eliciting_pkt_acked) {
1052
+ cc_ack.rtt = pkt_ts - largest_pkt_sent_ts;
1053
+
1054
+ rv = ngtcp2_conn_update_rtt(conn, cc_ack.rtt, fr->ack_delay_unscaled, ts);
1055
+ if (rv == 0 && cc->new_rtt_sample) {
1056
+ cc->new_rtt_sample(cc, cstat, ts);
1057
+ }
1058
+ }
1059
+
1060
+ if (conn) {
1061
+ for (ent = acked_ent; ent; ent = acked_ent) {
1062
+ if (ent->hd.pkt_num >= pktns->tx.ecn.start_pkt_num &&
1063
+ (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ECN)) {
1064
+ ++ecn_acked;
1065
+ }
1066
+
1067
+ assert(largest_acked_sent_ts == UINT64_MAX ||
1068
+ largest_acked_sent_ts <= ent->ts);
1069
+
1070
+ largest_acked_sent_ts = ent->ts;
1071
+
1072
+ rv = rtb_process_acked_pkt(rtb, ent, conn);
1073
+ if (rv != 0) {
1074
+ goto fail;
1075
+ }
1076
+
1077
+ if (ent->hd.pkt_num >= rtb->cc_pkt_num) {
1078
+ assert(cc_ack.pkt_delivered <= ent->rst.delivered);
1079
+
1080
+ cc_ack.bytes_delivered += ent->pktlen;
1081
+ cc_ack.pkt_delivered = ent->rst.delivered;
1082
+ }
1083
+
1084
+ rtb_on_pkt_acked(rtb, ent, cstat, ts);
1085
+ acked_ent = ent->next;
1086
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1087
+ rtb->frc_objalloc, rtb->mem);
1088
+ }
1089
+
1090
+ if (verify_ecn) {
1091
+ conn_verify_ecn(conn, pktns, rtb->cc, cstat, fr, ecn_acked,
1092
+ largest_acked_sent_ts, ts);
1093
+ }
1094
+ } else {
1095
+ /* For unit tests */
1096
+ for (ent = acked_ent; ent; ent = acked_ent) {
1097
+ rtb_on_pkt_acked(rtb, ent, cstat, ts);
1098
+ acked_ent = ent->next;
1099
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1100
+ rtb->frc_objalloc, rtb->mem);
1101
+ }
1102
+ }
1103
+
1104
+ if (rtb->cc->on_spurious_congestion && num_lost_pkts &&
1105
+ rtb->num_lost_pkts - rtb->num_lost_pmtud_pkts == 0) {
1106
+ rtb->cc->on_spurious_congestion(cc, cstat, ts);
1107
+ }
1108
+
1109
+ ngtcp2_rst_on_ack_recv(rtb->rst, cstat, cc_ack.pkt_delivered);
1110
+
1111
+ if (conn && num_acked > 0) {
1112
+ rv = rtb_detect_lost_pkt(rtb, &cc_ack.bytes_lost, conn, pktns, cstat, ts);
1113
+ if (rv != 0) {
1114
+ return rv;
1115
+ }
1116
+ }
1117
+
1118
+ rtb->rst->lost += cc_ack.bytes_lost;
1119
+
1120
+ cc_ack.largest_acked_sent_ts = largest_acked_sent_ts;
1121
+ cc->on_ack_recv(cc, cstat, &cc_ack, ts);
1122
+
1123
+ return num_acked;
1124
+
1125
+ fail:
1126
+ for (ent = acked_ent; ent; ent = acked_ent) {
1127
+ acked_ent = ent->next;
1128
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1129
+ rtb->frc_objalloc, rtb->mem);
1130
+ }
1131
+
1132
+ return rv;
1133
+ }
1134
+
1135
+ static int rtb_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat,
1136
+ const ngtcp2_rtb_entry *ent, ngtcp2_duration loss_delay,
1137
+ size_t pkt_thres, ngtcp2_tstamp ts) {
1138
+ ngtcp2_tstamp loss_time;
1139
+
1140
+ if (ent->ts + loss_delay <= ts ||
1141
+ rtb->largest_acked_tx_pkt_num >= ent->hd.pkt_num + (int64_t)pkt_thres) {
1142
+ return 1;
1143
+ }
1144
+
1145
+ loss_time = cstat->loss_time[rtb->pktns_id];
1146
+
1147
+ if (loss_time == UINT64_MAX) {
1148
+ loss_time = ent->ts + loss_delay;
1149
+ } else {
1150
+ loss_time = ngtcp2_min(loss_time, ent->ts + loss_delay);
1151
+ }
1152
+
1153
+ cstat->loss_time[rtb->pktns_id] = loss_time;
1154
+
1155
+ return 0;
1156
+ }
1157
+
1158
+ /*
1159
+ * rtb_compute_pkt_loss_delay computes loss delay.
1160
+ */
1161
+ static ngtcp2_duration compute_pkt_loss_delay(const ngtcp2_conn_stat *cstat) {
1162
+ /* 9/8 is kTimeThreshold */
1163
+ ngtcp2_duration loss_delay =
1164
+ ngtcp2_max(cstat->latest_rtt, cstat->smoothed_rtt) * 9 / 8;
1165
+ return ngtcp2_max(loss_delay, NGTCP2_GRANULARITY);
1166
+ }
1167
+
1168
+ /*
1169
+ * conn_all_ecn_pkt_lost returns nonzero if all ECN QUIC packets are
1170
+ * lost during validation period.
1171
+ */
1172
+ static int conn_all_ecn_pkt_lost(ngtcp2_conn *conn) {
1173
+ ngtcp2_pktns *in_pktns = conn->in_pktns;
1174
+ ngtcp2_pktns *hs_pktns = conn->hs_pktns;
1175
+ ngtcp2_pktns *pktns = &conn->pktns;
1176
+
1177
+ return (!in_pktns || in_pktns->tx.ecn.validation_pkt_sent ==
1178
+ in_pktns->tx.ecn.validation_pkt_lost) &&
1179
+ (!hs_pktns || hs_pktns->tx.ecn.validation_pkt_sent ==
1180
+ hs_pktns->tx.ecn.validation_pkt_lost) &&
1181
+ pktns->tx.ecn.validation_pkt_sent == pktns->tx.ecn.validation_pkt_lost;
1182
+ }
1183
+
1184
+ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
1185
+ ngtcp2_conn *conn, ngtcp2_pktns *pktns,
1186
+ ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts) {
1187
+ ngtcp2_rtb_entry *ent;
1188
+ ngtcp2_duration loss_delay;
1189
+ ngtcp2_ksl_it it;
1190
+ ngtcp2_tstamp latest_ts, oldest_ts;
1191
+ int64_t last_lost_pkt_num;
1192
+ ngtcp2_duration loss_window, congestion_period;
1193
+ ngtcp2_cc *cc = rtb->cc;
1194
+ int rv;
1195
+ uint64_t pkt_thres =
1196
+ rtb->cc_bytes_in_flight / cstat->max_tx_udp_payload_size / 2;
1197
+ size_t ecn_pkt_lost = 0;
1198
+ ngtcp2_tstamp start_ts;
1199
+ ngtcp2_duration pto = ngtcp2_conn_compute_pto(conn, pktns);
1200
+ uint64_t bytes_lost = 0;
1201
+ ngtcp2_duration max_ack_delay;
1202
+
1203
+ pkt_thres = ngtcp2_max(pkt_thres, NGTCP2_PKT_THRESHOLD);
1204
+ pkt_thres = ngtcp2_min(pkt_thres, 256);
1205
+ cstat->loss_time[rtb->pktns_id] = UINT64_MAX;
1206
+ loss_delay = compute_pkt_loss_delay(cstat);
1207
+
1208
+ it = ngtcp2_ksl_lower_bound(&rtb->ents, &rtb->largest_acked_tx_pkt_num);
1209
+ for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
1210
+ ent = ngtcp2_ksl_it_get(&it);
1211
+
1212
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
1213
+ break;
1214
+ }
1215
+
1216
+ if (rtb_pkt_lost(rtb, cstat, ent, loss_delay, (size_t)pkt_thres, ts)) {
1217
+ /* All entries from ent are considered to be lost. */
1218
+ latest_ts = oldest_ts = ent->ts;
1219
+ last_lost_pkt_num = ent->hd.pkt_num;
1220
+ max_ack_delay = conn->remote.transport_params
1221
+ ? conn->remote.transport_params->max_ack_delay
1222
+ : 0;
1223
+
1224
+ congestion_period =
1225
+ (cstat->smoothed_rtt +
1226
+ ngtcp2_max(4 * cstat->rttvar, NGTCP2_GRANULARITY) + max_ack_delay) *
1227
+ NGTCP2_PERSISTENT_CONGESTION_THRESHOLD;
1228
+
1229
+ start_ts = ngtcp2_max(rtb->persistent_congestion_start_ts,
1230
+ cstat->first_rtt_sample_ts);
1231
+
1232
+ for (; !ngtcp2_ksl_it_end(&it);) {
1233
+ ent = ngtcp2_ksl_it_get(&it);
1234
+
1235
+ if (last_lost_pkt_num == ent->hd.pkt_num + 1 && ent->ts >= start_ts) {
1236
+ last_lost_pkt_num = ent->hd.pkt_num;
1237
+ oldest_ts = ent->ts;
1238
+ } else {
1239
+ last_lost_pkt_num = -1;
1240
+ }
1241
+
1242
+ if ((ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED)) {
1243
+ if (rtb->pktns_id != NGTCP2_PKTNS_ID_APPLICATION ||
1244
+ last_lost_pkt_num == -1 ||
1245
+ latest_ts - oldest_ts >= congestion_period) {
1246
+ break;
1247
+ }
1248
+ ngtcp2_ksl_it_next(&it);
1249
+ continue;
1250
+ }
1251
+
1252
+ if (ent->hd.pkt_num >= pktns->tx.ecn.start_pkt_num &&
1253
+ (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ECN)) {
1254
+ ++ecn_pkt_lost;
1255
+ }
1256
+
1257
+ bytes_lost += rtb_on_remove(rtb, ent, cstat);
1258
+ rv = rtb_on_pkt_lost(rtb, &it, ent, cstat, conn, pktns, ts);
1259
+ if (rv != 0) {
1260
+ return rv;
1261
+ }
1262
+ }
1263
+
1264
+ /* If only PMTUD packets are lost, do not trigger congestion
1265
+ event. */
1266
+ if (bytes_lost == 0) {
1267
+ break;
1268
+ }
1269
+
1270
+ switch (conn->tx.ecn.state) {
1271
+ case NGTCP2_ECN_STATE_TESTING:
1272
+ if (conn->tx.ecn.validation_start_ts == UINT64_MAX) {
1273
+ break;
1274
+ }
1275
+ if (ts - conn->tx.ecn.validation_start_ts < 3 * pto) {
1276
+ pktns->tx.ecn.validation_pkt_lost += ecn_pkt_lost;
1277
+ assert(pktns->tx.ecn.validation_pkt_sent >=
1278
+ pktns->tx.ecn.validation_pkt_lost);
1279
+ break;
1280
+ }
1281
+ conn->tx.ecn.state = NGTCP2_ECN_STATE_UNKNOWN;
1282
+ /* fall through */
1283
+ case NGTCP2_ECN_STATE_UNKNOWN:
1284
+ pktns->tx.ecn.validation_pkt_lost += ecn_pkt_lost;
1285
+ assert(pktns->tx.ecn.validation_pkt_sent >=
1286
+ pktns->tx.ecn.validation_pkt_lost);
1287
+ if (conn_all_ecn_pkt_lost(conn)) {
1288
+ conn->tx.ecn.state = NGTCP2_ECN_STATE_FAILED;
1289
+ }
1290
+ break;
1291
+ default:
1292
+ break;
1293
+ }
1294
+
1295
+ cc->congestion_event(cc, cstat, latest_ts, ts);
1296
+
1297
+ loss_window = latest_ts - oldest_ts;
1298
+ /* Persistent congestion situation is only evaluated for app
1299
+ * packet number space and for the packets sent after handshake
1300
+ * is confirmed. During handshake, there is not much packets
1301
+ * sent and also people seem to do lots of effort not to trigger
1302
+ * persistent congestion there, then it is a lot easier to just
1303
+ * not enable it during handshake.
1304
+ */
1305
+ if (rtb->pktns_id == NGTCP2_PKTNS_ID_APPLICATION && loss_window > 0) {
1306
+ if (loss_window >= congestion_period) {
1307
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1308
+ "persistent congestion loss_window=%" PRIu64
1309
+ " congestion_period=%" PRIu64,
1310
+ loss_window, congestion_period);
1311
+
1312
+ /* Reset min_rtt, srtt, and rttvar here. Next new RTT
1313
+ sample will be used to recalculate these values. */
1314
+ cstat->min_rtt = UINT64_MAX;
1315
+ cstat->smoothed_rtt = conn->local.settings.initial_rtt;
1316
+ cstat->rttvar = conn->local.settings.initial_rtt / 2;
1317
+ cstat->first_rtt_sample_ts = UINT64_MAX;
1318
+
1319
+ cc->on_persistent_congestion(cc, cstat, ts);
1320
+ }
1321
+ }
1322
+
1323
+ break;
1324
+ }
1325
+ }
1326
+
1327
+ ngtcp2_rtb_remove_excessive_lost_pkt(rtb, (size_t)pkt_thres);
1328
+
1329
+ if (ppkt_lost) {
1330
+ *ppkt_lost = bytes_lost;
1331
+ }
1332
+
1333
+ return 0;
1334
+ }
1335
+
1336
+ int ngtcp2_rtb_detect_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
1337
+ ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat,
1338
+ ngtcp2_tstamp ts) {
1339
+ return rtb_detect_lost_pkt(rtb, /* ppkt_lost = */ NULL, conn, pktns, cstat,
1340
+ ts);
1341
+ }
1342
+
1343
+ void ngtcp2_rtb_remove_excessive_lost_pkt(ngtcp2_rtb *rtb, size_t n) {
1344
+ ngtcp2_ksl_it it = ngtcp2_ksl_end(&rtb->ents);
1345
+ ngtcp2_rtb_entry *ent;
1346
+ int rv;
1347
+ (void)rv;
1348
+
1349
+ for (; rtb->num_lost_pkts > n;) {
1350
+ assert(ngtcp2_ksl_it_end(&it));
1351
+ ngtcp2_ksl_it_prev(&it);
1352
+ ent = ngtcp2_ksl_it_get(&it);
1353
+
1354
+ assert(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED);
1355
+
1356
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1357
+ "removing stale lost pkn=%" PRId64, ent->hd.pkt_num);
1358
+
1359
+ --rtb->num_lost_pkts;
1360
+
1361
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
1362
+ --rtb->num_lost_pmtud_pkts;
1363
+ }
1364
+
1365
+ rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
1366
+ assert(0 == rv);
1367
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1368
+ rtb->frc_objalloc, rtb->mem);
1369
+ }
1370
+ }
1371
+
1372
+ void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
1373
+ ngtcp2_tstamp ts) {
1374
+ ngtcp2_ksl_it it;
1375
+ ngtcp2_rtb_entry *ent;
1376
+ int rv;
1377
+ (void)rv;
1378
+
1379
+ if (ngtcp2_ksl_len(&rtb->ents) == 0) {
1380
+ return;
1381
+ }
1382
+
1383
+ it = ngtcp2_ksl_end(&rtb->ents);
1384
+
1385
+ for (;;) {
1386
+ assert(ngtcp2_ksl_it_end(&it));
1387
+
1388
+ ngtcp2_ksl_it_prev(&it);
1389
+ ent = ngtcp2_ksl_it_get(&it);
1390
+
1391
+ if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) ||
1392
+ ts - ent->lost_ts < pto) {
1393
+ return;
1394
+ }
1395
+
1396
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1397
+ "removing stale lost pkn=%" PRId64, ent->hd.pkt_num);
1398
+
1399
+ --rtb->num_lost_pkts;
1400
+
1401
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
1402
+ --rtb->num_lost_pmtud_pkts;
1403
+ }
1404
+
1405
+ rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
1406
+ assert(0 == rv);
1407
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1408
+ rtb->frc_objalloc, rtb->mem);
1409
+
1410
+ if (ngtcp2_ksl_len(&rtb->ents) == 0) {
1411
+ return;
1412
+ }
1413
+ }
1414
+ }
1415
+
1416
+ ngtcp2_tstamp ngtcp2_rtb_lost_pkt_ts(ngtcp2_rtb *rtb) {
1417
+ ngtcp2_ksl_it it;
1418
+ ngtcp2_rtb_entry *ent;
1419
+
1420
+ if (ngtcp2_ksl_len(&rtb->ents) == 0) {
1421
+ return UINT64_MAX;
1422
+ }
1423
+
1424
+ it = ngtcp2_ksl_end(&rtb->ents);
1425
+ ngtcp2_ksl_it_prev(&it);
1426
+ ent = ngtcp2_ksl_it_get(&it);
1427
+
1428
+ if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED)) {
1429
+ return UINT64_MAX;
1430
+ }
1431
+
1432
+ return ent->lost_ts;
1433
+ }
1434
+
1435
+ static int rtb_on_pkt_lost_resched_move(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
1436
+ ngtcp2_pktns *pktns,
1437
+ ngtcp2_rtb_entry *ent) {
1438
+ ngtcp2_frame_chain **pfrc, *frc;
1439
+ ngtcp2_stream *sfr;
1440
+ ngtcp2_strm *strm;
1441
+ int rv;
1442
+ int streamfrq_empty;
1443
+
1444
+ ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type, ent->hd.flags,
1445
+ ent->ts);
1446
+
1447
+ if (rtb->qlog) {
1448
+ ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
1449
+ }
1450
+
1451
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PROBE) {
1452
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1453
+ "pkn=%" PRId64
1454
+ " is a probe packet, no retransmission is necessary",
1455
+ ent->hd.pkt_num);
1456
+ return 0;
1457
+ }
1458
+
1459
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
1460
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1461
+ "pkn=%" PRId64
1462
+ " is a PMTUD probe packet, no retransmission is necessary",
1463
+ ent->hd.pkt_num);
1464
+ return 0;
1465
+ }
1466
+
1467
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
1468
+ --rtb->num_lost_pkts;
1469
+
1470
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
1471
+ --rtb->num_lost_pmtud_pkts;
1472
+ }
1473
+
1474
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1475
+ "pkn=%" PRId64
1476
+ " was declared lost and has already been retransmitted",
1477
+ ent->hd.pkt_num);
1478
+ return 0;
1479
+ }
1480
+
1481
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
1482
+ ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_RCV,
1483
+ "pkn=%" PRId64 " has already been reclaimed on PTO",
1484
+ ent->hd.pkt_num);
1485
+ return 0;
1486
+ }
1487
+
1488
+ if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) &&
1489
+ (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_DATAGRAM) ||
1490
+ !conn->callbacks.lost_datagram)) {
1491
+ /* PADDING only (or PADDING + ACK ) packets will have NULL
1492
+ ent->frc. */
1493
+ return 0;
1494
+ }
1495
+
1496
+ pfrc = &ent->frc;
1497
+
1498
+ for (; *pfrc;) {
1499
+ switch ((*pfrc)->fr.type) {
1500
+ case NGTCP2_FRAME_STREAM:
1501
+ frc = *pfrc;
1502
+
1503
+ *pfrc = frc->next;
1504
+ frc->next = NULL;
1505
+ sfr = &frc->fr.stream;
1506
+
1507
+ strm = ngtcp2_conn_find_stream(conn, sfr->stream_id);
1508
+ if (!strm) {
1509
+ ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
1510
+ break;
1511
+ }
1512
+ streamfrq_empty = ngtcp2_strm_streamfrq_empty(strm);
1513
+ rv = ngtcp2_strm_streamfrq_push(strm, frc);
1514
+ if (rv != 0) {
1515
+ ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
1516
+ return rv;
1517
+ }
1518
+ if (!ngtcp2_strm_is_tx_queued(strm)) {
1519
+ strm->cycle = ngtcp2_conn_tx_strmq_first_cycle(conn);
1520
+ rv = ngtcp2_conn_tx_strmq_push(conn, strm);
1521
+ if (rv != 0) {
1522
+ return rv;
1523
+ }
1524
+ }
1525
+ if (streamfrq_empty) {
1526
+ ++conn->tx.strmq_nretrans;
1527
+ }
1528
+ break;
1529
+ case NGTCP2_FRAME_CRYPTO:
1530
+ frc = *pfrc;
1531
+
1532
+ *pfrc = frc->next;
1533
+ frc->next = NULL;
1534
+
1535
+ rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL,
1536
+ &frc->fr.crypto.offset, frc);
1537
+ if (rv != 0) {
1538
+ assert(ngtcp2_err_is_fatal(rv));
1539
+ ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
1540
+ return rv;
1541
+ }
1542
+ break;
1543
+ case NGTCP2_FRAME_DATAGRAM:
1544
+ case NGTCP2_FRAME_DATAGRAM_LEN:
1545
+ frc = *pfrc;
1546
+
1547
+ if (conn->callbacks.lost_datagram) {
1548
+ rv = conn->callbacks.lost_datagram(conn, frc->fr.datagram.dgram_id,
1549
+ conn->user_data);
1550
+ if (rv != 0) {
1551
+ return NGTCP2_ERR_CALLBACK_FAILURE;
1552
+ }
1553
+ }
1554
+
1555
+ *pfrc = (*pfrc)->next;
1556
+
1557
+ ngtcp2_frame_chain_objalloc_del(frc, rtb->frc_objalloc, rtb->mem);
1558
+ break;
1559
+ default:
1560
+ pfrc = &(*pfrc)->next;
1561
+ }
1562
+ }
1563
+
1564
+ *pfrc = pktns->tx.frq;
1565
+ pktns->tx.frq = ent->frc;
1566
+ ent->frc = NULL;
1567
+
1568
+ return 0;
1569
+ }
1570
+
1571
+ int ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
1572
+ ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat) {
1573
+ ngtcp2_rtb_entry *ent;
1574
+ ngtcp2_ksl_it it;
1575
+ int rv;
1576
+
1577
+ it = ngtcp2_ksl_begin(&rtb->ents);
1578
+
1579
+ for (; !ngtcp2_ksl_it_end(&it);) {
1580
+ ent = ngtcp2_ksl_it_get(&it);
1581
+
1582
+ rtb_on_remove(rtb, ent, cstat);
1583
+ rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
1584
+ assert(0 == rv);
1585
+
1586
+ rv = rtb_on_pkt_lost_resched_move(rtb, conn, pktns, ent);
1587
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1588
+ rtb->frc_objalloc, rtb->mem);
1589
+ if (rv != 0) {
1590
+ return rv;
1591
+ }
1592
+ }
1593
+
1594
+ return 0;
1595
+ }
1596
+
1597
+ void ngtcp2_rtb_remove_early_data(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat) {
1598
+ ngtcp2_rtb_entry *ent;
1599
+ ngtcp2_ksl_it it;
1600
+ int rv;
1601
+ (void)rv;
1602
+
1603
+ it = ngtcp2_ksl_begin(&rtb->ents);
1604
+
1605
+ for (; !ngtcp2_ksl_it_end(&it);) {
1606
+ ent = ngtcp2_ksl_it_get(&it);
1607
+
1608
+ if (ent->hd.type != NGTCP2_PKT_0RTT) {
1609
+ ngtcp2_ksl_it_next(&it);
1610
+ continue;
1611
+ }
1612
+
1613
+ rtb_on_remove(rtb, ent, cstat);
1614
+ rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
1615
+ assert(0 == rv);
1616
+
1617
+ ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
1618
+ rtb->frc_objalloc, rtb->mem);
1619
+ }
1620
+ }
1621
+
1622
+ int ngtcp2_rtb_empty(ngtcp2_rtb *rtb) {
1623
+ return ngtcp2_ksl_len(&rtb->ents) == 0;
1624
+ }
1625
+
1626
+ void ngtcp2_rtb_reset_cc_state(ngtcp2_rtb *rtb, int64_t cc_pkt_num) {
1627
+ rtb->cc_pkt_num = cc_pkt_num;
1628
+ rtb->cc_bytes_in_flight = 0;
1629
+ }
1630
+
1631
+ ngtcp2_ssize ngtcp2_rtb_reclaim_on_pto(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
1632
+ ngtcp2_pktns *pktns, size_t num_pkts) {
1633
+ ngtcp2_ksl_it it;
1634
+ ngtcp2_rtb_entry *ent;
1635
+ ngtcp2_ssize reclaimed;
1636
+ size_t atmost = num_pkts;
1637
+
1638
+ it = ngtcp2_ksl_end(&rtb->ents);
1639
+ for (; !ngtcp2_ksl_it_begin(&it) && num_pkts >= 1;) {
1640
+ ngtcp2_ksl_it_prev(&it);
1641
+ ent = ngtcp2_ksl_it_get(&it);
1642
+
1643
+ if ((ent->flags & (NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED |
1644
+ NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED)) ||
1645
+ !(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE)) {
1646
+ continue;
1647
+ }
1648
+
1649
+ assert(ent->frc);
1650
+
1651
+ reclaimed =
1652
+ rtb_reclaim_frame(rtb, NGTCP2_RECLAIM_FLAG_NONE, conn, pktns, ent);
1653
+ if (reclaimed < 0) {
1654
+ return reclaimed;
1655
+ }
1656
+
1657
+ /* Mark reclaimed even if reclaimed == 0 so that we can skip it in
1658
+ the next run. */
1659
+ ent->flags |= NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED;
1660
+
1661
+ assert(rtb->num_retransmittable);
1662
+ --rtb->num_retransmittable;
1663
+
1664
+ if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING) {
1665
+ ent->flags &= (uint16_t)~NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING;
1666
+ assert(rtb->num_pto_eliciting);
1667
+ --rtb->num_pto_eliciting;
1668
+ }
1669
+
1670
+ if (reclaimed) {
1671
+ --num_pkts;
1672
+ }
1673
+ }
1674
+
1675
+ return (ngtcp2_ssize)(atmost - num_pkts);
1676
+ }