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