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,2527 @@
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_pkt.h"
26
+
27
+ #include <assert.h>
28
+ #include <string.h>
29
+
30
+ #include "ngtcp2_conv.h"
31
+ #include "ngtcp2_str.h"
32
+ #include "ngtcp2_macro.h"
33
+ #include "ngtcp2_cid.h"
34
+ #include "ngtcp2_mem.h"
35
+ #include "ngtcp2_vec.h"
36
+ #include "ngtcp2_unreachable.h"
37
+ #include "ngtcp2_str.h"
38
+
39
+ int ngtcp2_pkt_chain_new(ngtcp2_pkt_chain **ppc, const ngtcp2_path *path,
40
+ const ngtcp2_pkt_info *pi, const uint8_t *pkt,
41
+ size_t pktlen, size_t dgramlen, ngtcp2_tstamp ts,
42
+ const ngtcp2_mem *mem) {
43
+ *ppc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_pkt_chain) + pktlen);
44
+ if (*ppc == NULL) {
45
+ return NGTCP2_ERR_NOMEM;
46
+ }
47
+
48
+ ngtcp2_path_storage_init2(&(*ppc)->path, path);
49
+ (*ppc)->pi = *pi;
50
+ (*ppc)->next = NULL;
51
+ (*ppc)->pkt = (uint8_t *)(*ppc) + sizeof(ngtcp2_pkt_chain);
52
+ (*ppc)->pktlen = pktlen;
53
+ (*ppc)->dgramlen = dgramlen;
54
+ (*ppc)->ts = ts;
55
+
56
+ memcpy((*ppc)->pkt, pkt, pktlen);
57
+
58
+ return 0;
59
+ }
60
+
61
+ void ngtcp2_pkt_chain_del(ngtcp2_pkt_chain *pc, const ngtcp2_mem *mem) {
62
+ ngtcp2_mem_free(mem, pc);
63
+ }
64
+
65
+ int ngtcp2_pkt_decode_version_cid(ngtcp2_version_cid *dest, const uint8_t *data,
66
+ size_t datalen, size_t short_dcidlen) {
67
+ size_t len;
68
+ uint32_t version;
69
+ size_t dcidlen, scidlen;
70
+ int supported_version;
71
+
72
+ assert(datalen);
73
+
74
+ if (data[0] & NGTCP2_HEADER_FORM_BIT) {
75
+ /* 1 byte (Header Form, Fixed Bit, Long Packet Type, Type-Specific bits)
76
+ * 4 bytes Version
77
+ * 1 byte DCID Length
78
+ * 1 byte SCID Length
79
+ */
80
+ len = 1 + 4 + 1 + 1;
81
+ if (datalen < len) {
82
+ return NGTCP2_ERR_INVALID_ARGUMENT;
83
+ }
84
+
85
+ dcidlen = data[5];
86
+ len += dcidlen;
87
+ if (datalen < len) {
88
+ return NGTCP2_ERR_INVALID_ARGUMENT;
89
+ }
90
+ scidlen = data[5 + 1 + dcidlen];
91
+ len += scidlen;
92
+ if (datalen < len) {
93
+ return NGTCP2_ERR_INVALID_ARGUMENT;
94
+ }
95
+
96
+ ngtcp2_get_uint32(&version, &data[1]);
97
+
98
+ supported_version = ngtcp2_is_supported_version(version);
99
+
100
+ if (supported_version &&
101
+ (dcidlen > NGTCP2_MAX_CIDLEN || scidlen > NGTCP2_MAX_CIDLEN)) {
102
+ return NGTCP2_ERR_INVALID_ARGUMENT;
103
+ }
104
+
105
+ if (version && !supported_version &&
106
+ datalen < NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
107
+ return NGTCP2_ERR_INVALID_ARGUMENT;
108
+ }
109
+
110
+ dest->version = version;
111
+ dest->dcid = &data[6];
112
+ dest->dcidlen = dcidlen;
113
+ dest->scid = &data[6 + dcidlen + 1];
114
+ dest->scidlen = scidlen;
115
+
116
+ if (!version) {
117
+ /* VN */
118
+ return 0;
119
+ }
120
+
121
+ if (!supported_version) {
122
+ return NGTCP2_ERR_VERSION_NEGOTIATION;
123
+ }
124
+ return 0;
125
+ }
126
+
127
+ assert(short_dcidlen <= NGTCP2_MAX_CIDLEN);
128
+
129
+ len = 1 + short_dcidlen;
130
+ if (datalen < len) {
131
+ return NGTCP2_ERR_INVALID_ARGUMENT;
132
+ }
133
+
134
+ dest->version = 0;
135
+ dest->dcid = &data[1];
136
+ dest->dcidlen = short_dcidlen;
137
+ dest->scid = NULL;
138
+ dest->scidlen = 0;
139
+
140
+ return 0;
141
+ }
142
+
143
+ void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
144
+ const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
145
+ int64_t pkt_num, size_t pkt_numlen, uint32_t version,
146
+ size_t len) {
147
+ hd->flags = flags;
148
+ hd->type = type;
149
+ if (dcid) {
150
+ hd->dcid = *dcid;
151
+ } else {
152
+ ngtcp2_cid_zero(&hd->dcid);
153
+ }
154
+ if (scid) {
155
+ hd->scid = *scid;
156
+ } else {
157
+ ngtcp2_cid_zero(&hd->scid);
158
+ }
159
+ hd->pkt_num = pkt_num;
160
+ hd->token = NULL;
161
+ hd->tokenlen = 0;
162
+ hd->pkt_numlen = pkt_numlen;
163
+ hd->version = version;
164
+ hd->len = len;
165
+ }
166
+
167
+ static int has_mask(uint8_t b, uint8_t mask) { return (b & mask) == mask; }
168
+
169
+ ngtcp2_ssize ngtcp2_pkt_decode_hd_long(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
170
+ size_t pktlen) {
171
+ uint8_t type;
172
+ uint32_t version;
173
+ size_t dcil, scil;
174
+ const uint8_t *p;
175
+ size_t len = 0;
176
+ size_t n;
177
+ size_t ntokenlen = 0;
178
+ const uint8_t *token = NULL;
179
+ size_t tokenlen = 0;
180
+ uint64_t vi;
181
+ uint8_t flags = NGTCP2_PKT_FLAG_LONG_FORM;
182
+
183
+ if (pktlen < 5) {
184
+ return NGTCP2_ERR_INVALID_ARGUMENT;
185
+ }
186
+
187
+ if (!(pkt[0] & NGTCP2_HEADER_FORM_BIT)) {
188
+ return NGTCP2_ERR_INVALID_ARGUMENT;
189
+ }
190
+
191
+ ngtcp2_get_uint32(&version, &pkt[1]);
192
+
193
+ if (version == 0) {
194
+ type = NGTCP2_PKT_VERSION_NEGOTIATION;
195
+ /* Version Negotiation is not a long header packet. */
196
+ flags = NGTCP2_PKT_FLAG_NONE;
197
+ /* This must be Version Negotiation packet which lacks packet
198
+ number and payload length fields. */
199
+ len = 5 + 2;
200
+ } else {
201
+ if (!(pkt[0] & NGTCP2_FIXED_BIT_MASK)) {
202
+ flags |= NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR;
203
+ }
204
+
205
+ type = ngtcp2_pkt_get_type_long(version, pkt[0]);
206
+ switch (type) {
207
+ case 0:
208
+ return NGTCP2_ERR_INVALID_ARGUMENT;
209
+ case NGTCP2_PKT_INITIAL:
210
+ len = 1 /* Token Length */ + NGTCP2_MIN_LONG_HEADERLEN -
211
+ 1; /* Cut packet number field */
212
+ break;
213
+ case NGTCP2_PKT_RETRY:
214
+ /* Retry packet does not have packet number and length fields */
215
+ len = 5 + 2;
216
+ break;
217
+ case NGTCP2_PKT_HANDSHAKE:
218
+ case NGTCP2_PKT_0RTT:
219
+ len = NGTCP2_MIN_LONG_HEADERLEN - 1; /* Cut packet number field */
220
+ break;
221
+ default:
222
+ /* Unreachable */
223
+ ngtcp2_unreachable();
224
+ }
225
+ }
226
+
227
+ if (pktlen < len) {
228
+ return NGTCP2_ERR_INVALID_ARGUMENT;
229
+ }
230
+
231
+ p = &pkt[5];
232
+ dcil = *p;
233
+ if (dcil > NGTCP2_MAX_CIDLEN) {
234
+ /* QUIC v1 implementation never expect to receive CID length more
235
+ than NGTCP2_MAX_CIDLEN. */
236
+ return NGTCP2_ERR_INVALID_ARGUMENT;
237
+ }
238
+ len += dcil;
239
+
240
+ if (pktlen < len) {
241
+ return NGTCP2_ERR_INVALID_ARGUMENT;
242
+ }
243
+
244
+ p += 1 + dcil;
245
+ scil = *p;
246
+ if (scil > NGTCP2_MAX_CIDLEN) {
247
+ return NGTCP2_ERR_INVALID_ARGUMENT;
248
+ }
249
+ len += scil;
250
+
251
+ if (pktlen < len) {
252
+ return NGTCP2_ERR_INVALID_ARGUMENT;
253
+ }
254
+
255
+ p += 1 + scil;
256
+
257
+ if (type == NGTCP2_PKT_INITIAL) {
258
+ /* Token Length */
259
+ ntokenlen = ngtcp2_get_uvarintlen(p);
260
+ len += ntokenlen - 1;
261
+
262
+ if (pktlen < len) {
263
+ return NGTCP2_ERR_INVALID_ARGUMENT;
264
+ }
265
+
266
+ p = ngtcp2_get_uvarint(&vi, p);
267
+ if (pktlen - len < vi) {
268
+ return NGTCP2_ERR_INVALID_ARGUMENT;
269
+ }
270
+ tokenlen = (size_t)vi;
271
+ len += tokenlen;
272
+
273
+ if (tokenlen) {
274
+ token = p;
275
+ }
276
+
277
+ p += tokenlen;
278
+ }
279
+
280
+ switch (type) {
281
+ case NGTCP2_PKT_RETRY:
282
+ break;
283
+ default:
284
+ if (!(flags & NGTCP2_PKT_FLAG_LONG_FORM)) {
285
+ assert(type == NGTCP2_PKT_VERSION_NEGOTIATION);
286
+ /* Version Negotiation is not a long header packet. */
287
+ break;
288
+ }
289
+
290
+ /* Length */
291
+ n = ngtcp2_get_uvarintlen(p);
292
+ len += n - 1;
293
+
294
+ if (pktlen < len) {
295
+ return NGTCP2_ERR_INVALID_ARGUMENT;
296
+ }
297
+ }
298
+
299
+ dest->flags = flags;
300
+ dest->type = type;
301
+ dest->version = version;
302
+ dest->pkt_num = 0;
303
+ dest->pkt_numlen = 0;
304
+
305
+ p = &pkt[6];
306
+ ngtcp2_cid_init(&dest->dcid, p, dcil);
307
+ p += dcil + 1;
308
+ ngtcp2_cid_init(&dest->scid, p, scil);
309
+ p += scil;
310
+
311
+ dest->token = token;
312
+ dest->tokenlen = tokenlen;
313
+ p += ntokenlen + tokenlen;
314
+
315
+ switch (type) {
316
+ case NGTCP2_PKT_RETRY:
317
+ dest->len = 0;
318
+ break;
319
+ default:
320
+ if (!(flags & NGTCP2_PKT_FLAG_LONG_FORM)) {
321
+ assert(type == NGTCP2_PKT_VERSION_NEGOTIATION);
322
+ /* Version Negotiation is not a long header packet. */
323
+ dest->len = 0;
324
+ break;
325
+ }
326
+
327
+ p = ngtcp2_get_uvarint(&vi, p);
328
+ if (vi > SIZE_MAX) {
329
+ return NGTCP2_ERR_INVALID_ARGUMENT;
330
+ }
331
+ dest->len = (size_t)vi;
332
+ }
333
+
334
+ assert((size_t)(p - pkt) == len);
335
+
336
+ return (ngtcp2_ssize)len;
337
+ }
338
+
339
+ ngtcp2_ssize ngtcp2_pkt_decode_hd_short(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
340
+ size_t pktlen, size_t dcidlen) {
341
+ size_t len = 1 + dcidlen;
342
+ const uint8_t *p = pkt;
343
+ uint8_t flags = NGTCP2_PKT_FLAG_NONE;
344
+
345
+ assert(dcidlen <= NGTCP2_MAX_CIDLEN);
346
+
347
+ if (pktlen < len) {
348
+ return NGTCP2_ERR_INVALID_ARGUMENT;
349
+ }
350
+
351
+ if (pkt[0] & NGTCP2_HEADER_FORM_BIT) {
352
+ return NGTCP2_ERR_INVALID_ARGUMENT;
353
+ }
354
+
355
+ if (!(pkt[0] & NGTCP2_FIXED_BIT_MASK)) {
356
+ flags |= NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR;
357
+ }
358
+
359
+ p = &pkt[1];
360
+
361
+ dest->type = NGTCP2_PKT_1RTT;
362
+
363
+ ngtcp2_cid_init(&dest->dcid, p, dcidlen);
364
+ p += dcidlen;
365
+
366
+ /* Set 0 to SCID so that we don't accidentally reference it and gets
367
+ garbage. */
368
+ ngtcp2_cid_zero(&dest->scid);
369
+
370
+ dest->flags = flags;
371
+ dest->version = 0;
372
+ dest->len = 0;
373
+ dest->pkt_num = 0;
374
+ dest->pkt_numlen = 0;
375
+ dest->token = NULL;
376
+ dest->tokenlen = 0;
377
+
378
+ assert((size_t)(p - pkt) == len);
379
+
380
+ return (ngtcp2_ssize)len;
381
+ }
382
+
383
+ ngtcp2_ssize ngtcp2_pkt_encode_hd_long(uint8_t *out, size_t outlen,
384
+ const ngtcp2_pkt_hd *hd) {
385
+ uint8_t *p;
386
+ size_t len = NGTCP2_MIN_LONG_HEADERLEN + hd->dcid.datalen + hd->scid.datalen -
387
+ 2; /* NGTCP2_MIN_LONG_HEADERLEN includes 1 byte for
388
+ len and 1 byte for packet number. */
389
+
390
+ if (hd->type != NGTCP2_PKT_RETRY) {
391
+ len += NGTCP2_PKT_LENGTHLEN /* Length */ + hd->pkt_numlen;
392
+ }
393
+
394
+ if (hd->type == NGTCP2_PKT_INITIAL) {
395
+ len += ngtcp2_put_uvarintlen(hd->tokenlen) + hd->tokenlen;
396
+ }
397
+
398
+ if (outlen < len) {
399
+ return NGTCP2_ERR_NOBUF;
400
+ }
401
+
402
+ p = out;
403
+
404
+ *p = (uint8_t)(NGTCP2_HEADER_FORM_BIT |
405
+ (ngtcp2_pkt_versioned_type(hd->version, hd->type) << 4) |
406
+ (uint8_t)(hd->pkt_numlen - 1));
407
+ if (!(hd->flags & NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR)) {
408
+ *p |= NGTCP2_FIXED_BIT_MASK;
409
+ }
410
+
411
+ ++p;
412
+
413
+ p = ngtcp2_put_uint32be(p, hd->version);
414
+ *p++ = (uint8_t)hd->dcid.datalen;
415
+ if (hd->dcid.datalen) {
416
+ p = ngtcp2_cpymem(p, hd->dcid.data, hd->dcid.datalen);
417
+ }
418
+ *p++ = (uint8_t)hd->scid.datalen;
419
+ if (hd->scid.datalen) {
420
+ p = ngtcp2_cpymem(p, hd->scid.data, hd->scid.datalen);
421
+ }
422
+
423
+ if (hd->type == NGTCP2_PKT_INITIAL) {
424
+ p = ngtcp2_put_uvarint(p, hd->tokenlen);
425
+ if (hd->tokenlen) {
426
+ p = ngtcp2_cpymem(p, hd->token, hd->tokenlen);
427
+ }
428
+ }
429
+
430
+ if (hd->type != NGTCP2_PKT_RETRY) {
431
+ p = ngtcp2_put_uvarint30(p, (uint32_t)hd->len);
432
+ p = ngtcp2_put_pkt_num(p, hd->pkt_num, hd->pkt_numlen);
433
+ }
434
+
435
+ assert((size_t)(p - out) == len);
436
+
437
+ return (ngtcp2_ssize)len;
438
+ }
439
+
440
+ ngtcp2_ssize ngtcp2_pkt_encode_hd_short(uint8_t *out, size_t outlen,
441
+ const ngtcp2_pkt_hd *hd) {
442
+ uint8_t *p;
443
+ size_t len = 1 + hd->dcid.datalen + hd->pkt_numlen;
444
+
445
+ if (outlen < len) {
446
+ return NGTCP2_ERR_NOBUF;
447
+ }
448
+
449
+ p = out;
450
+
451
+ *p = (uint8_t)(hd->pkt_numlen - 1);
452
+ if (!(hd->flags & NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR)) {
453
+ *p |= NGTCP2_FIXED_BIT_MASK;
454
+ }
455
+ if (hd->flags & NGTCP2_PKT_FLAG_KEY_PHASE) {
456
+ *p |= NGTCP2_SHORT_KEY_PHASE_BIT;
457
+ }
458
+
459
+ ++p;
460
+
461
+ if (hd->dcid.datalen) {
462
+ p = ngtcp2_cpymem(p, hd->dcid.data, hd->dcid.datalen);
463
+ }
464
+
465
+ p = ngtcp2_put_pkt_num(p, hd->pkt_num, hd->pkt_numlen);
466
+
467
+ assert((size_t)(p - out) == len);
468
+
469
+ return (ngtcp2_ssize)len;
470
+ }
471
+
472
+ ngtcp2_ssize ngtcp2_pkt_decode_frame(ngtcp2_frame *dest, const uint8_t *payload,
473
+ size_t payloadlen) {
474
+ uint8_t type;
475
+
476
+ if (payloadlen == 0) {
477
+ return NGTCP2_ERR_FRAME_ENCODING;
478
+ }
479
+
480
+ type = payload[0];
481
+
482
+ switch (type) {
483
+ case NGTCP2_FRAME_PADDING:
484
+ return ngtcp2_pkt_decode_padding_frame(&dest->padding, payload, payloadlen);
485
+ case NGTCP2_FRAME_RESET_STREAM:
486
+ return ngtcp2_pkt_decode_reset_stream_frame(&dest->reset_stream, payload,
487
+ payloadlen);
488
+ case NGTCP2_FRAME_CONNECTION_CLOSE:
489
+ case NGTCP2_FRAME_CONNECTION_CLOSE_APP:
490
+ return ngtcp2_pkt_decode_connection_close_frame(&dest->connection_close,
491
+ payload, payloadlen);
492
+ case NGTCP2_FRAME_MAX_DATA:
493
+ return ngtcp2_pkt_decode_max_data_frame(&dest->max_data, payload,
494
+ payloadlen);
495
+ case NGTCP2_FRAME_MAX_STREAM_DATA:
496
+ return ngtcp2_pkt_decode_max_stream_data_frame(&dest->max_stream_data,
497
+ payload, payloadlen);
498
+ case NGTCP2_FRAME_MAX_STREAMS_BIDI:
499
+ case NGTCP2_FRAME_MAX_STREAMS_UNI:
500
+ return ngtcp2_pkt_decode_max_streams_frame(&dest->max_streams, payload,
501
+ payloadlen);
502
+ case NGTCP2_FRAME_PING:
503
+ return ngtcp2_pkt_decode_ping_frame(&dest->ping, payload, payloadlen);
504
+ case NGTCP2_FRAME_DATA_BLOCKED:
505
+ return ngtcp2_pkt_decode_data_blocked_frame(&dest->data_blocked, payload,
506
+ payloadlen);
507
+ case NGTCP2_FRAME_STREAM_DATA_BLOCKED:
508
+ return ngtcp2_pkt_decode_stream_data_blocked_frame(
509
+ &dest->stream_data_blocked, payload, payloadlen);
510
+ case NGTCP2_FRAME_STREAMS_BLOCKED_BIDI:
511
+ case NGTCP2_FRAME_STREAMS_BLOCKED_UNI:
512
+ return ngtcp2_pkt_decode_streams_blocked_frame(&dest->streams_blocked,
513
+ payload, payloadlen);
514
+ case NGTCP2_FRAME_NEW_CONNECTION_ID:
515
+ return ngtcp2_pkt_decode_new_connection_id_frame(&dest->new_connection_id,
516
+ payload, payloadlen);
517
+ case NGTCP2_FRAME_STOP_SENDING:
518
+ return ngtcp2_pkt_decode_stop_sending_frame(&dest->stop_sending, payload,
519
+ payloadlen);
520
+ case NGTCP2_FRAME_ACK:
521
+ case NGTCP2_FRAME_ACK_ECN:
522
+ return ngtcp2_pkt_decode_ack_frame(&dest->ack, payload, payloadlen);
523
+ case NGTCP2_FRAME_PATH_CHALLENGE:
524
+ return ngtcp2_pkt_decode_path_challenge_frame(&dest->path_challenge,
525
+ payload, payloadlen);
526
+ case NGTCP2_FRAME_PATH_RESPONSE:
527
+ return ngtcp2_pkt_decode_path_response_frame(&dest->path_response, payload,
528
+ payloadlen);
529
+ case NGTCP2_FRAME_CRYPTO:
530
+ return ngtcp2_pkt_decode_crypto_frame(&dest->crypto, payload, payloadlen);
531
+ case NGTCP2_FRAME_NEW_TOKEN:
532
+ return ngtcp2_pkt_decode_new_token_frame(&dest->new_token, payload,
533
+ payloadlen);
534
+ case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
535
+ return ngtcp2_pkt_decode_retire_connection_id_frame(
536
+ &dest->retire_connection_id, payload, payloadlen);
537
+ case NGTCP2_FRAME_HANDSHAKE_DONE:
538
+ return ngtcp2_pkt_decode_handshake_done_frame(&dest->handshake_done,
539
+ payload, payloadlen);
540
+ case NGTCP2_FRAME_DATAGRAM:
541
+ case NGTCP2_FRAME_DATAGRAM_LEN:
542
+ return ngtcp2_pkt_decode_datagram_frame(&dest->datagram, payload,
543
+ payloadlen);
544
+ default:
545
+ if (has_mask(type, NGTCP2_FRAME_STREAM)) {
546
+ return ngtcp2_pkt_decode_stream_frame(&dest->stream, payload, payloadlen);
547
+ }
548
+ return NGTCP2_ERR_FRAME_ENCODING;
549
+ }
550
+ }
551
+
552
+ ngtcp2_ssize ngtcp2_pkt_decode_stream_frame(ngtcp2_stream *dest,
553
+ const uint8_t *payload,
554
+ size_t payloadlen) {
555
+ uint8_t type;
556
+ size_t len = 1 + 1;
557
+ const uint8_t *p;
558
+ size_t datalen;
559
+ size_t ndatalen = 0;
560
+ size_t n;
561
+ uint64_t vi;
562
+
563
+ if (payloadlen < len) {
564
+ return NGTCP2_ERR_FRAME_ENCODING;
565
+ }
566
+
567
+ type = payload[0];
568
+
569
+ p = payload + 1;
570
+
571
+ n = ngtcp2_get_uvarintlen(p);
572
+ len += n - 1;
573
+
574
+ if (payloadlen < len) {
575
+ return NGTCP2_ERR_FRAME_ENCODING;
576
+ }
577
+
578
+ p += n;
579
+
580
+ if (type & NGTCP2_STREAM_OFF_BIT) {
581
+ ++len;
582
+ if (payloadlen < len) {
583
+ return NGTCP2_ERR_FRAME_ENCODING;
584
+ }
585
+
586
+ n = ngtcp2_get_uvarintlen(p);
587
+ len += n - 1;
588
+
589
+ if (payloadlen < len) {
590
+ return NGTCP2_ERR_FRAME_ENCODING;
591
+ }
592
+
593
+ p += n;
594
+ }
595
+
596
+ if (type & NGTCP2_STREAM_LEN_BIT) {
597
+ ++len;
598
+ if (payloadlen < len) {
599
+ return NGTCP2_ERR_FRAME_ENCODING;
600
+ }
601
+
602
+ ndatalen = ngtcp2_get_uvarintlen(p);
603
+ len += ndatalen - 1;
604
+
605
+ if (payloadlen < len) {
606
+ return NGTCP2_ERR_FRAME_ENCODING;
607
+ }
608
+
609
+ /* p = */ ngtcp2_get_uvarint(&vi, p);
610
+ if (payloadlen - len < vi) {
611
+ return NGTCP2_ERR_FRAME_ENCODING;
612
+ }
613
+ datalen = (size_t)vi;
614
+ len += datalen;
615
+ } else {
616
+ len = payloadlen;
617
+ }
618
+
619
+ p = payload + 1;
620
+
621
+ dest->type = NGTCP2_FRAME_STREAM;
622
+ dest->flags = (uint8_t)(type & ~NGTCP2_FRAME_STREAM);
623
+ dest->fin = (type & NGTCP2_STREAM_FIN_BIT) != 0;
624
+ p = ngtcp2_get_varint(&dest->stream_id, p);
625
+
626
+ if (type & NGTCP2_STREAM_OFF_BIT) {
627
+ p = ngtcp2_get_uvarint(&dest->offset, p);
628
+ } else {
629
+ dest->offset = 0;
630
+ }
631
+
632
+ if (type & NGTCP2_STREAM_LEN_BIT) {
633
+ p += ndatalen;
634
+ } else {
635
+ datalen = payloadlen - (size_t)(p - payload);
636
+ }
637
+
638
+ if (datalen) {
639
+ dest->data[0].len = datalen;
640
+ dest->data[0].base = (uint8_t *)p;
641
+ dest->datacnt = 1;
642
+ p += datalen;
643
+ } else {
644
+ dest->datacnt = 0;
645
+ }
646
+
647
+ assert((size_t)(p - payload) == len);
648
+
649
+ return (ngtcp2_ssize)len;
650
+ }
651
+
652
+ ngtcp2_ssize ngtcp2_pkt_decode_ack_frame(ngtcp2_ack *dest,
653
+ const uint8_t *payload,
654
+ size_t payloadlen) {
655
+ size_t rangecnt, max_rangecnt;
656
+ size_t nrangecnt;
657
+ size_t len = 1 + 1 + 1 + 1 + 1;
658
+ const uint8_t *p;
659
+ size_t i, j;
660
+ ngtcp2_ack_range *range;
661
+ size_t n;
662
+ uint8_t type;
663
+ uint64_t vi;
664
+
665
+ if (payloadlen < len) {
666
+ return NGTCP2_ERR_FRAME_ENCODING;
667
+ }
668
+
669
+ type = payload[0];
670
+
671
+ p = payload + 1;
672
+
673
+ /* Largest Acknowledged */
674
+ n = ngtcp2_get_uvarintlen(p);
675
+ len += n - 1;
676
+
677
+ if (payloadlen < len) {
678
+ return NGTCP2_ERR_FRAME_ENCODING;
679
+ }
680
+
681
+ p += n;
682
+
683
+ /* ACK Delay */
684
+ n = ngtcp2_get_uvarintlen(p);
685
+ len += n - 1;
686
+
687
+ if (payloadlen < len) {
688
+ return NGTCP2_ERR_FRAME_ENCODING;
689
+ }
690
+
691
+ p += n;
692
+
693
+ /* ACK Range Count */
694
+ nrangecnt = ngtcp2_get_uvarintlen(p);
695
+ len += nrangecnt - 1;
696
+
697
+ if (payloadlen < len) {
698
+ return NGTCP2_ERR_FRAME_ENCODING;
699
+ }
700
+
701
+ p = ngtcp2_get_uvarint(&vi, p);
702
+ if (vi > SIZE_MAX / (1 + 1) || payloadlen - len < vi * (1 + 1)) {
703
+ return NGTCP2_ERR_FRAME_ENCODING;
704
+ }
705
+
706
+ rangecnt = (size_t)vi;
707
+ len += rangecnt * (1 + 1);
708
+
709
+ /* First ACK Range */
710
+ n = ngtcp2_get_uvarintlen(p);
711
+ len += n - 1;
712
+
713
+ if (payloadlen < len) {
714
+ return NGTCP2_ERR_FRAME_ENCODING;
715
+ }
716
+
717
+ p += n;
718
+
719
+ for (i = 0; i < rangecnt; ++i) {
720
+ /* Gap, and Additional ACK Range */
721
+ for (j = 0; j < 2; ++j) {
722
+ n = ngtcp2_get_uvarintlen(p);
723
+ len += n - 1;
724
+
725
+ if (payloadlen < len) {
726
+ return NGTCP2_ERR_FRAME_ENCODING;
727
+ }
728
+
729
+ p += n;
730
+ }
731
+ }
732
+
733
+ if (type == NGTCP2_FRAME_ACK_ECN) {
734
+ len += 3;
735
+ if (payloadlen < len) {
736
+ return NGTCP2_ERR_FRAME_ENCODING;
737
+ }
738
+
739
+ for (i = 0; i < 3; ++i) {
740
+ n = ngtcp2_get_uvarintlen(p);
741
+ len += n - 1;
742
+
743
+ if (payloadlen < len) {
744
+ return NGTCP2_ERR_FRAME_ENCODING;
745
+ }
746
+
747
+ p += n;
748
+ }
749
+ }
750
+
751
+ /* TODO We might not decode all ranges. It could be very large. */
752
+ max_rangecnt = ngtcp2_min(NGTCP2_MAX_ACK_RANGES, rangecnt);
753
+
754
+ p = payload + 1;
755
+
756
+ dest->type = type;
757
+ p = ngtcp2_get_varint(&dest->largest_ack, p);
758
+ p = ngtcp2_get_uvarint(&dest->ack_delay, p);
759
+ /* This value will be assigned in the upper layer. */
760
+ dest->ack_delay_unscaled = 0;
761
+ dest->rangecnt = max_rangecnt;
762
+ p += nrangecnt;
763
+ p = ngtcp2_get_uvarint(&dest->first_ack_range, p);
764
+
765
+ for (i = 0; i < max_rangecnt; ++i) {
766
+ range = &dest->ranges[i];
767
+ p = ngtcp2_get_uvarint(&range->gap, p);
768
+ p = ngtcp2_get_uvarint(&range->len, p);
769
+ }
770
+ for (i = max_rangecnt; i < rangecnt; ++i) {
771
+ p += ngtcp2_get_uvarintlen(p);
772
+ p += ngtcp2_get_uvarintlen(p);
773
+ }
774
+
775
+ if (type == NGTCP2_FRAME_ACK_ECN) {
776
+ p = ngtcp2_get_uvarint(&dest->ecn.ect0, p);
777
+ p = ngtcp2_get_uvarint(&dest->ecn.ect1, p);
778
+ p = ngtcp2_get_uvarint(&dest->ecn.ce, p);
779
+ }
780
+
781
+ assert((size_t)(p - payload) == len);
782
+
783
+ return (ngtcp2_ssize)len;
784
+ }
785
+
786
+ ngtcp2_ssize ngtcp2_pkt_decode_padding_frame(ngtcp2_padding *dest,
787
+ const uint8_t *payload,
788
+ size_t payloadlen) {
789
+ const uint8_t *p, *ep;
790
+
791
+ assert(payloadlen > 0);
792
+
793
+ p = payload + 1;
794
+ ep = payload + payloadlen;
795
+
796
+ for (; p != ep && *p == NGTCP2_FRAME_PADDING; ++p)
797
+ ;
798
+
799
+ dest->type = NGTCP2_FRAME_PADDING;
800
+ dest->len = (size_t)(p - payload);
801
+
802
+ return (ngtcp2_ssize)dest->len;
803
+ }
804
+
805
+ ngtcp2_ssize ngtcp2_pkt_decode_reset_stream_frame(ngtcp2_reset_stream *dest,
806
+ const uint8_t *payload,
807
+ size_t payloadlen) {
808
+ size_t len = 1 + 1 + 1 + 1;
809
+ const uint8_t *p;
810
+ size_t n;
811
+
812
+ if (payloadlen < len) {
813
+ return NGTCP2_ERR_FRAME_ENCODING;
814
+ }
815
+
816
+ p = payload + 1;
817
+
818
+ n = ngtcp2_get_uvarintlen(p);
819
+ len += n - 1;
820
+ if (payloadlen < len) {
821
+ return NGTCP2_ERR_FRAME_ENCODING;
822
+ }
823
+ p += n;
824
+ n = ngtcp2_get_uvarintlen(p);
825
+ len += n - 1;
826
+ if (payloadlen < len) {
827
+ return NGTCP2_ERR_FRAME_ENCODING;
828
+ }
829
+ p += n;
830
+ n = ngtcp2_get_uvarintlen(p);
831
+ len += n - 1;
832
+ if (payloadlen < len) {
833
+ return NGTCP2_ERR_FRAME_ENCODING;
834
+ }
835
+
836
+ p = payload + 1;
837
+
838
+ dest->type = NGTCP2_FRAME_RESET_STREAM;
839
+ p = ngtcp2_get_varint(&dest->stream_id, p);
840
+ p = ngtcp2_get_uvarint(&dest->app_error_code, p);
841
+ p = ngtcp2_get_uvarint(&dest->final_size, p);
842
+
843
+ assert((size_t)(p - payload) == len);
844
+
845
+ return (ngtcp2_ssize)len;
846
+ }
847
+
848
+ ngtcp2_ssize ngtcp2_pkt_decode_connection_close_frame(
849
+ ngtcp2_connection_close *dest, const uint8_t *payload, size_t payloadlen) {
850
+ size_t len = 1 + 1 + 1;
851
+ const uint8_t *p;
852
+ size_t reasonlen;
853
+ size_t nreasonlen;
854
+ size_t n;
855
+ uint8_t type;
856
+ uint64_t vi;
857
+
858
+ if (payloadlen < len) {
859
+ return NGTCP2_ERR_FRAME_ENCODING;
860
+ }
861
+
862
+ type = payload[0];
863
+
864
+ p = payload + 1;
865
+
866
+ n = ngtcp2_get_uvarintlen(p);
867
+ len += n - 1;
868
+ if (payloadlen < len) {
869
+ return NGTCP2_ERR_FRAME_ENCODING;
870
+ }
871
+
872
+ p += n;
873
+
874
+ if (type == NGTCP2_FRAME_CONNECTION_CLOSE) {
875
+ ++len;
876
+
877
+ n = ngtcp2_get_uvarintlen(p);
878
+ len += n - 1;
879
+ if (payloadlen < len) {
880
+ return NGTCP2_ERR_FRAME_ENCODING;
881
+ }
882
+
883
+ p += n;
884
+ }
885
+
886
+ nreasonlen = ngtcp2_get_uvarintlen(p);
887
+ len += nreasonlen - 1;
888
+ if (payloadlen < len) {
889
+ return NGTCP2_ERR_FRAME_ENCODING;
890
+ }
891
+
892
+ p = ngtcp2_get_uvarint(&vi, p);
893
+ if (payloadlen - len < vi) {
894
+ return NGTCP2_ERR_FRAME_ENCODING;
895
+ }
896
+ reasonlen = (size_t)vi;
897
+ len += reasonlen;
898
+
899
+ p = payload + 1;
900
+
901
+ dest->type = type;
902
+ p = ngtcp2_get_uvarint(&dest->error_code, p);
903
+ if (type == NGTCP2_FRAME_CONNECTION_CLOSE) {
904
+ p = ngtcp2_get_uvarint(&dest->frame_type, p);
905
+ } else {
906
+ dest->frame_type = 0;
907
+ }
908
+ dest->reasonlen = reasonlen;
909
+ p += nreasonlen;
910
+ if (reasonlen == 0) {
911
+ dest->reason = NULL;
912
+ } else {
913
+ dest->reason = (uint8_t *)p;
914
+ p += reasonlen;
915
+ }
916
+
917
+ assert((size_t)(p - payload) == len);
918
+
919
+ return (ngtcp2_ssize)len;
920
+ }
921
+
922
+ ngtcp2_ssize ngtcp2_pkt_decode_max_data_frame(ngtcp2_max_data *dest,
923
+ const uint8_t *payload,
924
+ size_t payloadlen) {
925
+ size_t len = 1 + 1;
926
+ const uint8_t *p;
927
+ size_t n;
928
+
929
+ if (payloadlen < len) {
930
+ return NGTCP2_ERR_FRAME_ENCODING;
931
+ }
932
+
933
+ p = payload + 1;
934
+
935
+ n = ngtcp2_get_uvarintlen(p);
936
+ len += n - 1;
937
+
938
+ if (payloadlen < len) {
939
+ return NGTCP2_ERR_FRAME_ENCODING;
940
+ }
941
+
942
+ dest->type = NGTCP2_FRAME_MAX_DATA;
943
+ p = ngtcp2_get_uvarint(&dest->max_data, p);
944
+
945
+ assert((size_t)(p - payload) == len);
946
+
947
+ return (ngtcp2_ssize)len;
948
+ }
949
+
950
+ ngtcp2_ssize ngtcp2_pkt_decode_max_stream_data_frame(
951
+ ngtcp2_max_stream_data *dest, const uint8_t *payload, size_t payloadlen) {
952
+ size_t len = 1 + 1 + 1;
953
+ const uint8_t *p;
954
+ size_t n;
955
+
956
+ if (payloadlen < len) {
957
+ return NGTCP2_ERR_FRAME_ENCODING;
958
+ }
959
+
960
+ p = payload + 1;
961
+
962
+ n = ngtcp2_get_uvarintlen(p);
963
+ len += n - 1;
964
+
965
+ if (payloadlen < len) {
966
+ return NGTCP2_ERR_FRAME_ENCODING;
967
+ }
968
+
969
+ p += n;
970
+
971
+ n = ngtcp2_get_uvarintlen(p);
972
+ len += n - 1;
973
+
974
+ if (payloadlen < len) {
975
+ return NGTCP2_ERR_FRAME_ENCODING;
976
+ }
977
+
978
+ p = payload + 1;
979
+
980
+ dest->type = NGTCP2_FRAME_MAX_STREAM_DATA;
981
+ p = ngtcp2_get_varint(&dest->stream_id, p);
982
+ p = ngtcp2_get_uvarint(&dest->max_stream_data, p);
983
+
984
+ assert((size_t)(p - payload) == len);
985
+
986
+ return (ngtcp2_ssize)len;
987
+ }
988
+
989
+ ngtcp2_ssize ngtcp2_pkt_decode_max_streams_frame(ngtcp2_max_streams *dest,
990
+ const uint8_t *payload,
991
+ size_t payloadlen) {
992
+ size_t len = 1 + 1;
993
+ const uint8_t *p;
994
+ size_t n;
995
+
996
+ if (payloadlen < len) {
997
+ return NGTCP2_ERR_FRAME_ENCODING;
998
+ }
999
+
1000
+ p = payload + 1;
1001
+
1002
+ n = ngtcp2_get_uvarintlen(p);
1003
+ len += n - 1;
1004
+
1005
+ if (payloadlen < len) {
1006
+ return NGTCP2_ERR_FRAME_ENCODING;
1007
+ }
1008
+
1009
+ dest->type = payload[0];
1010
+ p = ngtcp2_get_uvarint(&dest->max_streams, p);
1011
+
1012
+ assert((size_t)(p - payload) == len);
1013
+
1014
+ return (ngtcp2_ssize)len;
1015
+ }
1016
+
1017
+ ngtcp2_ssize ngtcp2_pkt_decode_ping_frame(ngtcp2_ping *dest,
1018
+ const uint8_t *payload,
1019
+ size_t payloadlen) {
1020
+ (void)payload;
1021
+ (void)payloadlen;
1022
+
1023
+ dest->type = NGTCP2_FRAME_PING;
1024
+ return 1;
1025
+ }
1026
+
1027
+ ngtcp2_ssize ngtcp2_pkt_decode_data_blocked_frame(ngtcp2_data_blocked *dest,
1028
+ const uint8_t *payload,
1029
+ size_t payloadlen) {
1030
+ size_t len = 1 + 1;
1031
+ const uint8_t *p;
1032
+ size_t n;
1033
+
1034
+ if (payloadlen < len) {
1035
+ return NGTCP2_ERR_FRAME_ENCODING;
1036
+ }
1037
+
1038
+ p = payload + 1;
1039
+
1040
+ n = ngtcp2_get_uvarintlen(p);
1041
+ len += n - 1;
1042
+
1043
+ if (payloadlen < len) {
1044
+ return NGTCP2_ERR_FRAME_ENCODING;
1045
+ }
1046
+
1047
+ dest->type = NGTCP2_FRAME_DATA_BLOCKED;
1048
+ p = ngtcp2_get_uvarint(&dest->offset, p);
1049
+
1050
+ assert((size_t)(p - payload) == len);
1051
+
1052
+ return (ngtcp2_ssize)len;
1053
+ }
1054
+
1055
+ ngtcp2_ssize
1056
+ ngtcp2_pkt_decode_stream_data_blocked_frame(ngtcp2_stream_data_blocked *dest,
1057
+ const uint8_t *payload,
1058
+ size_t payloadlen) {
1059
+ size_t len = 1 + 1 + 1;
1060
+ const uint8_t *p;
1061
+ size_t n;
1062
+
1063
+ if (payloadlen < len) {
1064
+ return NGTCP2_ERR_FRAME_ENCODING;
1065
+ }
1066
+
1067
+ p = payload + 1;
1068
+
1069
+ n = ngtcp2_get_uvarintlen(p);
1070
+ len += n - 1;
1071
+
1072
+ if (payloadlen < len) {
1073
+ return NGTCP2_ERR_FRAME_ENCODING;
1074
+ }
1075
+
1076
+ p += n;
1077
+
1078
+ n = ngtcp2_get_uvarintlen(p);
1079
+ len += n - 1;
1080
+
1081
+ if (payloadlen < len) {
1082
+ return NGTCP2_ERR_FRAME_ENCODING;
1083
+ }
1084
+
1085
+ p = payload + 1;
1086
+
1087
+ dest->type = NGTCP2_FRAME_STREAM_DATA_BLOCKED;
1088
+ p = ngtcp2_get_varint(&dest->stream_id, p);
1089
+ p = ngtcp2_get_uvarint(&dest->offset, p);
1090
+
1091
+ assert((size_t)(p - payload) == len);
1092
+
1093
+ return (ngtcp2_ssize)len;
1094
+ }
1095
+
1096
+ ngtcp2_ssize ngtcp2_pkt_decode_streams_blocked_frame(
1097
+ ngtcp2_streams_blocked *dest, const uint8_t *payload, size_t payloadlen) {
1098
+ size_t len = 1 + 1;
1099
+ const uint8_t *p;
1100
+ size_t n;
1101
+
1102
+ if (payloadlen < len) {
1103
+ return NGTCP2_ERR_FRAME_ENCODING;
1104
+ }
1105
+
1106
+ p = payload + 1;
1107
+
1108
+ n = ngtcp2_get_uvarintlen(p);
1109
+ len += n - 1;
1110
+
1111
+ if (payloadlen < len) {
1112
+ return NGTCP2_ERR_FRAME_ENCODING;
1113
+ }
1114
+
1115
+ dest->type = payload[0];
1116
+ p = ngtcp2_get_uvarint(&dest->max_streams, p);
1117
+
1118
+ assert((size_t)(p - payload) == len);
1119
+
1120
+ return (ngtcp2_ssize)len;
1121
+ }
1122
+
1123
+ ngtcp2_ssize ngtcp2_pkt_decode_new_connection_id_frame(
1124
+ ngtcp2_new_connection_id *dest, const uint8_t *payload, size_t payloadlen) {
1125
+ size_t len = 1 + 1 + 1 + 1 + 16;
1126
+ const uint8_t *p;
1127
+ size_t n;
1128
+ size_t cil;
1129
+
1130
+ if (payloadlen < len) {
1131
+ return NGTCP2_ERR_FRAME_ENCODING;
1132
+ }
1133
+
1134
+ p = payload + 1;
1135
+
1136
+ n = ngtcp2_get_uvarintlen(p);
1137
+ len += n - 1;
1138
+ if (payloadlen < len) {
1139
+ return NGTCP2_ERR_FRAME_ENCODING;
1140
+ }
1141
+
1142
+ p += n;
1143
+
1144
+ n = ngtcp2_get_uvarintlen(p);
1145
+ len += n - 1;
1146
+ if (payloadlen < len) {
1147
+ return NGTCP2_ERR_FRAME_ENCODING;
1148
+ }
1149
+
1150
+ p += n;
1151
+
1152
+ cil = *p;
1153
+ if (cil < NGTCP2_MIN_CIDLEN || cil > NGTCP2_MAX_CIDLEN) {
1154
+ return NGTCP2_ERR_FRAME_ENCODING;
1155
+ }
1156
+
1157
+ len += cil;
1158
+ if (payloadlen < len) {
1159
+ return NGTCP2_ERR_FRAME_ENCODING;
1160
+ }
1161
+
1162
+ p = payload + 1;
1163
+
1164
+ dest->type = NGTCP2_FRAME_NEW_CONNECTION_ID;
1165
+ p = ngtcp2_get_uvarint(&dest->seq, p);
1166
+ p = ngtcp2_get_uvarint(&dest->retire_prior_to, p);
1167
+ ++p;
1168
+ ngtcp2_cid_init(&dest->cid, p, cil);
1169
+ p += cil;
1170
+ p = ngtcp2_get_bytes(dest->stateless_reset_token, p,
1171
+ NGTCP2_STATELESS_RESET_TOKENLEN);
1172
+
1173
+ assert((size_t)(p - payload) == len);
1174
+
1175
+ return (ngtcp2_ssize)len;
1176
+ }
1177
+
1178
+ ngtcp2_ssize ngtcp2_pkt_decode_stop_sending_frame(ngtcp2_stop_sending *dest,
1179
+ const uint8_t *payload,
1180
+ size_t payloadlen) {
1181
+ size_t len = 1 + 1 + 1;
1182
+ const uint8_t *p;
1183
+ size_t n;
1184
+
1185
+ if (payloadlen < len) {
1186
+ return NGTCP2_ERR_FRAME_ENCODING;
1187
+ }
1188
+
1189
+ p = payload + 1;
1190
+
1191
+ n = ngtcp2_get_uvarintlen(p);
1192
+ len += n - 1;
1193
+
1194
+ if (payloadlen < len) {
1195
+ return NGTCP2_ERR_FRAME_ENCODING;
1196
+ }
1197
+ p += n;
1198
+ n = ngtcp2_get_uvarintlen(p);
1199
+ len += n - 1;
1200
+
1201
+ if (payloadlen < len) {
1202
+ return NGTCP2_ERR_FRAME_ENCODING;
1203
+ }
1204
+
1205
+ p = payload + 1;
1206
+
1207
+ dest->type = NGTCP2_FRAME_STOP_SENDING;
1208
+ p = ngtcp2_get_varint(&dest->stream_id, p);
1209
+ p = ngtcp2_get_uvarint(&dest->app_error_code, p);
1210
+
1211
+ assert((size_t)(p - payload) == len);
1212
+
1213
+ return (ngtcp2_ssize)len;
1214
+ }
1215
+
1216
+ ngtcp2_ssize ngtcp2_pkt_decode_path_challenge_frame(ngtcp2_path_challenge *dest,
1217
+ const uint8_t *payload,
1218
+ size_t payloadlen) {
1219
+ size_t len = 1 + 8;
1220
+ const uint8_t *p;
1221
+
1222
+ if (payloadlen < len) {
1223
+ return NGTCP2_ERR_FRAME_ENCODING;
1224
+ }
1225
+
1226
+ p = payload + 1;
1227
+
1228
+ dest->type = NGTCP2_FRAME_PATH_CHALLENGE;
1229
+ ngtcp2_cpymem(dest->data, p, sizeof(dest->data));
1230
+ p += sizeof(dest->data);
1231
+
1232
+ assert((size_t)(p - payload) == len);
1233
+
1234
+ return (ngtcp2_ssize)len;
1235
+ }
1236
+
1237
+ ngtcp2_ssize ngtcp2_pkt_decode_path_response_frame(ngtcp2_path_response *dest,
1238
+ const uint8_t *payload,
1239
+ size_t payloadlen) {
1240
+ size_t len = 1 + 8;
1241
+ const uint8_t *p;
1242
+
1243
+ if (payloadlen < len) {
1244
+ return NGTCP2_ERR_FRAME_ENCODING;
1245
+ }
1246
+
1247
+ p = payload + 1;
1248
+
1249
+ dest->type = NGTCP2_FRAME_PATH_RESPONSE;
1250
+ ngtcp2_cpymem(dest->data, p, sizeof(dest->data));
1251
+ p += sizeof(dest->data);
1252
+
1253
+ assert((size_t)(p - payload) == len);
1254
+
1255
+ return (ngtcp2_ssize)len;
1256
+ }
1257
+
1258
+ ngtcp2_ssize ngtcp2_pkt_decode_crypto_frame(ngtcp2_crypto *dest,
1259
+ const uint8_t *payload,
1260
+ size_t payloadlen) {
1261
+ size_t len = 1 + 1 + 1;
1262
+ const uint8_t *p;
1263
+ size_t datalen;
1264
+ size_t ndatalen;
1265
+ size_t n;
1266
+ uint64_t vi;
1267
+
1268
+ if (payloadlen < len) {
1269
+ return NGTCP2_ERR_FRAME_ENCODING;
1270
+ }
1271
+
1272
+ p = payload + 1;
1273
+
1274
+ n = ngtcp2_get_uvarintlen(p);
1275
+ len += n - 1;
1276
+
1277
+ if (payloadlen < len) {
1278
+ return NGTCP2_ERR_FRAME_ENCODING;
1279
+ }
1280
+
1281
+ p += n;
1282
+
1283
+ ndatalen = ngtcp2_get_uvarintlen(p);
1284
+ len += ndatalen - 1;
1285
+
1286
+ if (payloadlen < len) {
1287
+ return NGTCP2_ERR_FRAME_ENCODING;
1288
+ }
1289
+
1290
+ p = ngtcp2_get_uvarint(&vi, p);
1291
+ if (payloadlen - len < vi) {
1292
+ return NGTCP2_ERR_FRAME_ENCODING;
1293
+ }
1294
+
1295
+ datalen = (size_t)vi;
1296
+ len += datalen;
1297
+
1298
+ p = payload + 1;
1299
+
1300
+ dest->type = NGTCP2_FRAME_CRYPTO;
1301
+ p = ngtcp2_get_uvarint(&dest->offset, p);
1302
+ dest->data[0].len = datalen;
1303
+ p += ndatalen;
1304
+ if (dest->data[0].len) {
1305
+ dest->data[0].base = (uint8_t *)p;
1306
+ p += dest->data[0].len;
1307
+ dest->datacnt = 1;
1308
+ } else {
1309
+ dest->data[0].base = NULL;
1310
+ dest->datacnt = 0;
1311
+ }
1312
+
1313
+ assert((size_t)(p - payload) == len);
1314
+
1315
+ return (ngtcp2_ssize)len;
1316
+ }
1317
+
1318
+ ngtcp2_ssize ngtcp2_pkt_decode_new_token_frame(ngtcp2_new_token *dest,
1319
+ const uint8_t *payload,
1320
+ size_t payloadlen) {
1321
+ size_t len = 1 + 1;
1322
+ const uint8_t *p;
1323
+ size_t n;
1324
+ size_t datalen;
1325
+ uint64_t vi;
1326
+
1327
+ if (payloadlen < len) {
1328
+ return NGTCP2_ERR_FRAME_ENCODING;
1329
+ }
1330
+
1331
+ p = payload + 1;
1332
+
1333
+ n = ngtcp2_get_uvarintlen(p);
1334
+ len += n - 1;
1335
+
1336
+ if (payloadlen < len) {
1337
+ return NGTCP2_ERR_FRAME_ENCODING;
1338
+ }
1339
+
1340
+ p = ngtcp2_get_uvarint(&vi, p);
1341
+ if (payloadlen - len < vi) {
1342
+ return NGTCP2_ERR_FRAME_ENCODING;
1343
+ }
1344
+ datalen = (size_t)vi;
1345
+ len += datalen;
1346
+
1347
+ dest->type = NGTCP2_FRAME_NEW_TOKEN;
1348
+ dest->tokenlen = datalen;
1349
+ dest->token = (uint8_t *)p;
1350
+ p += dest->tokenlen;
1351
+
1352
+ assert((size_t)(p - payload) == len);
1353
+
1354
+ return (ngtcp2_ssize)len;
1355
+ }
1356
+
1357
+ ngtcp2_ssize
1358
+ ngtcp2_pkt_decode_retire_connection_id_frame(ngtcp2_retire_connection_id *dest,
1359
+ const uint8_t *payload,
1360
+ size_t payloadlen) {
1361
+ size_t len = 1 + 1;
1362
+ const uint8_t *p;
1363
+ size_t n;
1364
+
1365
+ if (payloadlen < len) {
1366
+ return NGTCP2_ERR_FRAME_ENCODING;
1367
+ }
1368
+
1369
+ p = payload + 1;
1370
+
1371
+ n = ngtcp2_get_uvarintlen(p);
1372
+ len += n - 1;
1373
+
1374
+ if (payloadlen < len) {
1375
+ return NGTCP2_ERR_FRAME_ENCODING;
1376
+ }
1377
+
1378
+ dest->type = NGTCP2_FRAME_RETIRE_CONNECTION_ID;
1379
+ p = ngtcp2_get_uvarint(&dest->seq, p);
1380
+
1381
+ assert((size_t)(p - payload) == len);
1382
+
1383
+ return (ngtcp2_ssize)len;
1384
+ }
1385
+
1386
+ ngtcp2_ssize ngtcp2_pkt_decode_handshake_done_frame(ngtcp2_handshake_done *dest,
1387
+ const uint8_t *payload,
1388
+ size_t payloadlen) {
1389
+ (void)payload;
1390
+ (void)payloadlen;
1391
+
1392
+ dest->type = NGTCP2_FRAME_HANDSHAKE_DONE;
1393
+ return 1;
1394
+ }
1395
+
1396
+ ngtcp2_ssize ngtcp2_pkt_decode_datagram_frame(ngtcp2_datagram *dest,
1397
+ const uint8_t *payload,
1398
+ size_t payloadlen) {
1399
+ size_t len = 1;
1400
+ const uint8_t *p;
1401
+ uint8_t type;
1402
+ size_t datalen;
1403
+ size_t n;
1404
+ uint64_t vi;
1405
+
1406
+ if (payloadlen < len) {
1407
+ return NGTCP2_ERR_FRAME_ENCODING;
1408
+ }
1409
+
1410
+ type = payload[0];
1411
+
1412
+ p = payload + 1;
1413
+
1414
+ switch (type) {
1415
+ case NGTCP2_FRAME_DATAGRAM:
1416
+ datalen = payloadlen - 1;
1417
+ len = payloadlen;
1418
+ break;
1419
+ case NGTCP2_FRAME_DATAGRAM_LEN:
1420
+ ++len;
1421
+ if (payloadlen < len) {
1422
+ return NGTCP2_ERR_FRAME_ENCODING;
1423
+ }
1424
+
1425
+ n = ngtcp2_get_uvarintlen(p);
1426
+ len += n - 1;
1427
+
1428
+ if (payloadlen < len) {
1429
+ return NGTCP2_ERR_FRAME_ENCODING;
1430
+ }
1431
+
1432
+ p = ngtcp2_get_uvarint(&vi, p);
1433
+ if (payloadlen - len < vi) {
1434
+ return NGTCP2_ERR_FRAME_ENCODING;
1435
+ }
1436
+
1437
+ datalen = (size_t)vi;
1438
+ len += datalen;
1439
+ break;
1440
+ default:
1441
+ ngtcp2_unreachable();
1442
+ }
1443
+
1444
+ dest->type = type;
1445
+
1446
+ if (datalen == 0) {
1447
+ dest->datacnt = 0;
1448
+ dest->data = NULL;
1449
+ } else {
1450
+ dest->datacnt = 1;
1451
+ dest->data = dest->rdata;
1452
+ dest->rdata[0].len = datalen;
1453
+
1454
+ dest->rdata[0].base = (uint8_t *)p;
1455
+ p += datalen;
1456
+ }
1457
+
1458
+ assert((size_t)(p - payload) == len);
1459
+
1460
+ return (ngtcp2_ssize)len;
1461
+ }
1462
+
1463
+ ngtcp2_ssize ngtcp2_pkt_encode_frame(uint8_t *out, size_t outlen,
1464
+ ngtcp2_frame *fr) {
1465
+ switch (fr->type) {
1466
+ case NGTCP2_FRAME_STREAM:
1467
+ return ngtcp2_pkt_encode_stream_frame(out, outlen, &fr->stream);
1468
+ case NGTCP2_FRAME_ACK:
1469
+ case NGTCP2_FRAME_ACK_ECN:
1470
+ return ngtcp2_pkt_encode_ack_frame(out, outlen, &fr->ack);
1471
+ case NGTCP2_FRAME_PADDING:
1472
+ return ngtcp2_pkt_encode_padding_frame(out, outlen, &fr->padding);
1473
+ case NGTCP2_FRAME_RESET_STREAM:
1474
+ return ngtcp2_pkt_encode_reset_stream_frame(out, outlen, &fr->reset_stream);
1475
+ case NGTCP2_FRAME_CONNECTION_CLOSE:
1476
+ case NGTCP2_FRAME_CONNECTION_CLOSE_APP:
1477
+ return ngtcp2_pkt_encode_connection_close_frame(out, outlen,
1478
+ &fr->connection_close);
1479
+ case NGTCP2_FRAME_MAX_DATA:
1480
+ return ngtcp2_pkt_encode_max_data_frame(out, outlen, &fr->max_data);
1481
+ case NGTCP2_FRAME_MAX_STREAM_DATA:
1482
+ return ngtcp2_pkt_encode_max_stream_data_frame(out, outlen,
1483
+ &fr->max_stream_data);
1484
+ case NGTCP2_FRAME_MAX_STREAMS_BIDI:
1485
+ case NGTCP2_FRAME_MAX_STREAMS_UNI:
1486
+ return ngtcp2_pkt_encode_max_streams_frame(out, outlen, &fr->max_streams);
1487
+ case NGTCP2_FRAME_PING:
1488
+ return ngtcp2_pkt_encode_ping_frame(out, outlen, &fr->ping);
1489
+ case NGTCP2_FRAME_DATA_BLOCKED:
1490
+ return ngtcp2_pkt_encode_data_blocked_frame(out, outlen, &fr->data_blocked);
1491
+ case NGTCP2_FRAME_STREAM_DATA_BLOCKED:
1492
+ return ngtcp2_pkt_encode_stream_data_blocked_frame(
1493
+ out, outlen, &fr->stream_data_blocked);
1494
+ case NGTCP2_FRAME_STREAMS_BLOCKED_BIDI:
1495
+ case NGTCP2_FRAME_STREAMS_BLOCKED_UNI:
1496
+ return ngtcp2_pkt_encode_streams_blocked_frame(out, outlen,
1497
+ &fr->streams_blocked);
1498
+ case NGTCP2_FRAME_NEW_CONNECTION_ID:
1499
+ return ngtcp2_pkt_encode_new_connection_id_frame(out, outlen,
1500
+ &fr->new_connection_id);
1501
+ case NGTCP2_FRAME_STOP_SENDING:
1502
+ return ngtcp2_pkt_encode_stop_sending_frame(out, outlen, &fr->stop_sending);
1503
+ case NGTCP2_FRAME_PATH_CHALLENGE:
1504
+ return ngtcp2_pkt_encode_path_challenge_frame(out, outlen,
1505
+ &fr->path_challenge);
1506
+ case NGTCP2_FRAME_PATH_RESPONSE:
1507
+ return ngtcp2_pkt_encode_path_response_frame(out, outlen,
1508
+ &fr->path_response);
1509
+ case NGTCP2_FRAME_CRYPTO:
1510
+ return ngtcp2_pkt_encode_crypto_frame(out, outlen, &fr->crypto);
1511
+ case NGTCP2_FRAME_NEW_TOKEN:
1512
+ return ngtcp2_pkt_encode_new_token_frame(out, outlen, &fr->new_token);
1513
+ case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
1514
+ return ngtcp2_pkt_encode_retire_connection_id_frame(
1515
+ out, outlen, &fr->retire_connection_id);
1516
+ case NGTCP2_FRAME_HANDSHAKE_DONE:
1517
+ return ngtcp2_pkt_encode_handshake_done_frame(out, outlen,
1518
+ &fr->handshake_done);
1519
+ case NGTCP2_FRAME_DATAGRAM:
1520
+ case NGTCP2_FRAME_DATAGRAM_LEN:
1521
+ return ngtcp2_pkt_encode_datagram_frame(out, outlen, &fr->datagram);
1522
+ default:
1523
+ return NGTCP2_ERR_INVALID_ARGUMENT;
1524
+ }
1525
+ }
1526
+
1527
+ ngtcp2_ssize ngtcp2_pkt_encode_stream_frame(uint8_t *out, size_t outlen,
1528
+ ngtcp2_stream *fr) {
1529
+ size_t len = 1;
1530
+ uint8_t flags = NGTCP2_STREAM_LEN_BIT;
1531
+ uint8_t *p;
1532
+ size_t i;
1533
+ size_t datalen = 0;
1534
+
1535
+ if (fr->fin) {
1536
+ flags |= NGTCP2_STREAM_FIN_BIT;
1537
+ }
1538
+
1539
+ if (fr->offset) {
1540
+ flags |= NGTCP2_STREAM_OFF_BIT;
1541
+ len += ngtcp2_put_uvarintlen(fr->offset);
1542
+ }
1543
+
1544
+ len += ngtcp2_put_uvarintlen((uint64_t)fr->stream_id);
1545
+
1546
+ for (i = 0; i < fr->datacnt; ++i) {
1547
+ datalen += fr->data[i].len;
1548
+ }
1549
+
1550
+ len += ngtcp2_put_uvarintlen(datalen);
1551
+ len += datalen;
1552
+
1553
+ if (outlen < len) {
1554
+ return NGTCP2_ERR_NOBUF;
1555
+ }
1556
+
1557
+ p = out;
1558
+
1559
+ *p++ = flags | NGTCP2_FRAME_STREAM;
1560
+
1561
+ fr->flags = flags;
1562
+
1563
+ p = ngtcp2_put_uvarint(p, (uint64_t)fr->stream_id);
1564
+
1565
+ if (fr->offset) {
1566
+ p = ngtcp2_put_uvarint(p, fr->offset);
1567
+ }
1568
+
1569
+ p = ngtcp2_put_uvarint(p, datalen);
1570
+
1571
+ for (i = 0; i < fr->datacnt; ++i) {
1572
+ assert(fr->data[i].len);
1573
+ assert(fr->data[i].base);
1574
+ p = ngtcp2_cpymem(p, fr->data[i].base, fr->data[i].len);
1575
+ }
1576
+
1577
+ assert((size_t)(p - out) == len);
1578
+
1579
+ return (ngtcp2_ssize)len;
1580
+ }
1581
+
1582
+ ngtcp2_ssize ngtcp2_pkt_encode_ack_frame(uint8_t *out, size_t outlen,
1583
+ ngtcp2_ack *fr) {
1584
+ size_t len = 1 + ngtcp2_put_uvarintlen((uint64_t)fr->largest_ack) +
1585
+ ngtcp2_put_uvarintlen(fr->ack_delay) +
1586
+ ngtcp2_put_uvarintlen(fr->rangecnt) +
1587
+ ngtcp2_put_uvarintlen(fr->first_ack_range);
1588
+ uint8_t *p;
1589
+ size_t i;
1590
+ const ngtcp2_ack_range *range;
1591
+
1592
+ for (i = 0; i < fr->rangecnt; ++i) {
1593
+ range = &fr->ranges[i];
1594
+ len += ngtcp2_put_uvarintlen(range->gap);
1595
+ len += ngtcp2_put_uvarintlen(range->len);
1596
+ }
1597
+
1598
+ if (fr->type == NGTCP2_FRAME_ACK_ECN) {
1599
+ len += ngtcp2_put_uvarintlen(fr->ecn.ect0) +
1600
+ ngtcp2_put_uvarintlen(fr->ecn.ect1) +
1601
+ ngtcp2_put_uvarintlen(fr->ecn.ce);
1602
+ }
1603
+
1604
+ if (outlen < len) {
1605
+ return NGTCP2_ERR_NOBUF;
1606
+ }
1607
+
1608
+ p = out;
1609
+
1610
+ *p++ = fr->type;
1611
+ p = ngtcp2_put_uvarint(p, (uint64_t)fr->largest_ack);
1612
+ p = ngtcp2_put_uvarint(p, fr->ack_delay);
1613
+ p = ngtcp2_put_uvarint(p, fr->rangecnt);
1614
+ p = ngtcp2_put_uvarint(p, fr->first_ack_range);
1615
+
1616
+ for (i = 0; i < fr->rangecnt; ++i) {
1617
+ range = &fr->ranges[i];
1618
+ p = ngtcp2_put_uvarint(p, range->gap);
1619
+ p = ngtcp2_put_uvarint(p, range->len);
1620
+ }
1621
+
1622
+ if (fr->type == NGTCP2_FRAME_ACK_ECN) {
1623
+ p = ngtcp2_put_uvarint(p, fr->ecn.ect0);
1624
+ p = ngtcp2_put_uvarint(p, fr->ecn.ect1);
1625
+ p = ngtcp2_put_uvarint(p, fr->ecn.ce);
1626
+ }
1627
+
1628
+ assert((size_t)(p - out) == len);
1629
+
1630
+ return (ngtcp2_ssize)len;
1631
+ }
1632
+
1633
+ ngtcp2_ssize ngtcp2_pkt_encode_padding_frame(uint8_t *out, size_t outlen,
1634
+ const ngtcp2_padding *fr) {
1635
+ if (outlen < fr->len) {
1636
+ return NGTCP2_ERR_NOBUF;
1637
+ }
1638
+
1639
+ memset(out, 0, fr->len);
1640
+
1641
+ return (ngtcp2_ssize)fr->len;
1642
+ }
1643
+
1644
+ ngtcp2_ssize
1645
+ ngtcp2_pkt_encode_reset_stream_frame(uint8_t *out, size_t outlen,
1646
+ const ngtcp2_reset_stream *fr) {
1647
+ size_t len = 1 + ngtcp2_put_uvarintlen((uint64_t)fr->stream_id) +
1648
+ ngtcp2_put_uvarintlen(fr->app_error_code) +
1649
+ ngtcp2_put_uvarintlen(fr->final_size);
1650
+ uint8_t *p;
1651
+
1652
+ if (outlen < len) {
1653
+ return NGTCP2_ERR_NOBUF;
1654
+ }
1655
+
1656
+ p = out;
1657
+
1658
+ *p++ = NGTCP2_FRAME_RESET_STREAM;
1659
+ p = ngtcp2_put_uvarint(p, (uint64_t)fr->stream_id);
1660
+ p = ngtcp2_put_uvarint(p, fr->app_error_code);
1661
+ p = ngtcp2_put_uvarint(p, fr->final_size);
1662
+
1663
+ assert((size_t)(p - out) == len);
1664
+
1665
+ return (ngtcp2_ssize)len;
1666
+ }
1667
+
1668
+ ngtcp2_ssize
1669
+ ngtcp2_pkt_encode_connection_close_frame(uint8_t *out, size_t outlen,
1670
+ const ngtcp2_connection_close *fr) {
1671
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->error_code) +
1672
+ (fr->type == NGTCP2_FRAME_CONNECTION_CLOSE
1673
+ ? ngtcp2_put_uvarintlen(fr->frame_type)
1674
+ : 0) +
1675
+ ngtcp2_put_uvarintlen(fr->reasonlen) + fr->reasonlen;
1676
+ uint8_t *p;
1677
+
1678
+ if (outlen < len) {
1679
+ return NGTCP2_ERR_NOBUF;
1680
+ }
1681
+
1682
+ p = out;
1683
+
1684
+ *p++ = fr->type;
1685
+ p = ngtcp2_put_uvarint(p, fr->error_code);
1686
+ if (fr->type == NGTCP2_FRAME_CONNECTION_CLOSE) {
1687
+ p = ngtcp2_put_uvarint(p, fr->frame_type);
1688
+ }
1689
+ p = ngtcp2_put_uvarint(p, fr->reasonlen);
1690
+ if (fr->reasonlen) {
1691
+ p = ngtcp2_cpymem(p, fr->reason, fr->reasonlen);
1692
+ }
1693
+
1694
+ assert((size_t)(p - out) == len);
1695
+
1696
+ return (ngtcp2_ssize)len;
1697
+ }
1698
+
1699
+ ngtcp2_ssize ngtcp2_pkt_encode_max_data_frame(uint8_t *out, size_t outlen,
1700
+ const ngtcp2_max_data *fr) {
1701
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->max_data);
1702
+ uint8_t *p;
1703
+
1704
+ if (outlen < len) {
1705
+ return NGTCP2_ERR_NOBUF;
1706
+ }
1707
+
1708
+ p = out;
1709
+
1710
+ *p++ = NGTCP2_FRAME_MAX_DATA;
1711
+ p = ngtcp2_put_uvarint(p, fr->max_data);
1712
+
1713
+ assert((size_t)(p - out) == len);
1714
+
1715
+ return (ngtcp2_ssize)len;
1716
+ }
1717
+
1718
+ ngtcp2_ssize
1719
+ ngtcp2_pkt_encode_max_stream_data_frame(uint8_t *out, size_t outlen,
1720
+ const ngtcp2_max_stream_data *fr) {
1721
+ size_t len = 1 + ngtcp2_put_uvarintlen((uint64_t)fr->stream_id) +
1722
+ ngtcp2_put_uvarintlen(fr->max_stream_data);
1723
+ uint8_t *p;
1724
+
1725
+ if (outlen < len) {
1726
+ return NGTCP2_ERR_NOBUF;
1727
+ }
1728
+
1729
+ p = out;
1730
+
1731
+ *p++ = NGTCP2_FRAME_MAX_STREAM_DATA;
1732
+ p = ngtcp2_put_uvarint(p, (uint64_t)fr->stream_id);
1733
+ p = ngtcp2_put_uvarint(p, fr->max_stream_data);
1734
+
1735
+ assert((size_t)(p - out) == len);
1736
+
1737
+ return (ngtcp2_ssize)len;
1738
+ }
1739
+
1740
+ ngtcp2_ssize ngtcp2_pkt_encode_max_streams_frame(uint8_t *out, size_t outlen,
1741
+ const ngtcp2_max_streams *fr) {
1742
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->max_streams);
1743
+ uint8_t *p;
1744
+
1745
+ if (outlen < len) {
1746
+ return NGTCP2_ERR_NOBUF;
1747
+ }
1748
+
1749
+ p = out;
1750
+
1751
+ *p++ = fr->type;
1752
+ p = ngtcp2_put_uvarint(p, fr->max_streams);
1753
+
1754
+ assert((size_t)(p - out) == len);
1755
+
1756
+ return (ngtcp2_ssize)len;
1757
+ }
1758
+
1759
+ ngtcp2_ssize ngtcp2_pkt_encode_ping_frame(uint8_t *out, size_t outlen,
1760
+ const ngtcp2_ping *fr) {
1761
+ (void)fr;
1762
+
1763
+ if (outlen < 1) {
1764
+ return NGTCP2_ERR_NOBUF;
1765
+ }
1766
+
1767
+ *out++ = NGTCP2_FRAME_PING;
1768
+
1769
+ return 1;
1770
+ }
1771
+
1772
+ ngtcp2_ssize
1773
+ ngtcp2_pkt_encode_data_blocked_frame(uint8_t *out, size_t outlen,
1774
+ const ngtcp2_data_blocked *fr) {
1775
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->offset);
1776
+ uint8_t *p;
1777
+
1778
+ if (outlen < len) {
1779
+ return NGTCP2_ERR_NOBUF;
1780
+ }
1781
+
1782
+ p = out;
1783
+
1784
+ *p++ = NGTCP2_FRAME_DATA_BLOCKED;
1785
+ p = ngtcp2_put_uvarint(p, fr->offset);
1786
+
1787
+ assert((size_t)(p - out) == len);
1788
+
1789
+ return (ngtcp2_ssize)len;
1790
+ }
1791
+
1792
+ ngtcp2_ssize ngtcp2_pkt_encode_stream_data_blocked_frame(
1793
+ uint8_t *out, size_t outlen, const ngtcp2_stream_data_blocked *fr) {
1794
+ size_t len = 1 + ngtcp2_put_uvarintlen((uint64_t)fr->stream_id) +
1795
+ ngtcp2_put_uvarintlen(fr->offset);
1796
+ uint8_t *p;
1797
+
1798
+ if (outlen < len) {
1799
+ return NGTCP2_ERR_NOBUF;
1800
+ }
1801
+
1802
+ p = out;
1803
+
1804
+ *p++ = NGTCP2_FRAME_STREAM_DATA_BLOCKED;
1805
+ p = ngtcp2_put_uvarint(p, (uint64_t)fr->stream_id);
1806
+ p = ngtcp2_put_uvarint(p, fr->offset);
1807
+
1808
+ assert((size_t)(p - out) == len);
1809
+
1810
+ return (ngtcp2_ssize)len;
1811
+ }
1812
+
1813
+ ngtcp2_ssize
1814
+ ngtcp2_pkt_encode_streams_blocked_frame(uint8_t *out, size_t outlen,
1815
+ const ngtcp2_streams_blocked *fr) {
1816
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->max_streams);
1817
+ uint8_t *p;
1818
+
1819
+ if (outlen < len) {
1820
+ return NGTCP2_ERR_NOBUF;
1821
+ }
1822
+
1823
+ p = out;
1824
+
1825
+ *p++ = fr->type;
1826
+ p = ngtcp2_put_uvarint(p, fr->max_streams);
1827
+
1828
+ assert((size_t)(p - out) == len);
1829
+
1830
+ return (ngtcp2_ssize)len;
1831
+ }
1832
+
1833
+ ngtcp2_ssize
1834
+ ngtcp2_pkt_encode_new_connection_id_frame(uint8_t *out, size_t outlen,
1835
+ const ngtcp2_new_connection_id *fr) {
1836
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->seq) +
1837
+ ngtcp2_put_uvarintlen(fr->retire_prior_to) + 1 +
1838
+ fr->cid.datalen + NGTCP2_STATELESS_RESET_TOKENLEN;
1839
+ uint8_t *p;
1840
+
1841
+ if (outlen < len) {
1842
+ return NGTCP2_ERR_NOBUF;
1843
+ }
1844
+
1845
+ p = out;
1846
+
1847
+ *p++ = NGTCP2_FRAME_NEW_CONNECTION_ID;
1848
+ p = ngtcp2_put_uvarint(p, fr->seq);
1849
+ p = ngtcp2_put_uvarint(p, fr->retire_prior_to);
1850
+ *p++ = (uint8_t)fr->cid.datalen;
1851
+ p = ngtcp2_cpymem(p, fr->cid.data, fr->cid.datalen);
1852
+ p = ngtcp2_cpymem(p, fr->stateless_reset_token,
1853
+ NGTCP2_STATELESS_RESET_TOKENLEN);
1854
+
1855
+ assert((size_t)(p - out) == len);
1856
+
1857
+ return (ngtcp2_ssize)len;
1858
+ }
1859
+
1860
+ ngtcp2_ssize
1861
+ ngtcp2_pkt_encode_stop_sending_frame(uint8_t *out, size_t outlen,
1862
+ const ngtcp2_stop_sending *fr) {
1863
+ size_t len = 1 + ngtcp2_put_uvarintlen((uint64_t)fr->stream_id) +
1864
+ ngtcp2_put_uvarintlen(fr->app_error_code);
1865
+ uint8_t *p;
1866
+
1867
+ if (outlen < len) {
1868
+ return NGTCP2_ERR_NOBUF;
1869
+ }
1870
+
1871
+ p = out;
1872
+
1873
+ *p++ = NGTCP2_FRAME_STOP_SENDING;
1874
+ p = ngtcp2_put_uvarint(p, (uint64_t)fr->stream_id);
1875
+ p = ngtcp2_put_uvarint(p, fr->app_error_code);
1876
+
1877
+ assert((size_t)(p - out) == len);
1878
+
1879
+ return (ngtcp2_ssize)len;
1880
+ }
1881
+
1882
+ ngtcp2_ssize
1883
+ ngtcp2_pkt_encode_path_challenge_frame(uint8_t *out, size_t outlen,
1884
+ const ngtcp2_path_challenge *fr) {
1885
+ size_t len = 1 + 8;
1886
+ uint8_t *p;
1887
+
1888
+ if (outlen < len) {
1889
+ return NGTCP2_ERR_NOBUF;
1890
+ }
1891
+
1892
+ p = out;
1893
+
1894
+ *p++ = NGTCP2_FRAME_PATH_CHALLENGE;
1895
+ p = ngtcp2_cpymem(p, fr->data, sizeof(fr->data));
1896
+
1897
+ assert((size_t)(p - out) == len);
1898
+
1899
+ return (ngtcp2_ssize)len;
1900
+ }
1901
+
1902
+ ngtcp2_ssize
1903
+ ngtcp2_pkt_encode_path_response_frame(uint8_t *out, size_t outlen,
1904
+ const ngtcp2_path_response *fr) {
1905
+ size_t len = 1 + 8;
1906
+ uint8_t *p;
1907
+
1908
+ if (outlen < len) {
1909
+ return NGTCP2_ERR_NOBUF;
1910
+ }
1911
+
1912
+ p = out;
1913
+
1914
+ *p++ = NGTCP2_FRAME_PATH_RESPONSE;
1915
+ p = ngtcp2_cpymem(p, fr->data, sizeof(fr->data));
1916
+
1917
+ assert((size_t)(p - out) == len);
1918
+
1919
+ return (ngtcp2_ssize)len;
1920
+ }
1921
+
1922
+ ngtcp2_ssize ngtcp2_pkt_encode_crypto_frame(uint8_t *out, size_t outlen,
1923
+ const ngtcp2_crypto *fr) {
1924
+ size_t len = 1;
1925
+ uint8_t *p;
1926
+ size_t i;
1927
+ size_t datalen = 0;
1928
+
1929
+ len += ngtcp2_put_uvarintlen(fr->offset);
1930
+
1931
+ for (i = 0; i < fr->datacnt; ++i) {
1932
+ datalen += fr->data[i].len;
1933
+ }
1934
+
1935
+ len += ngtcp2_put_uvarintlen(datalen);
1936
+ len += datalen;
1937
+
1938
+ if (outlen < len) {
1939
+ return NGTCP2_ERR_NOBUF;
1940
+ }
1941
+
1942
+ p = out;
1943
+
1944
+ *p++ = NGTCP2_FRAME_CRYPTO;
1945
+
1946
+ p = ngtcp2_put_uvarint(p, fr->offset);
1947
+ p = ngtcp2_put_uvarint(p, datalen);
1948
+
1949
+ for (i = 0; i < fr->datacnt; ++i) {
1950
+ assert(fr->data[i].base);
1951
+ p = ngtcp2_cpymem(p, fr->data[i].base, fr->data[i].len);
1952
+ }
1953
+
1954
+ assert((size_t)(p - out) == len);
1955
+
1956
+ return (ngtcp2_ssize)len;
1957
+ }
1958
+
1959
+ ngtcp2_ssize ngtcp2_pkt_encode_new_token_frame(uint8_t *out, size_t outlen,
1960
+ const ngtcp2_new_token *fr) {
1961
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->tokenlen) + fr->tokenlen;
1962
+ uint8_t *p;
1963
+
1964
+ assert(fr->tokenlen);
1965
+
1966
+ if (outlen < len) {
1967
+ return NGTCP2_ERR_NOBUF;
1968
+ }
1969
+
1970
+ p = out;
1971
+
1972
+ *p++ = NGTCP2_FRAME_NEW_TOKEN;
1973
+
1974
+ p = ngtcp2_put_uvarint(p, fr->tokenlen);
1975
+ p = ngtcp2_cpymem(p, fr->token, fr->tokenlen);
1976
+
1977
+ assert((size_t)(p - out) == len);
1978
+
1979
+ return (ngtcp2_ssize)len;
1980
+ }
1981
+
1982
+ ngtcp2_ssize ngtcp2_pkt_encode_retire_connection_id_frame(
1983
+ uint8_t *out, size_t outlen, const ngtcp2_retire_connection_id *fr) {
1984
+ size_t len = 1 + ngtcp2_put_uvarintlen(fr->seq);
1985
+ uint8_t *p;
1986
+
1987
+ if (outlen < len) {
1988
+ return NGTCP2_ERR_NOBUF;
1989
+ }
1990
+
1991
+ p = out;
1992
+
1993
+ *p++ = NGTCP2_FRAME_RETIRE_CONNECTION_ID;
1994
+
1995
+ p = ngtcp2_put_uvarint(p, fr->seq);
1996
+
1997
+ assert((size_t)(p - out) == len);
1998
+
1999
+ return (ngtcp2_ssize)len;
2000
+ }
2001
+
2002
+ ngtcp2_ssize
2003
+ ngtcp2_pkt_encode_handshake_done_frame(uint8_t *out, size_t outlen,
2004
+ const ngtcp2_handshake_done *fr) {
2005
+ (void)fr;
2006
+
2007
+ if (outlen < 1) {
2008
+ return NGTCP2_ERR_NOBUF;
2009
+ }
2010
+
2011
+ *out++ = NGTCP2_FRAME_HANDSHAKE_DONE;
2012
+
2013
+ return 1;
2014
+ }
2015
+
2016
+ ngtcp2_ssize ngtcp2_pkt_encode_datagram_frame(uint8_t *out, size_t outlen,
2017
+ const ngtcp2_datagram *fr) {
2018
+ uint64_t datalen = ngtcp2_vec_len(fr->data, fr->datacnt);
2019
+ uint64_t len =
2020
+ 1 +
2021
+ (fr->type == NGTCP2_FRAME_DATAGRAM ? 0 : ngtcp2_put_uvarintlen(datalen)) +
2022
+ datalen;
2023
+ uint8_t *p;
2024
+ size_t i;
2025
+
2026
+ assert(fr->type == NGTCP2_FRAME_DATAGRAM ||
2027
+ fr->type == NGTCP2_FRAME_DATAGRAM_LEN);
2028
+
2029
+ if (outlen < len) {
2030
+ return NGTCP2_ERR_NOBUF;
2031
+ }
2032
+
2033
+ p = out;
2034
+
2035
+ *p++ = fr->type;
2036
+ if (fr->type == NGTCP2_FRAME_DATAGRAM_LEN) {
2037
+ p = ngtcp2_put_uvarint(p, datalen);
2038
+ }
2039
+
2040
+ for (i = 0; i < fr->datacnt; ++i) {
2041
+ assert(fr->data[i].len);
2042
+ assert(fr->data[i].base);
2043
+ p = ngtcp2_cpymem(p, fr->data[i].base, fr->data[i].len);
2044
+ }
2045
+
2046
+ assert((size_t)(p - out) == len);
2047
+
2048
+ return (ngtcp2_ssize)len;
2049
+ }
2050
+
2051
+ ngtcp2_ssize ngtcp2_pkt_write_version_negotiation(
2052
+ uint8_t *dest, size_t destlen, uint8_t unused_random, const uint8_t *dcid,
2053
+ size_t dcidlen, const uint8_t *scid, size_t scidlen, const uint32_t *sv,
2054
+ size_t nsv) {
2055
+ size_t len = 1 + 4 + 1 + dcidlen + 1 + scidlen + nsv * 4;
2056
+ uint8_t *p;
2057
+ size_t i;
2058
+
2059
+ assert(dcidlen < 256);
2060
+ assert(scidlen < 256);
2061
+
2062
+ if (destlen < len) {
2063
+ return NGTCP2_ERR_NOBUF;
2064
+ }
2065
+
2066
+ p = dest;
2067
+
2068
+ *p++ = 0x80 | unused_random;
2069
+ p = ngtcp2_put_uint32be(p, 0);
2070
+ *p++ = (uint8_t)dcidlen;
2071
+ if (dcidlen) {
2072
+ p = ngtcp2_cpymem(p, dcid, dcidlen);
2073
+ }
2074
+ *p++ = (uint8_t)scidlen;
2075
+ if (scidlen) {
2076
+ p = ngtcp2_cpymem(p, scid, scidlen);
2077
+ }
2078
+
2079
+ for (i = 0; i < nsv; ++i) {
2080
+ p = ngtcp2_put_uint32be(p, sv[i]);
2081
+ }
2082
+
2083
+ assert((size_t)(p - dest) == len);
2084
+
2085
+ return (ngtcp2_ssize)len;
2086
+ }
2087
+
2088
+ size_t ngtcp2_pkt_decode_version_negotiation(uint32_t *dest,
2089
+ const uint8_t *payload,
2090
+ size_t payloadlen) {
2091
+ const uint8_t *end = payload + payloadlen;
2092
+
2093
+ assert((payloadlen % sizeof(uint32_t)) == 0);
2094
+
2095
+ for (; payload != end;) {
2096
+ payload = ngtcp2_get_uint32(dest++, payload);
2097
+ }
2098
+
2099
+ return payloadlen / sizeof(uint32_t);
2100
+ }
2101
+
2102
+ int ngtcp2_pkt_decode_stateless_reset(ngtcp2_pkt_stateless_reset *sr,
2103
+ const uint8_t *payload,
2104
+ size_t payloadlen) {
2105
+ const uint8_t *p = payload;
2106
+
2107
+ if (payloadlen <
2108
+ NGTCP2_MIN_STATELESS_RESET_RANDLEN + NGTCP2_STATELESS_RESET_TOKENLEN) {
2109
+ return NGTCP2_ERR_INVALID_ARGUMENT;
2110
+ }
2111
+
2112
+ sr->rand = p;
2113
+ sr->randlen = payloadlen - NGTCP2_STATELESS_RESET_TOKENLEN;
2114
+ p += sr->randlen;
2115
+ memcpy(sr->stateless_reset_token, p, NGTCP2_STATELESS_RESET_TOKENLEN);
2116
+
2117
+ return 0;
2118
+ }
2119
+
2120
+ int ngtcp2_pkt_decode_retry(ngtcp2_pkt_retry *dest, const uint8_t *payload,
2121
+ size_t payloadlen) {
2122
+ size_t len = /* token */ 1 + NGTCP2_RETRY_TAGLEN;
2123
+
2124
+ if (payloadlen < len) {
2125
+ return NGTCP2_ERR_INVALID_ARGUMENT;
2126
+ }
2127
+
2128
+ dest->token = (uint8_t *)payload;
2129
+ dest->tokenlen = (size_t)(payloadlen - NGTCP2_RETRY_TAGLEN);
2130
+ ngtcp2_cpymem(dest->tag, payload + dest->tokenlen, NGTCP2_RETRY_TAGLEN);
2131
+
2132
+ return 0;
2133
+ }
2134
+
2135
+ int64_t ngtcp2_pkt_adjust_pkt_num(int64_t max_pkt_num, int64_t pkt_num,
2136
+ size_t n) {
2137
+ int64_t expected = max_pkt_num + 1;
2138
+ int64_t win = (int64_t)1 << n;
2139
+ int64_t hwin = win / 2;
2140
+ int64_t mask = win - 1;
2141
+ int64_t cand = (expected & ~mask) | pkt_num;
2142
+
2143
+ if (cand <= expected - hwin) {
2144
+ assert(cand <= (int64_t)NGTCP2_MAX_VARINT - win);
2145
+ return cand + win;
2146
+ }
2147
+ if (cand > expected + hwin && cand >= win) {
2148
+ return cand - win;
2149
+ }
2150
+ return cand;
2151
+ }
2152
+
2153
+ int ngtcp2_pkt_validate_ack(ngtcp2_ack *fr) {
2154
+ int64_t largest_ack = fr->largest_ack;
2155
+ size_t i;
2156
+
2157
+ if (largest_ack < (int64_t)fr->first_ack_range) {
2158
+ return NGTCP2_ERR_ACK_FRAME;
2159
+ }
2160
+
2161
+ largest_ack -= (int64_t)fr->first_ack_range;
2162
+
2163
+ for (i = 0; i < fr->rangecnt; ++i) {
2164
+ if (largest_ack < (int64_t)fr->ranges[i].gap + 2) {
2165
+ return NGTCP2_ERR_ACK_FRAME;
2166
+ }
2167
+
2168
+ largest_ack -= (int64_t)fr->ranges[i].gap + 2;
2169
+
2170
+ if (largest_ack < (int64_t)fr->ranges[i].len) {
2171
+ return NGTCP2_ERR_ACK_FRAME;
2172
+ }
2173
+
2174
+ largest_ack -= (int64_t)fr->ranges[i].len;
2175
+ }
2176
+
2177
+ return 0;
2178
+ }
2179
+
2180
+ ngtcp2_ssize
2181
+ ngtcp2_pkt_write_stateless_reset(uint8_t *dest, size_t destlen,
2182
+ const uint8_t *stateless_reset_token,
2183
+ const uint8_t *rand, size_t randlen) {
2184
+ uint8_t *p;
2185
+
2186
+ if (destlen <
2187
+ NGTCP2_MIN_STATELESS_RESET_RANDLEN + NGTCP2_STATELESS_RESET_TOKENLEN) {
2188
+ return NGTCP2_ERR_NOBUF;
2189
+ }
2190
+
2191
+ if (randlen < NGTCP2_MIN_STATELESS_RESET_RANDLEN) {
2192
+ return NGTCP2_ERR_INVALID_ARGUMENT;
2193
+ }
2194
+
2195
+ p = dest;
2196
+
2197
+ randlen = ngtcp2_min(destlen - NGTCP2_STATELESS_RESET_TOKENLEN, randlen);
2198
+
2199
+ p = ngtcp2_cpymem(p, rand, randlen);
2200
+ p = ngtcp2_cpymem(p, stateless_reset_token, NGTCP2_STATELESS_RESET_TOKENLEN);
2201
+ *dest = (uint8_t)((*dest & 0x7fu) | 0x40u);
2202
+
2203
+ return p - dest;
2204
+ }
2205
+
2206
+ ngtcp2_ssize ngtcp2_pkt_write_retry(
2207
+ uint8_t *dest, size_t destlen, uint32_t version, const ngtcp2_cid *dcid,
2208
+ const ngtcp2_cid *scid, const ngtcp2_cid *odcid, const uint8_t *token,
2209
+ size_t tokenlen, ngtcp2_encrypt encrypt, const ngtcp2_crypto_aead *aead,
2210
+ const ngtcp2_crypto_aead_ctx *aead_ctx) {
2211
+ ngtcp2_pkt_hd hd;
2212
+ uint8_t pseudo_retry[1500];
2213
+ ngtcp2_ssize pseudo_retrylen;
2214
+ uint8_t tag[NGTCP2_RETRY_TAGLEN];
2215
+ int rv;
2216
+ uint8_t *p;
2217
+ size_t offset;
2218
+ const uint8_t *nonce;
2219
+ size_t noncelen;
2220
+
2221
+ assert(tokenlen > 0);
2222
+ assert(!ngtcp2_cid_eq(scid, odcid));
2223
+
2224
+ /* Retry packet is sent at most once per one connection attempt. In
2225
+ the first connection attempt, client has to send random DCID
2226
+ which is at least NGTCP2_MIN_INITIAL_DCIDLEN bytes long. */
2227
+ if (odcid->datalen < NGTCP2_MIN_INITIAL_DCIDLEN) {
2228
+ return NGTCP2_ERR_INVALID_ARGUMENT;
2229
+ }
2230
+
2231
+ ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_RETRY, dcid,
2232
+ scid, /* pkt_num = */ 0, /* pkt_numlen = */ 1, version,
2233
+ /* len = */ 0);
2234
+
2235
+ pseudo_retrylen =
2236
+ ngtcp2_pkt_encode_pseudo_retry(pseudo_retry, sizeof(pseudo_retry), &hd,
2237
+ /* unused = */ 0, odcid, token, tokenlen);
2238
+ if (pseudo_retrylen < 0) {
2239
+ return pseudo_retrylen;
2240
+ }
2241
+
2242
+ switch (version) {
2243
+ case NGTCP2_PROTO_VER_V1:
2244
+ nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V1;
2245
+ noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
2246
+ break;
2247
+ case NGTCP2_PROTO_VER_V2:
2248
+ nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V2;
2249
+ noncelen = sizeof(NGTCP2_RETRY_NONCE_V2) - 1;
2250
+ break;
2251
+ default:
2252
+ nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_DRAFT;
2253
+ noncelen = sizeof(NGTCP2_RETRY_NONCE_DRAFT) - 1;
2254
+ }
2255
+
2256
+ /* OpenSSL does not like NULL plaintext. */
2257
+ rv = encrypt(tag, aead, aead_ctx, (const uint8_t *)"", 0, nonce, noncelen,
2258
+ pseudo_retry, (size_t)pseudo_retrylen);
2259
+ if (rv != 0) {
2260
+ return rv;
2261
+ }
2262
+
2263
+ offset = 1 + odcid->datalen;
2264
+ if (destlen < (size_t)pseudo_retrylen + sizeof(tag) - offset) {
2265
+ return NGTCP2_ERR_NOBUF;
2266
+ }
2267
+
2268
+ p = ngtcp2_cpymem(dest, pseudo_retry + offset,
2269
+ (size_t)pseudo_retrylen - offset);
2270
+ p = ngtcp2_cpymem(p, tag, sizeof(tag));
2271
+
2272
+ return p - dest;
2273
+ }
2274
+
2275
+ ngtcp2_ssize ngtcp2_pkt_encode_pseudo_retry(
2276
+ uint8_t *dest, size_t destlen, const ngtcp2_pkt_hd *hd, uint8_t unused,
2277
+ const ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen) {
2278
+ uint8_t *p = dest;
2279
+ ngtcp2_ssize nwrite;
2280
+
2281
+ if (destlen < 1 + odcid->datalen) {
2282
+ return NGTCP2_ERR_NOBUF;
2283
+ }
2284
+
2285
+ *p++ = (uint8_t)odcid->datalen;
2286
+ p = ngtcp2_cpymem(p, odcid->data, odcid->datalen);
2287
+ destlen -= (size_t)(p - dest);
2288
+
2289
+ nwrite = ngtcp2_pkt_encode_hd_long(p, destlen, hd);
2290
+ if (nwrite < 0) {
2291
+ return nwrite;
2292
+ }
2293
+
2294
+ if (destlen < (size_t)nwrite + tokenlen) {
2295
+ return NGTCP2_ERR_NOBUF;
2296
+ }
2297
+
2298
+ *p &= 0xf0;
2299
+ *p |= unused;
2300
+
2301
+ p += nwrite;
2302
+
2303
+ p = ngtcp2_cpymem(p, token, tokenlen);
2304
+
2305
+ return p - dest;
2306
+ }
2307
+
2308
+ int ngtcp2_pkt_verify_retry_tag(uint32_t version, const ngtcp2_pkt_retry *retry,
2309
+ const uint8_t *pkt, size_t pktlen,
2310
+ ngtcp2_encrypt encrypt,
2311
+ const ngtcp2_crypto_aead *aead,
2312
+ const ngtcp2_crypto_aead_ctx *aead_ctx) {
2313
+ uint8_t pseudo_retry[1500];
2314
+ size_t pseudo_retrylen;
2315
+ uint8_t *p = pseudo_retry;
2316
+ int rv;
2317
+ uint8_t tag[NGTCP2_RETRY_TAGLEN];
2318
+ const uint8_t *nonce;
2319
+ size_t noncelen;
2320
+
2321
+ assert(pktlen >= sizeof(retry->tag));
2322
+
2323
+ if (sizeof(pseudo_retry) <
2324
+ 1 + retry->odcid.datalen + pktlen - sizeof(retry->tag)) {
2325
+ return NGTCP2_ERR_PROTO;
2326
+ }
2327
+
2328
+ *p++ = (uint8_t)retry->odcid.datalen;
2329
+ p = ngtcp2_cpymem(p, retry->odcid.data, retry->odcid.datalen);
2330
+ p = ngtcp2_cpymem(p, pkt, pktlen - sizeof(retry->tag));
2331
+
2332
+ pseudo_retrylen = (size_t)(p - pseudo_retry);
2333
+
2334
+ switch (version) {
2335
+ case NGTCP2_PROTO_VER_V1:
2336
+ nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V1;
2337
+ noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
2338
+ break;
2339
+ case NGTCP2_PROTO_VER_V2:
2340
+ nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V2;
2341
+ noncelen = sizeof(NGTCP2_RETRY_NONCE_V2) - 1;
2342
+ break;
2343
+ default:
2344
+ nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_DRAFT;
2345
+ noncelen = sizeof(NGTCP2_RETRY_NONCE_DRAFT) - 1;
2346
+ }
2347
+
2348
+ /* OpenSSL does not like NULL plaintext. */
2349
+ rv = encrypt(tag, aead, aead_ctx, (const uint8_t *)"", 0, nonce, noncelen,
2350
+ pseudo_retry, pseudo_retrylen);
2351
+ if (rv != 0) {
2352
+ return rv;
2353
+ }
2354
+
2355
+ if (0 != memcmp(retry->tag, tag, sizeof(retry->tag))) {
2356
+ return NGTCP2_ERR_PROTO;
2357
+ }
2358
+
2359
+ return 0;
2360
+ }
2361
+
2362
+ size_t ngtcp2_pkt_stream_max_datalen(int64_t stream_id, uint64_t offset,
2363
+ uint64_t len, size_t left) {
2364
+ size_t n = 1 /* type */ + ngtcp2_put_uvarintlen((uint64_t)stream_id) +
2365
+ (offset ? ngtcp2_put_uvarintlen(offset) : 0);
2366
+
2367
+ if (left <= n) {
2368
+ return (size_t)-1;
2369
+ }
2370
+
2371
+ left -= n;
2372
+
2373
+ if (left > 8 + 1073741823 && len > 1073741823) {
2374
+ #if SIZE_MAX > UINT32_MAX
2375
+ len = ngtcp2_min(len, 4611686018427387903lu);
2376
+ #endif /* SIZE_MAX > UINT32_MAX */
2377
+ return (size_t)ngtcp2_min(len, (uint64_t)(left - 8));
2378
+ }
2379
+
2380
+ if (left > 4 + 16383 && len > 16383) {
2381
+ len = ngtcp2_min(len, 1073741823);
2382
+ return (size_t)ngtcp2_min(len, (uint64_t)(left - 4));
2383
+ }
2384
+
2385
+ if (left > 2 + 63 && len > 63) {
2386
+ len = ngtcp2_min(len, 16383);
2387
+ return (size_t)ngtcp2_min(len, (uint64_t)(left - 2));
2388
+ }
2389
+
2390
+ len = ngtcp2_min(len, 63);
2391
+ return (size_t)ngtcp2_min(len, (uint64_t)(left - 1));
2392
+ }
2393
+
2394
+ size_t ngtcp2_pkt_crypto_max_datalen(uint64_t offset, size_t len, size_t left) {
2395
+ size_t n = 1 /* type */ + ngtcp2_put_uvarintlen(offset);
2396
+
2397
+ /* CRYPTO frame must contain nonzero length data. Return -1 if
2398
+ there is no space to write crypto data. */
2399
+ if (left <= n + 1) {
2400
+ return (size_t)-1;
2401
+ }
2402
+
2403
+ left -= n;
2404
+
2405
+ if (left > 8 + 1073741823 && len > 1073741823) {
2406
+ #if SIZE_MAX > UINT32_MAX
2407
+ len = ngtcp2_min(len, 4611686018427387903lu);
2408
+ #endif /* SIZE_MAX > UINT32_MAX */
2409
+ return ngtcp2_min(len, left - 8);
2410
+ }
2411
+
2412
+ if (left > 4 + 16383 && len > 16383) {
2413
+ len = ngtcp2_min(len, 1073741823);
2414
+ return ngtcp2_min(len, left - 4);
2415
+ }
2416
+
2417
+ if (left > 2 + 63 && len > 63) {
2418
+ len = ngtcp2_min(len, 16383);
2419
+ return ngtcp2_min(len, left - 2);
2420
+ }
2421
+
2422
+ len = ngtcp2_min(len, 63);
2423
+ return ngtcp2_min(len, left - 1);
2424
+ }
2425
+
2426
+ size_t ngtcp2_pkt_datagram_framelen(size_t len) {
2427
+ return 1 /* type */ + ngtcp2_put_uvarintlen(len) + len;
2428
+ }
2429
+
2430
+ int ngtcp2_is_supported_version(uint32_t version) {
2431
+ switch (version) {
2432
+ case NGTCP2_PROTO_VER_V1:
2433
+ case NGTCP2_PROTO_VER_V2:
2434
+ return 1;
2435
+ default:
2436
+ return NGTCP2_PROTO_VER_DRAFT_MIN <= version &&
2437
+ version <= NGTCP2_PROTO_VER_DRAFT_MAX;
2438
+ }
2439
+ }
2440
+
2441
+ int ngtcp2_is_reserved_version(uint32_t version) {
2442
+ return (version & NGTCP2_RESERVED_VERSION_MASK) ==
2443
+ NGTCP2_RESERVED_VERSION_MASK;
2444
+ }
2445
+
2446
+ uint8_t ngtcp2_pkt_get_type_long(uint32_t version, uint8_t c) {
2447
+ uint8_t pkt_type = (uint8_t)((c & NGTCP2_LONG_TYPE_MASK) >> 4);
2448
+
2449
+ switch (version) {
2450
+ case NGTCP2_PROTO_VER_V2:
2451
+ switch (pkt_type) {
2452
+ case NGTCP2_PKT_TYPE_INITIAL_V2:
2453
+ return NGTCP2_PKT_INITIAL;
2454
+ case NGTCP2_PKT_TYPE_0RTT_V2:
2455
+ return NGTCP2_PKT_0RTT;
2456
+ case NGTCP2_PKT_TYPE_HANDSHAKE_V2:
2457
+ return NGTCP2_PKT_HANDSHAKE;
2458
+ case NGTCP2_PKT_TYPE_RETRY_V2:
2459
+ return NGTCP2_PKT_RETRY;
2460
+ default:
2461
+ return 0;
2462
+ }
2463
+ default:
2464
+ if (!ngtcp2_is_supported_version(version)) {
2465
+ return 0;
2466
+ }
2467
+
2468
+ /* QUIC v1 and draft versions share the same numeric packet
2469
+ types. */
2470
+ switch (pkt_type) {
2471
+ case NGTCP2_PKT_TYPE_INITIAL_V1:
2472
+ return NGTCP2_PKT_INITIAL;
2473
+ case NGTCP2_PKT_TYPE_0RTT_V1:
2474
+ return NGTCP2_PKT_0RTT;
2475
+ case NGTCP2_PKT_TYPE_HANDSHAKE_V1:
2476
+ return NGTCP2_PKT_HANDSHAKE;
2477
+ case NGTCP2_PKT_TYPE_RETRY_V1:
2478
+ return NGTCP2_PKT_RETRY;
2479
+ default:
2480
+ return 0;
2481
+ }
2482
+ }
2483
+ }
2484
+
2485
+ uint8_t ngtcp2_pkt_versioned_type(uint32_t version, uint32_t pkt_type) {
2486
+ switch (version) {
2487
+ case NGTCP2_PROTO_VER_V2:
2488
+ switch (pkt_type) {
2489
+ case NGTCP2_PKT_INITIAL:
2490
+ return NGTCP2_PKT_TYPE_INITIAL_V2;
2491
+ case NGTCP2_PKT_0RTT:
2492
+ return NGTCP2_PKT_TYPE_0RTT_V2;
2493
+ case NGTCP2_PKT_HANDSHAKE:
2494
+ return NGTCP2_PKT_TYPE_HANDSHAKE_V2;
2495
+ case NGTCP2_PKT_RETRY:
2496
+ return NGTCP2_PKT_TYPE_RETRY_V2;
2497
+ default:
2498
+ ngtcp2_unreachable();
2499
+ }
2500
+ default:
2501
+ /* Assume that unsupported versions share the numeric long packet
2502
+ types with QUIC v1 in order to send a packet to elicit Version
2503
+ Negotiation packet. */
2504
+
2505
+ /* QUIC v1 and draft versions share the same numeric packet
2506
+ types. */
2507
+ switch (pkt_type) {
2508
+ case NGTCP2_PKT_INITIAL:
2509
+ return NGTCP2_PKT_TYPE_INITIAL_V1;
2510
+ case NGTCP2_PKT_0RTT:
2511
+ return NGTCP2_PKT_TYPE_0RTT_V1;
2512
+ case NGTCP2_PKT_HANDSHAKE:
2513
+ return NGTCP2_PKT_TYPE_HANDSHAKE_V1;
2514
+ case NGTCP2_PKT_RETRY:
2515
+ return NGTCP2_PKT_TYPE_RETRY_V1;
2516
+ default:
2517
+ ngtcp2_unreachable();
2518
+ }
2519
+ }
2520
+ }
2521
+
2522
+ int ngtcp2_pkt_verify_reserved_bits(uint8_t c) {
2523
+ if (c & NGTCP2_HEADER_FORM_BIT) {
2524
+ return (c & NGTCP2_LONG_RESERVED_BIT_MASK) == 0 ? 0 : NGTCP2_ERR_PROTO;
2525
+ }
2526
+ return (c & NGTCP2_SHORT_RESERVED_BIT_MASK) == 0 ? 0 : NGTCP2_ERR_PROTO;
2527
+ }