protocol-quic 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/ext/ngtcp2/AUTHORS +44 -0
- data/ext/ngtcp2/CMakeLists.txt +431 -0
- data/ext/ngtcp2/CMakeOptions.txt +17 -0
- data/ext/ngtcp2/COPYING +22 -0
- data/ext/ngtcp2/ChangeLog +0 -0
- data/ext/ngtcp2/Makefile.am +60 -0
- data/ext/ngtcp2/NEWS +0 -0
- data/ext/ngtcp2/README +1 -0
- data/ext/ngtcp2/README.rst +258 -0
- data/ext/ngtcp2/ci/build_boringssl.sh +10 -0
- data/ext/ngtcp2/ci/build_nghttp3.sh +9 -0
- data/ext/ngtcp2/ci/build_openssl1.sh +8 -0
- data/ext/ngtcp2/ci/build_openssl1_cross.sh +9 -0
- data/ext/ngtcp2/ci/build_openssl3.sh +8 -0
- data/ext/ngtcp2/ci/build_picotls.sh +26 -0
- data/ext/ngtcp2/ci/build_wolfssl.sh +9 -0
- data/ext/ngtcp2/ci/gen-certificate.sh +8 -0
- data/ext/ngtcp2/cmake/ExtractValidFlags.cmake +31 -0
- data/ext/ngtcp2/cmake/FindCUnit.cmake +40 -0
- data/ext/ngtcp2/cmake/FindJemalloc.cmake +40 -0
- data/ext/ngtcp2/cmake/FindLibev.cmake +38 -0
- data/ext/ngtcp2/cmake/FindLibnghttp3.cmake +41 -0
- data/ext/ngtcp2/cmake/Findwolfssl.cmake +41 -0
- data/ext/ngtcp2/cmake/Version.cmake +11 -0
- data/ext/ngtcp2/cmakeconfig.h.in +36 -0
- data/ext/ngtcp2/configure.ac +755 -0
- data/ext/ngtcp2/crypto/CMakeLists.txt +56 -0
- data/ext/ngtcp2/crypto/Makefile.am +49 -0
- data/ext/ngtcp2/crypto/boringssl/CMakeLists.txt +64 -0
- data/ext/ngtcp2/crypto/boringssl/Makefile.am +39 -0
- data/ext/ngtcp2/crypto/boringssl/boringssl.c +630 -0
- data/ext/ngtcp2/crypto/boringssl/libngtcp2_crypto_boringssl.pc.in +33 -0
- data/ext/ngtcp2/crypto/gnutls/CMakeLists.txt +86 -0
- data/ext/ngtcp2/crypto/gnutls/Makefile.am +43 -0
- data/ext/ngtcp2/crypto/gnutls/gnutls.c +644 -0
- data/ext/ngtcp2/crypto/gnutls/libngtcp2_crypto_gnutls.pc.in +33 -0
- data/ext/ngtcp2/crypto/includes/CMakeLists.txt +56 -0
- data/ext/ngtcp2/crypto/includes/Makefile.am +45 -0
- data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto.h +893 -0
- data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_boringssl.h +104 -0
- data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_gnutls.h +107 -0
- data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_openssl.h +132 -0
- data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_picotls.h +246 -0
- data/ext/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_wolfssl.h +106 -0
- data/ext/ngtcp2/crypto/openssl/CMakeLists.txt +86 -0
- data/ext/ngtcp2/crypto/openssl/Makefile.am +43 -0
- data/ext/ngtcp2/crypto/openssl/libngtcp2_crypto_openssl.pc.in +33 -0
- data/ext/ngtcp2/crypto/openssl/openssl.c +807 -0
- data/ext/ngtcp2/crypto/picotls/CMakeLists.txt +65 -0
- data/ext/ngtcp2/crypto/picotls/Makefile.am +39 -0
- data/ext/ngtcp2/crypto/picotls/libngtcp2_crypto_picotls.pc.in +33 -0
- data/ext/ngtcp2/crypto/picotls/picotls.c +707 -0
- data/ext/ngtcp2/crypto/shared.c +1431 -0
- data/ext/ngtcp2/crypto/shared.h +350 -0
- data/ext/ngtcp2/crypto/wolfssl/CMakeLists.txt +84 -0
- data/ext/ngtcp2/crypto/wolfssl/Makefile.am +43 -0
- data/ext/ngtcp2/crypto/wolfssl/libngtcp2_crypto_wolfssl.pc.in +33 -0
- data/ext/ngtcp2/crypto/wolfssl/wolfssl.c +534 -0
- data/ext/ngtcp2/doc/Makefile.am +65 -0
- data/ext/ngtcp2/doc/make.bat +35 -0
- data/ext/ngtcp2/doc/mkapiref.py +356 -0
- data/ext/ngtcp2/doc/source/conf.py.in +94 -0
- data/ext/ngtcp2/doc/source/index.rst +22 -0
- data/ext/ngtcp2/doc/source/programmers-guide.rst +476 -0
- data/ext/ngtcp2/docker/Dockerfile +39 -0
- data/ext/ngtcp2/examples/CMakeLists.txt +361 -0
- data/ext/ngtcp2/examples/Makefile.am +228 -0
- data/ext/ngtcp2/examples/client.cc +3049 -0
- data/ext/ngtcp2/examples/client.h +192 -0
- data/ext/ngtcp2/examples/client_base.cc +202 -0
- data/ext/ngtcp2/examples/client_base.h +213 -0
- data/ext/ngtcp2/examples/debug.cc +298 -0
- data/ext/ngtcp2/examples/debug.h +124 -0
- data/ext/ngtcp2/examples/examplestest.cc +84 -0
- data/ext/ngtcp2/examples/gtlssimpleclient.c +720 -0
- data/ext/ngtcp2/examples/h09client.cc +2601 -0
- data/ext/ngtcp2/examples/h09client.h +196 -0
- data/ext/ngtcp2/examples/h09server.cc +3024 -0
- data/ext/ngtcp2/examples/h09server.h +237 -0
- data/ext/ngtcp2/examples/http.cc +138 -0
- data/ext/ngtcp2/examples/http.h +44 -0
- data/ext/ngtcp2/examples/network.h +80 -0
- data/ext/ngtcp2/examples/server.cc +3731 -0
- data/ext/ngtcp2/examples/server.h +256 -0
- data/ext/ngtcp2/examples/server_base.cc +58 -0
- data/ext/ngtcp2/examples/server_base.h +195 -0
- data/ext/ngtcp2/examples/shared.cc +385 -0
- data/ext/ngtcp2/examples/shared.h +96 -0
- data/ext/ngtcp2/examples/simpleclient.c +683 -0
- data/ext/ngtcp2/examples/template.h +71 -0
- data/ext/ngtcp2/examples/tests/README.rst +60 -0
- data/ext/ngtcp2/examples/tests/__init__.py +0 -0
- data/ext/ngtcp2/examples/tests/config.ini.in +32 -0
- data/ext/ngtcp2/examples/tests/conftest.py +28 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/__init__.py +6 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/certs.py +476 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/client.py +187 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/env.py +191 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/log.py +101 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/server.py +137 -0
- data/ext/ngtcp2/examples/tests/ngtcp2test/tls.py +983 -0
- data/ext/ngtcp2/examples/tests/test_01_handshake.py +30 -0
- data/ext/ngtcp2/examples/tests/test_02_resume.py +46 -0
- data/ext/ngtcp2/examples/tests/test_03_earlydata.py +56 -0
- data/ext/ngtcp2/examples/tests/test_04_clientcert.py +57 -0
- data/ext/ngtcp2/examples/tests/test_05_ciphers.py +46 -0
- data/ext/ngtcp2/examples/tls_client_context.h +52 -0
- data/ext/ngtcp2/examples/tls_client_context_boringssl.cc +126 -0
- data/ext/ngtcp2/examples/tls_client_context_boringssl.h +49 -0
- data/ext/ngtcp2/examples/tls_client_context_gnutls.cc +74 -0
- data/ext/ngtcp2/examples/tls_client_context_gnutls.h +50 -0
- data/ext/ngtcp2/examples/tls_client_context_openssl.cc +137 -0
- data/ext/ngtcp2/examples/tls_client_context_openssl.h +49 -0
- data/ext/ngtcp2/examples/tls_client_context_picotls.cc +158 -0
- data/ext/ngtcp2/examples/tls_client_context_picotls.h +53 -0
- data/ext/ngtcp2/examples/tls_client_context_wolfssl.cc +177 -0
- data/ext/ngtcp2/examples/tls_client_context_wolfssl.h +51 -0
- data/ext/ngtcp2/examples/tls_client_session.h +52 -0
- data/ext/ngtcp2/examples/tls_client_session_boringssl.cc +110 -0
- data/ext/ngtcp2/examples/tls_client_session_boringssl.h +52 -0
- data/ext/ngtcp2/examples/tls_client_session_gnutls.cc +190 -0
- data/ext/ngtcp2/examples/tls_client_session_gnutls.h +52 -0
- data/ext/ngtcp2/examples/tls_client_session_openssl.cc +113 -0
- data/ext/ngtcp2/examples/tls_client_session_openssl.h +52 -0
- data/ext/ngtcp2/examples/tls_client_session_picotls.cc +147 -0
- data/ext/ngtcp2/examples/tls_client_session_picotls.h +52 -0
- data/ext/ngtcp2/examples/tls_client_session_wolfssl.cc +160 -0
- data/ext/ngtcp2/examples/tls_client_session_wolfssl.h +52 -0
- data/ext/ngtcp2/examples/tls_server_context.h +52 -0
- data/ext/ngtcp2/examples/tls_server_context_boringssl.cc +257 -0
- data/ext/ngtcp2/examples/tls_server_context_boringssl.h +54 -0
- data/ext/ngtcp2/examples/tls_server_context_gnutls.cc +99 -0
- data/ext/ngtcp2/examples/tls_server_context_gnutls.h +59 -0
- data/ext/ngtcp2/examples/tls_server_context_openssl.cc +338 -0
- data/ext/ngtcp2/examples/tls_server_context_openssl.h +54 -0
- data/ext/ngtcp2/examples/tls_server_context_picotls.cc +321 -0
- data/ext/ngtcp2/examples/tls_server_context_picotls.h +58 -0
- data/ext/ngtcp2/examples/tls_server_context_wolfssl.cc +284 -0
- data/ext/ngtcp2/examples/tls_server_context_wolfssl.h +55 -0
- data/ext/ngtcp2/examples/tls_server_session.h +52 -0
- data/ext/ngtcp2/examples/tls_server_session_boringssl.cc +84 -0
- data/ext/ngtcp2/examples/tls_server_session_boringssl.h +47 -0
- data/ext/ngtcp2/examples/tls_server_session_gnutls.cc +155 -0
- data/ext/ngtcp2/examples/tls_server_session_gnutls.h +46 -0
- data/ext/ngtcp2/examples/tls_server_session_openssl.cc +54 -0
- data/ext/ngtcp2/examples/tls_server_session_openssl.h +47 -0
- data/ext/ngtcp2/examples/tls_server_session_picotls.cc +70 -0
- data/ext/ngtcp2/examples/tls_server_session_picotls.h +47 -0
- data/ext/ngtcp2/examples/tls_server_session_wolfssl.cc +55 -0
- data/ext/ngtcp2/examples/tls_server_session_wolfssl.h +47 -0
- data/ext/ngtcp2/examples/tls_session_base_gnutls.cc +87 -0
- data/ext/ngtcp2/examples/tls_session_base_gnutls.h +51 -0
- data/ext/ngtcp2/examples/tls_session_base_openssl.cc +54 -0
- data/ext/ngtcp2/examples/tls_session_base_openssl.h +52 -0
- data/ext/ngtcp2/examples/tls_session_base_picotls.cc +56 -0
- data/ext/ngtcp2/examples/tls_session_base_picotls.h +54 -0
- data/ext/ngtcp2/examples/tls_session_base_wolfssl.cc +54 -0
- data/ext/ngtcp2/examples/tls_session_base_wolfssl.h +54 -0
- data/ext/ngtcp2/examples/tls_shared_picotls.cc +59 -0
- data/ext/ngtcp2/examples/tls_shared_picotls.h +36 -0
- data/ext/ngtcp2/examples/util.cc +646 -0
- data/ext/ngtcp2/examples/util.h +361 -0
- data/ext/ngtcp2/examples/util_gnutls.cc +136 -0
- data/ext/ngtcp2/examples/util_openssl.cc +131 -0
- data/ext/ngtcp2/examples/util_test.cc +237 -0
- data/ext/ngtcp2/examples/util_test.h +45 -0
- data/ext/ngtcp2/examples/util_wolfssl.cc +130 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/ack +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/ack_ecn +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/connection_close +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/crypto +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/data_blocked +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/datagram +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/datagram_len +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/max_data +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/max_stream_data +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/max_streams +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/new_connection_id +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/new_token +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/path_challenge +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/path_response +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/reset_stream +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/retire_connection_id +1 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/stop_sending +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/stream +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/stream_data_blocked +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/stream_len +0 -0
- data/ext/ngtcp2/fuzz/corpus/decode_frame/streams_blocked +0 -0
- data/ext/ngtcp2/fuzz/corpus/ksl/random +0 -0
- data/ext/ngtcp2/fuzz/decode_frame.cc +25 -0
- data/ext/ngtcp2/fuzz/ksl.cc +77 -0
- data/ext/ngtcp2/interop/Dockerfile +39 -0
- data/ext/ngtcp2/interop/run_endpoint.sh +93 -0
- data/ext/ngtcp2/lib/CMakeLists.txt +110 -0
- data/ext/ngtcp2/lib/Makefile.am +122 -0
- data/ext/ngtcp2/lib/includes/CMakeLists.txt +4 -0
- data/ext/ngtcp2/lib/includes/Makefile.am +25 -0
- data/ext/ngtcp2/lib/includes/ngtcp2/ngtcp2.h +5843 -0
- data/ext/ngtcp2/lib/includes/ngtcp2/version.h.in +51 -0
- data/ext/ngtcp2/lib/libngtcp2.pc.in +33 -0
- data/ext/ngtcp2/lib/ngtcp2_acktr.c +335 -0
- data/ext/ngtcp2/lib/ngtcp2_acktr.h +221 -0
- data/ext/ngtcp2/lib/ngtcp2_addr.c +117 -0
- data/ext/ngtcp2/lib/ngtcp2_addr.h +69 -0
- data/ext/ngtcp2/lib/ngtcp2_balloc.c +90 -0
- data/ext/ngtcp2/lib/ngtcp2_balloc.h +91 -0
- data/ext/ngtcp2/lib/ngtcp2_bbr.c +693 -0
- data/ext/ngtcp2/lib/ngtcp2_bbr.h +157 -0
- data/ext/ngtcp2/lib/ngtcp2_bbr2.c +1490 -0
- data/ext/ngtcp2/lib/ngtcp2_bbr2.h +149 -0
- data/ext/ngtcp2/lib/ngtcp2_buf.c +56 -0
- data/ext/ngtcp2/lib/ngtcp2_buf.h +108 -0
- data/ext/ngtcp2/lib/ngtcp2_cc.c +616 -0
- data/ext/ngtcp2/lib/ngtcp2_cc.h +422 -0
- data/ext/ngtcp2/lib/ngtcp2_cid.c +147 -0
- data/ext/ngtcp2/lib/ngtcp2_cid.h +175 -0
- data/ext/ngtcp2/lib/ngtcp2_conn.c +13731 -0
- data/ext/ngtcp2/lib/ngtcp2_conn.h +1119 -0
- data/ext/ngtcp2/lib/ngtcp2_conn_stat.h +131 -0
- data/ext/ngtcp2/lib/ngtcp2_conv.c +291 -0
- data/ext/ngtcp2/lib/ngtcp2_conv.h +208 -0
- data/ext/ngtcp2/lib/ngtcp2_crypto.c +895 -0
- data/ext/ngtcp2/lib/ngtcp2_crypto.h +148 -0
- data/ext/ngtcp2/lib/ngtcp2_err.c +154 -0
- data/ext/ngtcp2/lib/ngtcp2_err.h +34 -0
- data/ext/ngtcp2/lib/ngtcp2_gaptr.c +167 -0
- data/ext/ngtcp2/lib/ngtcp2_gaptr.h +98 -0
- data/ext/ngtcp2/lib/ngtcp2_idtr.c +79 -0
- data/ext/ngtcp2/lib/ngtcp2_idtr.h +89 -0
- data/ext/ngtcp2/lib/ngtcp2_ksl.c +819 -0
- data/ext/ngtcp2/lib/ngtcp2_ksl.h +345 -0
- data/ext/ngtcp2/lib/ngtcp2_log.c +822 -0
- data/ext/ngtcp2/lib/ngtcp2_log.h +123 -0
- data/ext/ngtcp2/lib/ngtcp2_macro.h +58 -0
- data/ext/ngtcp2/lib/ngtcp2_map.c +336 -0
- data/ext/ngtcp2/lib/ngtcp2_map.h +136 -0
- data/ext/ngtcp2/lib/ngtcp2_mem.c +113 -0
- data/ext/ngtcp2/lib/ngtcp2_mem.h +72 -0
- data/ext/ngtcp2/lib/ngtcp2_net.h +136 -0
- data/ext/ngtcp2/lib/ngtcp2_objalloc.c +40 -0
- data/ext/ngtcp2/lib/ngtcp2_objalloc.h +140 -0
- data/ext/ngtcp2/lib/ngtcp2_opl.c +46 -0
- data/ext/ngtcp2/lib/ngtcp2_opl.h +65 -0
- data/ext/ngtcp2/lib/ngtcp2_path.c +77 -0
- data/ext/ngtcp2/lib/ngtcp2_path.h +49 -0
- data/ext/ngtcp2/lib/ngtcp2_pkt.c +2527 -0
- data/ext/ngtcp2/lib/ngtcp2_pkt.h +1235 -0
- data/ext/ngtcp2/lib/ngtcp2_pmtud.c +160 -0
- data/ext/ngtcp2/lib/ngtcp2_pmtud.h +123 -0
- data/ext/ngtcp2/lib/ngtcp2_ppe.c +230 -0
- data/ext/ngtcp2/lib/ngtcp2_ppe.h +153 -0
- data/ext/ngtcp2/lib/ngtcp2_pq.c +164 -0
- data/ext/ngtcp2/lib/ngtcp2_pq.h +126 -0
- data/ext/ngtcp2/lib/ngtcp2_pv.c +172 -0
- data/ext/ngtcp2/lib/ngtcp2_pv.h +194 -0
- data/ext/ngtcp2/lib/ngtcp2_qlog.c +1219 -0
- data/ext/ngtcp2/lib/ngtcp2_qlog.h +161 -0
- data/ext/ngtcp2/lib/ngtcp2_range.c +61 -0
- data/ext/ngtcp2/lib/ngtcp2_range.h +80 -0
- data/ext/ngtcp2/lib/ngtcp2_rcvry.h +40 -0
- data/ext/ngtcp2/lib/ngtcp2_ringbuf.c +121 -0
- data/ext/ngtcp2/lib/ngtcp2_ringbuf.h +132 -0
- data/ext/ngtcp2/lib/ngtcp2_rob.c +319 -0
- data/ext/ngtcp2/lib/ngtcp2_rob.h +197 -0
- data/ext/ngtcp2/lib/ngtcp2_rst.c +138 -0
- data/ext/ngtcp2/lib/ngtcp2_rst.h +86 -0
- data/ext/ngtcp2/lib/ngtcp2_rtb.c +1676 -0
- data/ext/ngtcp2/lib/ngtcp2_rtb.h +468 -0
- data/ext/ngtcp2/lib/ngtcp2_str.c +233 -0
- data/ext/ngtcp2/lib/ngtcp2_str.h +94 -0
- data/ext/ngtcp2/lib/ngtcp2_strm.c +698 -0
- data/ext/ngtcp2/lib/ngtcp2_strm.h +310 -0
- data/ext/ngtcp2/lib/ngtcp2_unreachable.c +71 -0
- data/ext/ngtcp2/lib/ngtcp2_unreachable.h +46 -0
- data/ext/ngtcp2/lib/ngtcp2_vec.c +243 -0
- data/ext/ngtcp2/lib/ngtcp2_vec.h +120 -0
- data/ext/ngtcp2/lib/ngtcp2_version.c +39 -0
- data/ext/ngtcp2/lib/ngtcp2_window_filter.c +99 -0
- data/ext/ngtcp2/lib/ngtcp2_window_filter.h +65 -0
- data/ext/ngtcp2/m4/ax_check_compile_flag.m4 +74 -0
- data/ext/ngtcp2/m4/ax_cxx_compile_stdcxx.m4 +1009 -0
- data/ext/ngtcp2/tests/CMakeLists.txt +68 -0
- data/ext/ngtcp2/tests/Makefile.am +94 -0
- data/ext/ngtcp2/tests/main.c +358 -0
- data/ext/ngtcp2/tests/ngtcp2_acktr_test.c +367 -0
- data/ext/ngtcp2/tests/ngtcp2_acktr_test.h +37 -0
- data/ext/ngtcp2/tests/ngtcp2_conn_test.c +9821 -0
- data/ext/ngtcp2/tests/ngtcp2_conn_test.h +104 -0
- data/ext/ngtcp2/tests/ngtcp2_conv_test.c +430 -0
- data/ext/ngtcp2/tests/ngtcp2_conv_test.h +46 -0
- data/ext/ngtcp2/tests/ngtcp2_crypto_test.c +667 -0
- data/ext/ngtcp2/tests/ngtcp2_crypto_test.h +35 -0
- data/ext/ngtcp2/tests/ngtcp2_gaptr_test.c +127 -0
- data/ext/ngtcp2/tests/ngtcp2_gaptr_test.h +36 -0
- data/ext/ngtcp2/tests/ngtcp2_idtr_test.c +79 -0
- data/ext/ngtcp2/tests/ngtcp2_idtr_test.h +34 -0
- data/ext/ngtcp2/tests/ngtcp2_ksl_test.c +502 -0
- data/ext/ngtcp2/tests/ngtcp2_ksl_test.h +39 -0
- data/ext/ngtcp2/tests/ngtcp2_map_test.c +206 -0
- data/ext/ngtcp2/tests/ngtcp2_map_test.h +38 -0
- data/ext/ngtcp2/tests/ngtcp2_pkt_test.c +1645 -0
- data/ext/ngtcp2/tests/ngtcp2_pkt_test.h +68 -0
- data/ext/ngtcp2/tests/ngtcp2_pmtud_test.c +153 -0
- data/ext/ngtcp2/tests/ngtcp2_pmtud_test.h +34 -0
- data/ext/ngtcp2/tests/ngtcp2_pv_test.c +129 -0
- data/ext/ngtcp2/tests/ngtcp2_pv_test.h +35 -0
- data/ext/ngtcp2/tests/ngtcp2_range_test.c +105 -0
- data/ext/ngtcp2/tests/ngtcp2_range_test.h +36 -0
- data/ext/ngtcp2/tests/ngtcp2_ringbuf_test.c +91 -0
- data/ext/ngtcp2/tests/ngtcp2_ringbuf_test.h +35 -0
- data/ext/ngtcp2/tests/ngtcp2_rob_test.c +552 -0
- data/ext/ngtcp2/tests/ngtcp2_rob_test.h +37 -0
- data/ext/ngtcp2/tests/ngtcp2_rtb_test.c +470 -0
- data/ext/ngtcp2/tests/ngtcp2_rtb_test.h +38 -0
- data/ext/ngtcp2/tests/ngtcp2_str_test.c +96 -0
- data/ext/ngtcp2/tests/ngtcp2_str_test.h +36 -0
- data/ext/ngtcp2/tests/ngtcp2_strm_test.c +575 -0
- data/ext/ngtcp2/tests/ngtcp2_strm_test.h +36 -0
- data/ext/ngtcp2/tests/ngtcp2_test_helper.c +404 -0
- data/ext/ngtcp2/tests/ngtcp2_test_helper.h +191 -0
- data/ext/ngtcp2/tests/ngtcp2_vec_test.c +426 -0
- data/ext/ngtcp2/tests/ngtcp2_vec_test.h +36 -0
- data/ext/ngtcp2/third-party/CMakeLists.txt +34 -0
- data/ext/ngtcp2/third-party/Makefile.am +31 -0
- data/ext/ngtcp2/third-party/http-parser/AUTHORS +68 -0
- data/ext/ngtcp2/third-party/http-parser/LICENSE-MIT +23 -0
- data/ext/ngtcp2/third-party/http-parser/Makefile +157 -0
- data/ext/ngtcp2/third-party/http-parser/README.md +246 -0
- data/ext/ngtcp2/third-party/http-parser/bench.c +111 -0
- data/ext/ngtcp2/third-party/http-parser/contrib/parsertrace.c +160 -0
- data/ext/ngtcp2/third-party/http-parser/contrib/url_parser.c +47 -0
- data/ext/ngtcp2/third-party/http-parser/http_parser.c +2419 -0
- data/ext/ngtcp2/third-party/http-parser/http_parser.gyp +111 -0
- data/ext/ngtcp2/third-party/http-parser/http_parser.h +431 -0
- data/ext/ngtcp2/third-party/http-parser/test.c +4411 -0
- data/lib/protocol/quic/version.rb +10 -0
- data/lib/protocol/quic.rb +9 -0
- data/license.md +21 -0
- data.tar.gz.sig +1 -0
- metadata +424 -0
- 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
|
+
}
|