diff options
Diffstat (limited to '')
40 files changed, 631 insertions, 184 deletions
@@ -1,3 +1,17 @@ +Knot DNS 3.3.7 (2024-06-25) +=========================== + +Improvements: +------------- + - libs: upgraded embedded libngtcp2 to 1.6.0 + +Bugfixes: +--------- + - knotd: insufficient metadata check can cause journal corruption + - knotd: missing zone timers initialization upon purge + - knotd: missing RCU lock in zone flush and refresh + - knotd: defective assert in zone refresh + Knot DNS 3.3.6 (2024-06-12) =========================== @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for knot 3.3.6. +# Generated by GNU Autoconf 2.71 for knot 3.3.7. # # Report bugs to <knot-dns@labs.nic.cz>. # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='knot' PACKAGE_TARNAME='knot' -PACKAGE_VERSION='3.3.6' -PACKAGE_STRING='knot 3.3.6' +PACKAGE_VERSION='3.3.7' +PACKAGE_STRING='knot 3.3.7' PACKAGE_BUGREPORT='knot-dns@labs.nic.cz' PACKAGE_URL='' @@ -1603,7 +1603,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures knot 3.3.6 to adapt to many kinds of systems. +\`configure' configures knot 3.3.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1674,7 +1674,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of knot 3.3.6:";; + short | recursive ) echo "Configuration of knot 3.3.7:";; esac cat <<\_ACEOF @@ -1923,7 +1923,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -knot configure 3.3.6 +knot configure 3.3.7 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2274,7 +2274,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by knot $as_me 3.3.6, which was +It was created by knot $as_me 3.3.7, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3549,7 +3549,7 @@ fi # Define the identity of the package. PACKAGE='knot' - VERSION='3.3.6' + VERSION='3.3.7' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5269,7 +5269,7 @@ KNOT_VERSION_MAJOR=3 KNOT_VERSION_MINOR=3 -KNOT_VERSION_PATCH=6 +KNOT_VERSION_PATCH=7 # Store ./configure parameters and CFLAGS @@ -21750,7 +21750,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by knot $as_me 3.3.6, which was +This file was extended by knot $as_me 3.3.7, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21818,7 +21818,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -knot config.status 3.3.6 +knot config.status 3.3.7 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 6f5859f..949d734 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.69]) m4_define([knot_VERSION_MAJOR], 3)dnl m4_define([knot_VERSION_MINOR], 3)dnl -m4_define([knot_VERSION_PATCH], 6)dnl Leave empty if the master branch! +m4_define([knot_VERSION_PATCH], 7)dnl Leave empty if the master branch! m4_include([m4/knot-version.m4]) AC_INIT([knot], [knot_PKG_VERSION], [knot-dns@labs.nic.cz]) diff --git a/distro/pkg/deb-noxdp/patches/05-revert-mod-dnstap-TCP-sink.patch b/distro/pkg/deb-noxdp/patches/05-revert-mod-dnstap-TCP-sink.patch new file mode 100644 index 0000000..dae0fac --- /dev/null +++ b/distro/pkg/deb-noxdp/patches/05-revert-mod-dnstap-TCP-sink.patch @@ -0,0 +1,160 @@ +From d236d2b7fcd5fa607f7bfd38044eb6f510fac7ce Mon Sep 17 00:00:00 2001 +From: Daniel Salzman <daniel.salzman@nic.cz> +Date: Wed, 12 Jun 2024 11:18:31 +0200 +Subject: [PATCH] Revert "mod-dnstap: add sink for TCP connection" + +This reverts commit 2ffd7dfa58ddcd1b860f0c9980fd082c3852d3e6. +--- + src/knot/modules/dnstap/dnstap.c | 74 +++++------------------------- + src/knot/modules/dnstap/dnstap.rst | 9 ++-- + 2 files changed, 15 insertions(+), 68 deletions(-) + +diff --git a/src/knot/modules/dnstap/dnstap.c b/src/knot/modules/dnstap/dnstap.c +index 612e48869..c8c82eaa4 100644 +--- a/src/knot/modules/dnstap/dnstap.c ++++ b/src/knot/modules/dnstap/dnstap.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> ++/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -185,33 +185,6 @@ finish: + return writer; + } + +-static struct fstrm_writer* dnstap_tcp_writer(const char *address, const char *port) +-{ +- struct fstrm_tcp_writer_options *opt = NULL; +- struct fstrm_writer_options *wopt = NULL; +- struct fstrm_writer *writer = NULL; +- +- opt = fstrm_tcp_writer_options_init(); +- if (opt == NULL) { +- goto finish; +- } +- +- fstrm_tcp_writer_options_set_socket_address(opt, address); +- fstrm_tcp_writer_options_set_socket_port(opt, port); +- +- wopt = fstrm_writer_options_init(); +- if (wopt == NULL) { +- goto finish; +- } +- fstrm_writer_options_add_content_type(wopt, DNSTAP_CONTENT_TYPE, +- strlen(DNSTAP_CONTENT_TYPE)); +- writer = fstrm_tcp_writer_init(opt, wopt); +-finish: +- fstrm_tcp_writer_options_destroy(&opt); +- fstrm_writer_options_destroy(&wopt); +- return writer; +-} +- + /*! \brief Create a basic file writer sink. */ + static struct fstrm_writer* dnstap_file_writer(const char *path) + { +@@ -240,42 +213,17 @@ finish: + } + + /*! \brief Create a log sink according to the path string. */ +-static struct fstrm_writer* dnstap_writer(knotd_mod_t *mod, const char *path) ++static struct fstrm_writer* dnstap_writer(const char *path) + { +- const char *unix_prefix = "unix:"; +- const size_t unix_prefix_len = strlen(unix_prefix); +- +- const char *tcp_prefix = "tcp:"; +- const size_t tcp_prefix_len = strlen(tcp_prefix); +- +- const size_t path_len = strlen(path); ++ const char *prefix = "unix:"; ++ const size_t prefix_len = strlen(prefix); + + /* UNIX socket prefix. */ +- if (path_len > unix_prefix_len && +- strncmp(path, unix_prefix, unix_prefix_len) == 0) { +- knotd_mod_log(mod, LOG_DEBUG, "using sink UNIX socket '%s'", path); +- return dnstap_unix_writer(path + unix_prefix_len); +- /* TCP socket prefix. */ +- } else if (path_len > tcp_prefix_len && +- strncmp(path, tcp_prefix, tcp_prefix_len) == 0) { +- char addr[INET6_ADDRSTRLEN] = { 0 }; +- const char *delimiter = strchr(path + tcp_prefix_len, '@'); +- if (delimiter == NULL) { +- return NULL; +- } +- size_t addr_len = delimiter - path - tcp_prefix_len; +- if (addr_len >= sizeof(addr)) { +- return NULL; +- } +- memcpy(addr, path + tcp_prefix_len, addr_len); +- knotd_mod_log(mod, LOG_DEBUG, "using sink TCP address '%s' port '%s'", +- addr, delimiter + 1); +- return dnstap_tcp_writer(addr, delimiter + 1); +- /* File path. */ +- } else { +- knotd_mod_log(mod, LOG_DEBUG, "using sink file '%s'", path); +- return dnstap_file_writer(path); ++ if (strlen(path) > prefix_len && strncmp(path, prefix, prefix_len) == 0) { ++ return dnstap_unix_writer(path + prefix_len); + } ++ ++ return dnstap_file_writer(path); + } + + int dnstap_load(knotd_mod_t *mod) +@@ -325,7 +273,7 @@ int dnstap_load(knotd_mod_t *mod) + const bool log_responses = conf.single.boolean; + + /* Initialize the writer and the options. */ +- struct fstrm_writer *writer = dnstap_writer(mod, sink); ++ struct fstrm_writer *writer = dnstap_writer(sink); + if (writer == NULL) { + goto fail; + } +@@ -359,13 +307,13 @@ int dnstap_load(knotd_mod_t *mod) + + return KNOT_EOK; + fail: +- knotd_mod_log(mod, LOG_ERR, "failed to initialize sink '%s'", sink); ++ knotd_mod_log(mod, LOG_ERR, "failed to init sink '%s'", sink); + + free(ctx->identity); + free(ctx->version); + free(ctx); + +- return KNOT_EINVAL; ++ return KNOT_ENOMEM; + } + + void dnstap_unload(knotd_mod_t *mod) +diff --git a/src/knot/modules/dnstap/dnstap.rst b/src/knot/modules/dnstap/dnstap.rst +index 05eac09ab..358977da0 100644 +--- a/src/knot/modules/dnstap/dnstap.rst ++++ b/src/knot/modules/dnstap/dnstap.rst +@@ -11,7 +11,7 @@ Example + ------- + + The configuration comprises only a :ref:`mod-dnstap_sink` path parameter, +-which can be either a file, a UNIX socket, or a TCP address:: ++which can be either a file or a UNIX socket:: + + mod-dnstap: + - id: capture_all +@@ -60,10 +60,9 @@ A module identifier. + sink + .... + +-A sink path, which can be either a file, a UNIX socket when prefixed with +-``unix:``, or a TCP `address@port` when prefixed with ``tcp:``. The file may +-be specified as an absolute path or a path relative to +-the :doc:`knotd<man_knotd>` startup directory. ++A sink path, which can be either a file or a UNIX socket when prefixed with ++``unix:``. The file may be specified as an absolute path or a path relative ++to the :doc:`knotd<man_knotd>` startup directory. + + *Required* + +-- +2.34.1 + diff --git a/distro/pkg/deb-noxdp/patches/series b/distro/pkg/deb-noxdp/patches/series new file mode 100644 index 0000000..54de4e3 --- /dev/null +++ b/distro/pkg/deb-noxdp/patches/series @@ -0,0 +1 @@ +05-revert-mod-dnstap-TCP-sink.patch diff --git a/distro/pkg/el-7/05-revert-mod-dnstap-TCP-sink.patch b/distro/pkg/el-7/05-revert-mod-dnstap-TCP-sink.patch new file mode 100644 index 0000000..dae0fac --- /dev/null +++ b/distro/pkg/el-7/05-revert-mod-dnstap-TCP-sink.patch @@ -0,0 +1,160 @@ +From d236d2b7fcd5fa607f7bfd38044eb6f510fac7ce Mon Sep 17 00:00:00 2001 +From: Daniel Salzman <daniel.salzman@nic.cz> +Date: Wed, 12 Jun 2024 11:18:31 +0200 +Subject: [PATCH] Revert "mod-dnstap: add sink for TCP connection" + +This reverts commit 2ffd7dfa58ddcd1b860f0c9980fd082c3852d3e6. +--- + src/knot/modules/dnstap/dnstap.c | 74 +++++------------------------- + src/knot/modules/dnstap/dnstap.rst | 9 ++-- + 2 files changed, 15 insertions(+), 68 deletions(-) + +diff --git a/src/knot/modules/dnstap/dnstap.c b/src/knot/modules/dnstap/dnstap.c +index 612e48869..c8c82eaa4 100644 +--- a/src/knot/modules/dnstap/dnstap.c ++++ b/src/knot/modules/dnstap/dnstap.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> ++/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -185,33 +185,6 @@ finish: + return writer; + } + +-static struct fstrm_writer* dnstap_tcp_writer(const char *address, const char *port) +-{ +- struct fstrm_tcp_writer_options *opt = NULL; +- struct fstrm_writer_options *wopt = NULL; +- struct fstrm_writer *writer = NULL; +- +- opt = fstrm_tcp_writer_options_init(); +- if (opt == NULL) { +- goto finish; +- } +- +- fstrm_tcp_writer_options_set_socket_address(opt, address); +- fstrm_tcp_writer_options_set_socket_port(opt, port); +- +- wopt = fstrm_writer_options_init(); +- if (wopt == NULL) { +- goto finish; +- } +- fstrm_writer_options_add_content_type(wopt, DNSTAP_CONTENT_TYPE, +- strlen(DNSTAP_CONTENT_TYPE)); +- writer = fstrm_tcp_writer_init(opt, wopt); +-finish: +- fstrm_tcp_writer_options_destroy(&opt); +- fstrm_writer_options_destroy(&wopt); +- return writer; +-} +- + /*! \brief Create a basic file writer sink. */ + static struct fstrm_writer* dnstap_file_writer(const char *path) + { +@@ -240,42 +213,17 @@ finish: + } + + /*! \brief Create a log sink according to the path string. */ +-static struct fstrm_writer* dnstap_writer(knotd_mod_t *mod, const char *path) ++static struct fstrm_writer* dnstap_writer(const char *path) + { +- const char *unix_prefix = "unix:"; +- const size_t unix_prefix_len = strlen(unix_prefix); +- +- const char *tcp_prefix = "tcp:"; +- const size_t tcp_prefix_len = strlen(tcp_prefix); +- +- const size_t path_len = strlen(path); ++ const char *prefix = "unix:"; ++ const size_t prefix_len = strlen(prefix); + + /* UNIX socket prefix. */ +- if (path_len > unix_prefix_len && +- strncmp(path, unix_prefix, unix_prefix_len) == 0) { +- knotd_mod_log(mod, LOG_DEBUG, "using sink UNIX socket '%s'", path); +- return dnstap_unix_writer(path + unix_prefix_len); +- /* TCP socket prefix. */ +- } else if (path_len > tcp_prefix_len && +- strncmp(path, tcp_prefix, tcp_prefix_len) == 0) { +- char addr[INET6_ADDRSTRLEN] = { 0 }; +- const char *delimiter = strchr(path + tcp_prefix_len, '@'); +- if (delimiter == NULL) { +- return NULL; +- } +- size_t addr_len = delimiter - path - tcp_prefix_len; +- if (addr_len >= sizeof(addr)) { +- return NULL; +- } +- memcpy(addr, path + tcp_prefix_len, addr_len); +- knotd_mod_log(mod, LOG_DEBUG, "using sink TCP address '%s' port '%s'", +- addr, delimiter + 1); +- return dnstap_tcp_writer(addr, delimiter + 1); +- /* File path. */ +- } else { +- knotd_mod_log(mod, LOG_DEBUG, "using sink file '%s'", path); +- return dnstap_file_writer(path); ++ if (strlen(path) > prefix_len && strncmp(path, prefix, prefix_len) == 0) { ++ return dnstap_unix_writer(path + prefix_len); + } ++ ++ return dnstap_file_writer(path); + } + + int dnstap_load(knotd_mod_t *mod) +@@ -325,7 +273,7 @@ int dnstap_load(knotd_mod_t *mod) + const bool log_responses = conf.single.boolean; + + /* Initialize the writer and the options. */ +- struct fstrm_writer *writer = dnstap_writer(mod, sink); ++ struct fstrm_writer *writer = dnstap_writer(sink); + if (writer == NULL) { + goto fail; + } +@@ -359,13 +307,13 @@ int dnstap_load(knotd_mod_t *mod) + + return KNOT_EOK; + fail: +- knotd_mod_log(mod, LOG_ERR, "failed to initialize sink '%s'", sink); ++ knotd_mod_log(mod, LOG_ERR, "failed to init sink '%s'", sink); + + free(ctx->identity); + free(ctx->version); + free(ctx); + +- return KNOT_EINVAL; ++ return KNOT_ENOMEM; + } + + void dnstap_unload(knotd_mod_t *mod) +diff --git a/src/knot/modules/dnstap/dnstap.rst b/src/knot/modules/dnstap/dnstap.rst +index 05eac09ab..358977da0 100644 +--- a/src/knot/modules/dnstap/dnstap.rst ++++ b/src/knot/modules/dnstap/dnstap.rst +@@ -11,7 +11,7 @@ Example + ------- + + The configuration comprises only a :ref:`mod-dnstap_sink` path parameter, +-which can be either a file, a UNIX socket, or a TCP address:: ++which can be either a file or a UNIX socket:: + + mod-dnstap: + - id: capture_all +@@ -60,10 +60,9 @@ A module identifier. + sink + .... + +-A sink path, which can be either a file, a UNIX socket when prefixed with +-``unix:``, or a TCP `address@port` when prefixed with ``tcp:``. The file may +-be specified as an absolute path or a path relative to +-the :doc:`knotd<man_knotd>` startup directory. ++A sink path, which can be either a file or a UNIX socket when prefixed with ++``unix:``. The file may be specified as an absolute path or a path relative ++to the :doc:`knotd<man_knotd>` startup directory. + + *Required* + +-- +2.34.1 + diff --git a/distro/pkg/el-7/knot.spec b/distro/pkg/el-7/knot.spec index 93d05bb..887f988 100644 --- a/distro/pkg/el-7/knot.spec +++ b/distro/pkg/el-7/knot.spec @@ -26,6 +26,7 @@ Patch1: 01-revert-AC_PROG_CC.patch Patch2: 02-fix-compilation-by-using-SHA-1.patch Patch3: 03-doc-don-t-try-to-import-sphinx_panels.patch Patch4: 04-revert-don-t-share-PKCS-11-private-keys.patch +Patch5: 05-revert-mod-dnstap-TCP-sink.patch # Required dependencies BuildRequires: autoconf diff --git a/src/contrib/libngtcp2/ngtcp2/crypto/shared.c b/src/contrib/libngtcp2/ngtcp2/crypto/shared.c index 604cb96..63b3856 100644 --- a/src/contrib/libngtcp2/ngtcp2/crypto/shared.c +++ b/src/contrib/libngtcp2/ngtcp2/crypto/shared.c @@ -125,7 +125,7 @@ int ngtcp2_crypto_derive_initial_secrets(uint8_t *rx_secret, uint8_t *tx_secret, size_t ngtcp2_crypto_packet_protection_ivlen(const ngtcp2_crypto_aead *aead) { size_t noncelen = ngtcp2_crypto_aead_noncelen(aead); - return ngtcp2_max(8, noncelen); + return ngtcp2_max_size(8, noncelen); } int ngtcp2_crypto_derive_packet_protection_key( diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c index 3ed581f..b76d1c8 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c @@ -62,7 +62,8 @@ static int greater(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) { void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log, const ngtcp2_mem *mem) { - ngtcp2_objalloc_acktr_entry_init(&acktr->objalloc, 32, mem); + ngtcp2_objalloc_acktr_entry_init(&acktr->objalloc, NGTCP2_ACKTR_MAX_ENT + 1, + mem); ngtcp2_static_ringbuf_acks_init(&acktr->acks); diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h index 0cbb490..f5c2b3d 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h @@ -39,7 +39,7 @@ /* NGTCP2_ACKTR_MAX_ENT is the maximum number of ngtcp2_acktr_entry which ngtcp2_acktr stores. */ -#define NGTCP2_ACKTR_MAX_ENT 1024 +#define NGTCP2_ACKTR_MAX_ENT (NGTCP2_MAX_ACK_RANGES + 1) typedef struct ngtcp2_log ngtcp2_log; diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c index ebc6f48..2211a31 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c @@ -493,9 +493,9 @@ static void bbr_update_on_loss(ngtcp2_cc_bbr *cc, ngtcp2_conn_stat *cstat, static void bbr_update_latest_delivery_signals(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) { bbr->loss_round_start = 0; - bbr->bw_latest = ngtcp2_max(bbr->bw_latest, cstat->delivery_rate_sec); + bbr->bw_latest = ngtcp2_max_uint64(bbr->bw_latest, cstat->delivery_rate_sec); bbr->inflight_latest = - ngtcp2_max(bbr->inflight_latest, bbr->rst->rs.delivered); + ngtcp2_max_uint64(bbr->inflight_latest, bbr->rst->rs.delivered); if (bbr->rst->rs.prior_delivered >= bbr->loss_round_delivered) { bbr->loss_round_delivered = bbr->rst->delivered; @@ -567,8 +567,8 @@ static void bbr_loss_lower_bounds(ngtcp2_cc_bbr *bbr) { } static void bbr_bound_bw_for_model(ngtcp2_cc_bbr *bbr) { - bbr->bw = ngtcp2_min(bbr->max_bw, bbr->bw_lo); - bbr->bw = ngtcp2_min(bbr->bw, bbr->bw_hi); + bbr->bw = ngtcp2_min_uint64(bbr->max_bw, bbr->bw_lo); + bbr->bw = ngtcp2_min_uint64(bbr->bw, bbr->bw_hi); } static void bbr_update_max_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat, @@ -634,7 +634,7 @@ static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr, bbr->extra_acked_delivered += ack->bytes_delivered; extra = bbr->extra_acked_delivered - expected_delivered; - extra = ngtcp2_min(extra, cstat->cwnd); + extra = ngtcp2_min_uint64(extra, cstat->cwnd); ngtcp2_window_filter_update(&bbr->extra_acked_filter, extra, bbr->round_count); @@ -911,14 +911,14 @@ static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr, uint64_t reno_rounds = bbr_target_inflight(bbr, cstat) / cstat->max_tx_udp_payload_size; - return bbr->rounds_since_bw_probe >= ngtcp2_min(reno_rounds, 63); + return bbr->rounds_since_bw_probe >= ngtcp2_min_uint64(reno_rounds, 63); } static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) { uint64_t bdp = bbr_inflight(bbr, cstat, bbr->bw, 100); - return ngtcp2_min(bdp, cstat->cwnd); + return ngtcp2_min_uint64(bdp, cstat->cwnd); } static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr, @@ -1154,7 +1154,7 @@ static uint64_t bbr_quantization_budget(ngtcp2_cc_bbr *bbr, uint64_t inflight) { bbr_update_offload_budget(bbr, cstat); - inflight = ngtcp2_max(inflight, bbr->offload_budget); + inflight = ngtcp2_max_uint64(inflight, bbr->offload_budget); inflight = ngtcp2_max_uint64(inflight, min_pipe_cwnd(cstat->max_tx_udp_payload_size)); @@ -1218,11 +1218,11 @@ static void bbr_save_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) { return; } - bbr->prior_cwnd = ngtcp2_max(bbr->prior_cwnd, cstat->cwnd); + bbr->prior_cwnd = ngtcp2_max_uint64(bbr->prior_cwnd, cstat->cwnd); } static void bbr_restore_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) { - cstat->cwnd = ngtcp2_max(cstat->cwnd, bbr->prior_cwnd); + cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, bbr->prior_cwnd); } static uint64_t bbr_probe_rtt_cwnd(ngtcp2_cc_bbr *bbr, @@ -1231,7 +1231,7 @@ static uint64_t bbr_probe_rtt_cwnd(ngtcp2_cc_bbr *bbr, bbr_bdp_multiple(bbr, bbr->bw, NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H); uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size); - return ngtcp2_max(probe_rtt_cwnd, mpcwnd); + return ngtcp2_max_uint64(probe_rtt_cwnd, mpcwnd); } static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_cc_bbr *bbr, @@ -1241,7 +1241,7 @@ static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_cc_bbr *bbr, if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT) { probe_rtt_cwnd = bbr_probe_rtt_cwnd(bbr, cstat); - cstat->cwnd = ngtcp2_min(cstat->cwnd, probe_rtt_cwnd); + cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, probe_rtt_cwnd); } } @@ -1255,14 +1255,14 @@ static void bbr_set_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat, if (!bbr->packet_conservation) { if (bbr->filled_pipe) { cstat->cwnd += ack->bytes_delivered; - cstat->cwnd = ngtcp2_min(cstat->cwnd, bbr->max_inflight); + cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, bbr->max_inflight); } else if (cstat->cwnd < bbr->max_inflight || bbr->rst->delivered < bbr->initial_cwnd) { cstat->cwnd += ack->bytes_delivered; } mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size); - cstat->cwnd = ngtcp2_max(cstat->cwnd, mpcwnd); + cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, mpcwnd); } bbr_bound_cwnd_for_probe_rtt(bbr, cstat); @@ -1282,10 +1282,10 @@ static void bbr_bound_cwnd_for_model(ngtcp2_cc_bbr *bbr, cap = bbr_inflight_with_headroom(bbr, cstat); } - cap = ngtcp2_min(cap, bbr->inflight_lo); - cap = ngtcp2_max(cap, mpcwnd); + cap = ngtcp2_min_uint64(cap, bbr->inflight_lo); + cap = ngtcp2_max_uint64(cap, mpcwnd); - cstat->cwnd = ngtcp2_min(cstat->cwnd, cap); + cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, cap); } static void bbr_set_send_quantum(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) { @@ -1300,12 +1300,12 @@ static void bbr_set_send_quantum(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) { if (cstat->pacing_interval) { send_quantum = (size_t)(NGTCP2_MILLISECONDS / cstat->pacing_interval); - send_quantum = ngtcp2_min(send_quantum, 64 * 1024); + send_quantum = ngtcp2_min_size(send_quantum, 64 * 1024); } else { send_quantum = 64 * 1024; } - cstat->send_quantum = ngtcp2_max(send_quantum, floor); + cstat->send_quantum = ngtcp2_max_size(send_quantum, floor); } static int in_congestion_recovery(const ngtcp2_conn_stat *cstat, @@ -1336,7 +1336,7 @@ static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat, bbr_save_cwnd(bbr, cstat); cstat->cwnd = cstat->bytes_in_flight + - ngtcp2_max(ack->bytes_delivered, cstat->max_tx_udp_payload_size); + ngtcp2_max_uint64(ack->bytes_delivered, cstat->max_tx_udp_payload_size); cstat->congestion_recovery_start_ts = bbr->congestion_recovery_start_ts; bbr->congestion_recovery_start_ts = UINT64_MAX; @@ -1383,9 +1383,11 @@ static void bbr_cc_on_spurious_congestion(ngtcp2_cc *cc, bbr_restore_cwnd(bbr, cstat); bbr->full_bw_count = 0; bbr->loss_in_round = 0; - bbr->inflight_lo = ngtcp2_max(bbr->inflight_lo, bbr->prior_inflight_lo); - bbr->inflight_hi = ngtcp2_max(bbr->inflight_hi, bbr->prior_inflight_hi); - bbr->bw_lo = ngtcp2_max(bbr->bw_lo, bbr->prior_bw_lo); + bbr->inflight_lo = + ngtcp2_max_uint64(bbr->inflight_lo, bbr->prior_inflight_lo); + bbr->inflight_hi = + ngtcp2_max_uint64(bbr->inflight_hi, bbr->prior_inflight_hi); + bbr->bw_lo = ngtcp2_max_uint64(bbr->bw_lo, bbr->prior_bw_lo); } } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c index bade016..c547efc 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c @@ -40,7 +40,7 @@ uint64_t ngtcp2_cc_compute_initcwnd(size_t max_udp_payload_size) { uint64_t n = 2 * max_udp_payload_size; - n = ngtcp2_max(n, 14720); + n = ngtcp2_max_uint64(n, 14720); return ngtcp2_min_uint64(10 * max_udp_payload_size, n); } @@ -129,7 +129,7 @@ void ngtcp2_cc_reno_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, cstat->congestion_recovery_start_ts = ts; cstat->cwnd >>= NGTCP2_LOSS_REDUCTION_FACTOR_BITS; min_cwnd = 2 * cstat->max_tx_udp_payload_size; - cstat->cwnd = ngtcp2_max(cstat->cwnd, min_cwnd); + cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, min_cwnd); cstat->ssthresh = cstat->cwnd; reno->pending_add = 0; @@ -168,7 +168,7 @@ void ngtcp2_cc_reno_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, if (cstat->min_rtt != UINT64_MAX && max_delivery_rate_sec) { target_cwnd = max_delivery_rate_sec * cstat->smoothed_rtt / NGTCP2_SECONDS; initcwnd = ngtcp2_cc_compute_initcwnd(cstat->max_tx_udp_payload_size); - reno->target_cwnd = ngtcp2_max(initcwnd, target_cwnd) * 289 / 100; + reno->target_cwnd = ngtcp2_max_uint64(initcwnd, target_cwnd) * 289 / 100; ngtcp2_log_info(reno->cc.log, NGTCP2_LOG_EVENT_CCA, "target_cwnd=%" PRIu64 " max_delivery_rate_sec=%" PRIu64 @@ -436,7 +436,7 @@ void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, min_cwnd = 2 * cstat->max_tx_udp_payload_size; cstat->ssthresh = cstat->cwnd * 7 / 10; - cstat->ssthresh = ngtcp2_max(cstat->ssthresh, min_cwnd); + cstat->ssthresh = ngtcp2_max_uint64(cstat->ssthresh, min_cwnd); cstat->cwnd = cstat->ssthresh; ngtcp2_log_info(cubic->cc.log, NGTCP2_LOG_EVENT_CCA, @@ -508,7 +508,7 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, if (cstat->min_rtt != UINT64_MAX && max_delivery_rate_sec) { target_cwnd = max_delivery_rate_sec * cstat->smoothed_rtt / NGTCP2_SECONDS; initcwnd = ngtcp2_cc_compute_initcwnd(cstat->max_tx_udp_payload_size); - cubic->target_cwnd = ngtcp2_max(initcwnd, target_cwnd) * 289 / 100; + cubic->target_cwnd = ngtcp2_max_uint64(initcwnd, target_cwnd) * 289 / 100; ngtcp2_log_info(cubic->cc.log, NGTCP2_LOG_EVENT_CCA, "target_cwnd=%" PRIu64 " max_delivery_rate_sec=%" PRIu64 @@ -543,7 +543,7 @@ void ngtcp2_cc_cubic_cc_new_rtt_sample(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat, } cubic->current_round_min_rtt = - ngtcp2_min(cubic->current_round_min_rtt, cstat->latest_rtt); + ngtcp2_min_uint64(cubic->current_round_min_rtt, cstat->latest_rtt); ++cubic->rtt_sample_count; } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c index a8e8874..a5a47b7 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c @@ -883,7 +883,7 @@ static ngtcp2_duration conn_compute_pv_timeout_pto(ngtcp2_conn *conn, ngtcp2_duration pto) { ngtcp2_duration initial_pto = conn_compute_initial_pto(conn, &conn->pktns); - return 3 * ngtcp2_max(pto, initial_pto); + return 3 * ngtcp2_max_uint64(pto, initial_pto); } /* @@ -1147,9 +1147,9 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid, (*pconn)->server = server; - ngtcp2_objalloc_frame_chain_init(&(*pconn)->frc_objalloc, 64, mem); - ngtcp2_objalloc_rtb_entry_init(&(*pconn)->rtb_entry_objalloc, 64, mem); - ngtcp2_objalloc_strm_init(&(*pconn)->strm_objalloc, 64, mem); + ngtcp2_objalloc_frame_chain_init(&(*pconn)->frc_objalloc, 16, mem); + ngtcp2_objalloc_rtb_entry_init(&(*pconn)->rtb_entry_objalloc, 16, mem); + ngtcp2_objalloc_strm_init(&(*pconn)->strm_objalloc, 16, mem); ngtcp2_static_ringbuf_dcid_bound_init(&(*pconn)->dcid.bound); @@ -1483,7 +1483,7 @@ static uint64_t conn_fc_credits(ngtcp2_conn *conn, ngtcp2_strm *strm) { static uint64_t conn_enforce_flow_control(ngtcp2_conn *conn, ngtcp2_strm *strm, uint64_t len) { uint64_t fc_credits = conn_fc_credits(conn, strm); - return ngtcp2_min(len, fc_credits); + return ngtcp2_min_uint64(len, fc_credits); } static int delete_strms_each(void *data, void *ptr) { @@ -1940,7 +1940,7 @@ static uint64_t conn_retry_early_payloadlen(ngtcp2_conn *conn) { /* Take the min because in conn_should_pad_pkt we take max in order to deal with unbreakable DATAGRAM. */ - return ngtcp2_min(len, NGTCP2_MIN_COALESCED_PAYLOADLEN); + return ngtcp2_min_uint64(len, NGTCP2_MIN_COALESCED_PAYLOADLEN); } return 0; @@ -2038,7 +2038,7 @@ static int conn_should_pad_pkt(ngtcp2_conn *conn, uint8_t type, size_t left, PADDING in that packet. Take maximum in case that write_datalen includes DATAGRAM which cannot be split. */ min_payloadlen = - ngtcp2_max(write_datalen, NGTCP2_MIN_COALESCED_PAYLOADLEN); + ngtcp2_max_uint64(write_datalen, NGTCP2_MIN_COALESCED_PAYLOADLEN); } else { return 1; } @@ -2815,7 +2815,7 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn, ngtcp2_log_info( &conn->log, NGTCP2_LOG_EVENT_LDC, "loss detection timer canceled due to amplification limit"); - cstat->loss_detection_timer = UINT64_MAX; + ngtcp2_conn_cancel_loss_detection_timer(conn); } return 0; @@ -2937,9 +2937,9 @@ static size_t conn_required_num_new_connection_id(ngtcp2_conn *conn) { n = conn->remote.transport_params->active_connection_id_limit + conn->scid.num_retired; - n = ngtcp2_min(NGTCP2_MAX_SCID_POOL_SIZE, n) - len; + n = ngtcp2_min_uint64(NGTCP2_MAX_SCID_POOL_SIZE, n) - len; - return (size_t)ngtcp2_min(lim, n); + return (size_t)ngtcp2_min_uint64(lim, n); } /* @@ -3086,7 +3086,7 @@ static int conn_remove_retired_connection_id(ngtcp2_conn *conn, * this endpoint sends. */ static size_t conn_min_short_pktlen(ngtcp2_conn *conn) { - return ngtcp2_max(conn->dcid.current.cid.datalen, conn->oscid.datalen) + + return ngtcp2_max_size(conn->dcid.current.cid.datalen, conn->oscid.datalen) + NGTCP2_MIN_PKT_EXPANDLEN; } @@ -4148,6 +4148,8 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING; if (conn->pktns.rtb.probe_pkt_left) { rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_PROBE; + } else if (keep_alive_expired) { + rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING; } pktns->tx.non_ack_pkt_start_ts = UINT64_MAX; } @@ -4656,7 +4658,7 @@ static int conn_start_pmtud(ngtcp2_conn *conn) { assert(conn->remote.transport_params->max_udp_payload_size >= NGTCP2_MAX_UDP_PAYLOAD_SIZE); - hard_max_udp_payload_size = (size_t)ngtcp2_min( + hard_max_udp_payload_size = (size_t)ngtcp2_min_uint64( conn->remote.transport_params->max_udp_payload_size, (uint64_t)conn->local.settings.max_tx_udp_payload_size); @@ -4813,19 +4815,19 @@ static size_t conn_shape_udp_payload(ngtcp2_conn *conn, const ngtcp2_dcid *dcid, assert(conn->remote.transport_params->max_udp_payload_size >= NGTCP2_MAX_UDP_PAYLOAD_SIZE); - payloadlen = - (size_t)ngtcp2_min((uint64_t)payloadlen, - conn->remote.transport_params->max_udp_payload_size); + payloadlen = (size_t)ngtcp2_min_uint64( + (uint64_t)payloadlen, + conn->remote.transport_params->max_udp_payload_size); } payloadlen = - ngtcp2_min(payloadlen, conn->local.settings.max_tx_udp_payload_size); + ngtcp2_min_size(payloadlen, conn->local.settings.max_tx_udp_payload_size); if (conn->local.settings.no_tx_udp_payload_size_shaping) { return payloadlen; } - return ngtcp2_min(payloadlen, dcid->max_udp_payload_size); + return ngtcp2_min_size(payloadlen, dcid->max_udp_payload_size); } static void conn_reset_congestion_state(ngtcp2_conn *conn, ngtcp2_tstamp ts); @@ -4920,15 +4922,15 @@ static ngtcp2_ssize conn_write_path_challenge(ngtcp2_conn *conn, initial_pto = conn_compute_initial_pto(conn, &conn->pktns); timeout = conn_compute_pto(conn, &conn->pktns); - timeout = ngtcp2_max(timeout, initial_pto); + timeout = ngtcp2_max_uint64(timeout, initial_pto); expiry = ts + timeout * (1ULL << pv->round); - destlen = ngtcp2_min(destlen, NGTCP2_MAX_UDP_PAYLOAD_SIZE); + destlen = ngtcp2_min_size(destlen, NGTCP2_MAX_UDP_PAYLOAD_SIZE); if (conn->server) { if (!(pv->dcid.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) { tx_left = conn_server_tx_left(conn, &pv->dcid); - destlen = (size_t)ngtcp2_min((uint64_t)destlen, tx_left); + destlen = (size_t)ngtcp2_min_uint64((uint64_t)destlen, tx_left); if (destlen == 0) { return 0; } @@ -5039,11 +5041,11 @@ static ngtcp2_ssize conn_write_path_response(ngtcp2_conn *conn, } } - destlen = ngtcp2_min(destlen, NGTCP2_MAX_UDP_PAYLOAD_SIZE); + destlen = ngtcp2_min_size(destlen, NGTCP2_MAX_UDP_PAYLOAD_SIZE); if (conn->server && !(dcid->flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) { tx_left = conn_server_tx_left(conn, dcid); - destlen = (size_t)ngtcp2_min((uint64_t)destlen, tx_left); + destlen = (size_t)ngtcp2_min_uint64((uint64_t)destlen, tx_left); if (destlen == 0) { return 0; } @@ -5351,7 +5353,7 @@ static int conn_recv_ack(ngtcp2_conn *conn, ngtcp2_pktns *pktns, ngtcp2_ack *fr, (conn->server || (conn->flags & NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED))) { /* Reset PTO count but no less than 2 to avoid frequent probe packet transmission. */ - cstat->pto_count = ngtcp2_min(cstat->pto_count, 2); + cstat->pto_count = ngtcp2_min_size(cstat->pto_count, 2); } ngtcp2_conn_set_loss_detection_timer(conn, ts); @@ -5467,7 +5469,7 @@ static int conn_recv_max_stream_data(ngtcp2_conn *conn, * conn_recv_max_data processes received MAX_DATA frame |fr|. */ static void conn_recv_max_data(ngtcp2_conn *conn, const ngtcp2_max_data *fr) { - conn->tx.max_offset = ngtcp2_max(conn->tx.max_offset, fr->max_data); + conn->tx.max_offset = ngtcp2_max_uint64(conn->tx.max_offset, fr->max_data); } /* @@ -5735,7 +5737,7 @@ static int conn_recv_connection_close(ngtcp2_conn *conn, } } - ccerr->reasonlen = ngtcp2_min(fr->reasonlen, NGTCP2_CCERR_MAX_REASONLEN); + ccerr->reasonlen = ngtcp2_min_size(fr->reasonlen, NGTCP2_CCERR_MAX_REASONLEN); ngtcp2_cpymem((uint8_t *)ccerr->reason, fr->reason, ccerr->reasonlen); return 0; @@ -6907,7 +6909,8 @@ static int conn_recv_crypto(ngtcp2_conn *conn, return 0; } - crypto->rx.last_offset = ngtcp2_max(crypto->rx.last_offset, fr_end_offset); + crypto->rx.last_offset = + ngtcp2_max_uint64(crypto->rx.last_offset, fr_end_offset); /* TODO Before dispatching incoming data to TLS stack, make sure that previous data in previous encryption level has been @@ -7106,7 +7109,8 @@ static int conn_recv_stream(ngtcp2_conn *conn, const ngtcp2_stream *fr) { return NGTCP2_ERR_FINAL_SIZE; } - strm->rx.last_offset = ngtcp2_max(strm->rx.last_offset, fr_end_offset); + strm->rx.last_offset = + ngtcp2_max_uint64(strm->rx.last_offset, fr_end_offset); if (fr_end_offset <= rx_offset) { return 0; @@ -7582,7 +7586,7 @@ static int conn_recv_max_streams(ngtcp2_conn *conn, return NGTCP2_ERR_FRAME_ENCODING; } - n = ngtcp2_min(fr->max_streams, NGTCP2_MAX_STREAMS); + n = ngtcp2_min_uint64(fr->max_streams, NGTCP2_MAX_STREAMS); if (fr->type == NGTCP2_FRAME_MAX_STREAMS_BIDI) { if (conn->local.bidi.max_streams < n) { @@ -10922,7 +10926,7 @@ ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) { } if (conn->pmtud) { - res = ngtcp2_min(res, conn->pmtud->expiry); + res = ngtcp2_min_uint64(res, conn->pmtud->expiry); } if (!ngtcp2_pq_empty(&conn->scid.used)) { @@ -10987,7 +10991,7 @@ ngtcp2_tstamp ngtcp2_conn_get_expiry(ngtcp2_conn *conn) { res = ngtcp2_min_uint64(res, conn_keep_alive_expiry(conn)); res = ngtcp2_min_uint64(res, conn_handshake_expiry(conn)); res = ngtcp2_min_uint64(res, ngtcp2_conn_get_idle_expiry(conn)); - return ngtcp2_min(res, conn->tx.pacing.next_ts); + return ngtcp2_min_uint64(res, conn->tx.pacing.next_ts); } int ngtcp2_conn_handle_expiry(ngtcp2_conn *conn, ngtcp2_tstamp ts) { @@ -11085,7 +11089,7 @@ ngtcp2_tstamp ngtcp2_conn_lost_pkt_expiry(ngtcp2_conn *conn) { ts = ngtcp2_rtb_lost_pkt_ts(&conn->in_pktns->rtb); if (ts != UINT64_MAX) { ts += conn_compute_pto(conn, conn->in_pktns); - res = ngtcp2_min(res, ts); + res = ngtcp2_min_uint64(res, ts); } } @@ -11093,14 +11097,14 @@ ngtcp2_tstamp ngtcp2_conn_lost_pkt_expiry(ngtcp2_conn *conn) { ts = ngtcp2_rtb_lost_pkt_ts(&conn->hs_pktns->rtb); if (ts != UINT64_MAX) { ts += conn_compute_pto(conn, conn->hs_pktns); - res = ngtcp2_min(res, ts); + res = ngtcp2_min_uint64(res, ts); } } ts = ngtcp2_rtb_lost_pkt_ts(&conn->pktns.rtb); if (ts != UINT64_MAX) { ts += conn_compute_pto(conn, &conn->pktns); - res = ngtcp2_min(res, ts); + res = ngtcp2_min_uint64(res, ts); } return res; @@ -11478,14 +11482,14 @@ int ngtcp2_conn_set_0rtt_remote_transport_params( p->initial_max_data = params->initial_max_data; /* we might hit garbage, then set the sane default. */ p->active_connection_id_limit = - ngtcp2_max(NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT, - params->active_connection_id_limit); + ngtcp2_max_uint64(NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT, + params->active_connection_id_limit); p->max_datagram_frame_size = params->max_datagram_frame_size; /* we might hit garbage, then set the sane default. */ if (params->max_udp_payload_size) { - p->max_udp_payload_size = - ngtcp2_max(NGTCP2_MAX_UDP_PAYLOAD_SIZE, params->max_udp_payload_size); + p->max_udp_payload_size = ngtcp2_max_uint64(NGTCP2_MAX_UDP_PAYLOAD_SIZE, + params->max_udp_payload_size); } /* These parameters are treated specially. If server accepts early @@ -11890,7 +11894,7 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path, return 0; } - origlen = (size_t)ngtcp2_min((uint64_t)origlen, server_tx_left); + origlen = (size_t)ngtcp2_min_uint64((uint64_t)origlen, server_tx_left); } return conn_write_handshake_ack_pkts(conn, pi, dest, origlen, ts); @@ -11904,13 +11908,13 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path, ngtcp2_log_info( &conn->log, NGTCP2_LOG_EVENT_LDC, "loss detection timer canceled due to amplification limit"); - cstat->loss_detection_timer = UINT64_MAX; + ngtcp2_conn_cancel_loss_detection_timer(conn); } return 0; } - destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left); + destlen = (size_t)ngtcp2_min_uint64((uint64_t)destlen, server_tx_left); } if (conn->in_pktns) { @@ -11957,7 +11961,7 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path, return 0; } - origlen = (size_t)ngtcp2_min((uint64_t)origlen, server_tx_left); + origlen = (size_t)ngtcp2_min_uint64((uint64_t)origlen, server_tx_left); } return conn_write_ack_pkt(conn, pi, dest, origlen, NGTCP2_PKT_1RTT, ts); @@ -12049,15 +12053,15 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path, if (conn->server && !(conn->dcid.current.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) { server_tx_left = conn_server_tx_left(conn, &conn->dcid.current); - origlen = (size_t)ngtcp2_min((uint64_t)origlen, server_tx_left); - destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left); + origlen = (size_t)ngtcp2_min_uint64((uint64_t)origlen, server_tx_left); + destlen = (size_t)ngtcp2_min_uint64((uint64_t)destlen, server_tx_left); if (server_tx_left == 0 && conn->cstat.loss_detection_timer != UINT64_MAX) { ngtcp2_log_info( &conn->log, NGTCP2_LOG_EVENT_LDC, "loss detection timer canceled due to amplification limit"); - conn->cstat.loss_detection_timer = UINT64_MAX; + ngtcp2_conn_cancel_loss_detection_timer(conn); } } } @@ -12245,7 +12249,7 @@ ngtcp2_ssize ngtcp2_conn_write_connection_close_pkt( if (conn->server) { server_tx_left = conn_server_tx_left(conn, &conn->dcid.current); - destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left); + destlen = (size_t)ngtcp2_min_uint64((uint64_t)destlen, server_tx_left); } if (conn->state == NGTCP2_CS_POST_HANDSHAKE || @@ -12307,7 +12311,7 @@ ngtcp2_ssize ngtcp2_conn_write_application_close_pkt( if (conn->server) { server_tx_left = conn_server_tx_left(conn, &conn->dcid.current); - destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left); + destlen = (size_t)ngtcp2_min_uint64((uint64_t)destlen, server_tx_left); } if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED)) { @@ -12793,8 +12797,8 @@ int ngtcp2_conn_update_rtt(ngtcp2_conn *conn, ngtcp2_duration rtt, if (conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) { assert(conn->remote.transport_params); - ack_delay = - ngtcp2_min(ack_delay, conn->remote.transport_params->max_ack_delay); + ack_delay = ngtcp2_min_uint64( + ack_delay, conn->remote.transport_params->max_ack_delay); } else if (ack_delay > 0 && rtt >= cstat->min_rtt && rtt < cstat->min_rtt + ack_delay) { /* Ignore RTT sample if adjusting ack_delay causes the sample @@ -12809,7 +12813,7 @@ int ngtcp2_conn_update_rtt(ngtcp2_conn *conn, ngtcp2_duration rtt, } cstat->latest_rtt = rtt; - cstat->min_rtt = ngtcp2_min(cstat->min_rtt, rtt); + cstat->min_rtt = ngtcp2_min_uint64(cstat->min_rtt, rtt); if (rtt >= cstat->min_rtt + ack_delay) { rtt -= ack_delay; @@ -12944,8 +12948,7 @@ void ngtcp2_conn_set_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts) { if (cstat->loss_detection_timer != UINT64_MAX) { ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_LDC, "loss detection timer canceled"); - cstat->loss_detection_timer = UINT64_MAX; - cstat->pto_count = 0; + ngtcp2_conn_cancel_loss_detection_timer(conn); } return; } @@ -12960,6 +12963,13 @@ void ngtcp2_conn_set_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts) { cstat->loss_detection_timer, timeout / NGTCP2_MILLISECONDS); } +void ngtcp2_conn_cancel_loss_detection_timer(ngtcp2_conn *conn) { + ngtcp2_conn_stat *cstat = &conn->cstat; + + cstat->loss_detection_timer = UINT64_MAX; + cstat->pto_count = 0; +} + int ngtcp2_conn_on_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts) { ngtcp2_conn_stat *cstat = &conn->cstat; int rv; @@ -12971,8 +12981,7 @@ int ngtcp2_conn_on_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts) { switch (conn->state) { case NGTCP2_CS_CLOSING: case NGTCP2_CS_DRAINING: - cstat->loss_detection_timer = UINT64_MAX; - cstat->pto_count = 0; + ngtcp2_conn_cancel_loss_detection_timer(conn); return 0; default: break; @@ -13047,7 +13056,8 @@ static int conn_buffer_crypto_data(ngtcp2_conn *conn, const uint8_t **pdata, } if (!*pbufchain) { - rv = ngtcp2_buf_chain_new(pbufchain, ngtcp2_max(1024, datalen), conn->mem); + rv = ngtcp2_buf_chain_new(pbufchain, ngtcp2_max_size(1024, datalen), + conn->mem); if (rv != 0) { return rv; } @@ -13463,7 +13473,7 @@ ngtcp2_tstamp ngtcp2_conn_get_idle_expiry(ngtcp2_conn *conn) { ? &conn->pktns : conn->hs_pktns); - idle_timeout = ngtcp2_max(idle_timeout, trpto); + idle_timeout = ngtcp2_max_uint64(idle_timeout, trpto); if (conn->idle_ts >= UINT64_MAX - idle_timeout) { return UINT64_MAX; diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h index 1172816..e7d16a1 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h @@ -816,6 +816,8 @@ int ngtcp2_conn_update_rtt(ngtcp2_conn *conn, ngtcp2_duration rtt, void ngtcp2_conn_set_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts); +void ngtcp2_conn_cancel_loss_detection_timer(ngtcp2_conn *conn); + int ngtcp2_conn_on_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts); /* diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h index 1a93867..573efd6 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h @@ -105,8 +105,9 @@ typedef struct ngtcp2_conn_stat { uint64_t bytes_in_flight; /** * :member:`max_tx_udp_payload_size` is the maximum size of UDP - * datagram payload that this endpoint transmits. It is used by - * congestion controller to compute congestion window. + * datagram payload that this endpoint transmits to the current + * path. It is used by congestion controller to compute congestion + * window. */ size_t max_tx_udp_payload_size; /** diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c index 41c2a6a..25f9341 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c @@ -68,14 +68,11 @@ int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc, size_t datacnt, ngtcp2_objalloc *objalloc, const ngtcp2_mem *mem) { - size_t need, avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_stream); - - if (datacnt > 1) { - need = sizeof(ngtcp2_vec) * (datacnt - 1); - - if (need > avail) { - return ngtcp2_frame_chain_extralen_new(pfrc, need - avail, mem); - } + if (datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) { + return ngtcp2_frame_chain_extralen_new(pfrc, + sizeof(ngtcp2_vec) * (datacnt - 1) - + NGTCP2_FRAME_CHAIN_STREAM_AVAIL, + mem); } return ngtcp2_frame_chain_objalloc_new(pfrc, objalloc); @@ -139,9 +136,7 @@ void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc, switch (frc->fr.type) { case NGTCP2_FRAME_CRYPTO: case NGTCP2_FRAME_STREAM: - if (frc->fr.stream.datacnt && - sizeof(ngtcp2_vec) * (frc->fr.stream.datacnt - 1) > - sizeof(ngtcp2_frame) - sizeof(ngtcp2_stream)) { + if (frc->fr.stream.datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) { ngtcp2_frame_chain_del(frc, mem); return; diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h index 656fa5b..07dae55 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h @@ -121,12 +121,29 @@ int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc, int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen, const ngtcp2_mem *mem); +/* NGTCP2_FRAME_CHAIN_STREAM_AVAIL is the number of additional bytes + available after ngtcp2_stream when it is embedded in + ngtcp2_frame. */ +#define NGTCP2_FRAME_CHAIN_STREAM_AVAIL \ + (sizeof(ngtcp2_frame) - sizeof(ngtcp2_stream)) + +/* NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES is the number of datacnt + that changes allocation method. If datacnt is more than this + value, ngtcp2_frame_chain is allocated without ngtcp2_objalloc. + Otherwise, it is allocated using ngtcp2_objalloc. */ +#define NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES \ + (NGTCP2_FRAME_CHAIN_STREAM_AVAIL / sizeof(ngtcp2_vec) + 1) + /* * ngtcp2_frame_chain_stream_datacnt_objalloc_new works like * ngtcp2_frame_chain_new, but it allocates enough data to store * additional |datacnt| - 1 ngtcp2_vec object after ngtcp2_stream - * object. If no additional space is required, - * ngtcp2_frame_chain_objalloc_new is called internally. + * object. If no additional space is required, in other words, + * |datacnt| <= NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES, + * ngtcp2_frame_chain_objalloc_new is called internally. Otherwise, + * ngtcp2_frame_chain_extralen_new is used and objalloc is not used. + * Therefore, it is important to call ngtcp2_frame_chain_objalloc_del + * without changing datacnt field. */ int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc, size_t datacnt, diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c index 0ccc048..a7284bd 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c @@ -60,8 +60,7 @@ void ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar, size_t keylen, size_t nodelen = ksl_nodelen(keylen); ngtcp2_objalloc_init(&ksl->blkalloc, - ((ksl_blklen(nodelen) + 0xfu) & ~(uintptr_t)0xfu) * 8, - mem); + (ksl_blklen(nodelen) + 0xfu) & ~(uintptr_t)0xfu, mem); ksl->head = NULL; ksl->front = ksl->back = NULL; @@ -818,6 +817,6 @@ int ngtcp2_ksl_range_compar(const ngtcp2_ksl_key *lhs, int ngtcp2_ksl_range_exclusive_compar(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) { const ngtcp2_range *a = lhs, *b = rhs; - return a->begin < b->begin && - !(ngtcp2_max(a->begin, b->begin) < ngtcp2_min(a->end, b->end)); + return a->begin < b->begin && !(ngtcp2_max_uint64(a->begin, b->begin) < + ngtcp2_min_uint64(a->end, b->end)); } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h index 7e08f15..d972bfc 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h @@ -44,7 +44,7 @@ block can contain. */ #define NGTCP2_KSL_MAX_NBLK (2 * NGTCP2_KSL_DEGR - 1) /* NGTCP2_KSL_MIN_NBLK is the minimum number of nodes which a single - block other than root must contains. */ + block other than root must contain. */ #define NGTCP2_KSL_MIN_NBLK (NGTCP2_KSL_DEGR - 1) /* diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_log.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_log.c index 93922a2..36d72ec 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_log.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_log.c @@ -296,7 +296,7 @@ static void log_fr_connection_close(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, const ngtcp2_connection_close *fr, const char *dir) { char reason[256]; - size_t reasonlen = ngtcp2_min(sizeof(reason) - 1, fr->reasonlen); + size_t reasonlen = ngtcp2_min_size(sizeof(reason) - 1, fr->reasonlen); log->log_printf(log->user_data, (NGTCP2_LOG_PKT " CONNECTION_CLOSE(0x%02" PRIx64 diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h index 8974c86..46cfebc 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h @@ -33,9 +33,6 @@ #include <ngtcp2/ngtcp2.h> -#define ngtcp2_min(A, B) ((A) < (B) ? (A) : (B)) -#define ngtcp2_max(A, B) ((A) > (B) ? (A) : (B)) - #define ngtcp2_struct_of(ptr, type, member) \ ((type *)(void *)((char *)(ptr)-offsetof(type, member))) @@ -55,11 +52,6 @@ */ #define ngtcp2_arraylen(A) (sizeof(A) / sizeof(A[0])) -/* - * ngtcp2_max variants but they are inline functions. The - * intermediate values are stored in parameters so that they are - * evaluated just once. - */ #define ngtcp2_max_def(SUFFIX, T) \ static inline T ngtcp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; } @@ -73,11 +65,6 @@ ngtcp2_max_def(uint32, uint32_t); ngtcp2_max_def(uint64, uint64_t); ngtcp2_max_def(size, size_t); -/* - * ngtcp2_min variants but they are inline functions. The - * intermediate values are stored in parameters so that they are - * evaluated just once. - */ #define ngtcp2_min_def(SUFFIX, T) \ static inline T ngtcp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c index f4ceb32..39ebd84 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c @@ -752,7 +752,7 @@ ngtcp2_ssize ngtcp2_pkt_decode_ack_frame(ngtcp2_ack *dest, } /* TODO We might not decode all ranges. It could be very large. */ - max_rangecnt = ngtcp2_min(NGTCP2_MAX_ACK_RANGES, rangecnt); + max_rangecnt = ngtcp2_min_size(NGTCP2_MAX_ACK_RANGES, rangecnt); p = payload + 1; @@ -2382,22 +2382,22 @@ size_t ngtcp2_pkt_stream_max_datalen(int64_t stream_id, uint64_t offset, if (left > 8 + 1073741823 && len > 1073741823) { #if SIZE_MAX > UINT32_MAX - len = ngtcp2_min(len, 4611686018427387903lu); + len = ngtcp2_min_uint64(len, 4611686018427387903lu); #endif /* SIZE_MAX > UINT32_MAX */ return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 8)); } if (left > 4 + 16383 && len > 16383) { - len = ngtcp2_min(len, 1073741823); + len = ngtcp2_min_uint64(len, 1073741823); return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 4)); } if (left > 2 + 63 && len > 63) { - len = ngtcp2_min(len, 16383); + len = ngtcp2_min_uint64(len, 16383); return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 2)); } - len = ngtcp2_min(len, 63); + len = ngtcp2_min_uint64(len, 63); return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 1)); } @@ -2414,22 +2414,22 @@ size_t ngtcp2_pkt_crypto_max_datalen(uint64_t offset, size_t len, size_t left) { if (left > 8 + 1073741823 && len > 1073741823) { #if SIZE_MAX > UINT32_MAX - len = ngtcp2_min(len, 4611686018427387903lu); + len = ngtcp2_min_size(len, 4611686018427387903lu); #endif /* SIZE_MAX > UINT32_MAX */ return ngtcp2_min_size(len, left - 8); } if (left > 4 + 16383 && len > 16383) { - len = ngtcp2_min(len, 1073741823); + len = ngtcp2_min_size(len, 1073741823); return ngtcp2_min_size(len, left - 4); } if (left > 2 + 63 && len > 63) { - len = ngtcp2_min(len, 16383); + len = ngtcp2_min_size(len, 16383); return ngtcp2_min_size(len, left - 2); } - len = ngtcp2_min(len, 63); + len = ngtcp2_min_size(len, 63); return ngtcp2_min_size(len, left - 1); } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c index 6010e42..c891135 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c @@ -134,7 +134,7 @@ static void pmtud_next_probe(ngtcp2_pmtud *pmtud) { void ngtcp2_pmtud_probe_success(ngtcp2_pmtud *pmtud, size_t payloadlen) { pmtud->max_udp_payload_size = - ngtcp2_max(pmtud->max_udp_payload_size, payloadlen); + ngtcp2_max_size(pmtud->max_udp_payload_size, payloadlen); assert(pmtud->mtu_idx < pmtud->probeslen); diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.c index 314e005..e4fee94 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.c @@ -143,7 +143,7 @@ int ngtcp2_pv_validation_timed_out(ngtcp2_pv *pv, ngtcp2_tstamp ts) { ent = ngtcp2_ringbuf_get(&pv->ents.rb, ngtcp2_ringbuf_len(&pv->ents.rb) - 1); t = pv->started_ts + pv->timeout; - t = ngtcp2_max(t, ent->expiry); + t = ngtcp2_max_uint64(t, ent->expiry); return t <= ts; } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_range.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_range.c index 9379496..ed07eb3 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_range.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_range.c @@ -33,8 +33,8 @@ void ngtcp2_range_init(ngtcp2_range *r, uint64_t begin, uint64_t end) { ngtcp2_range ngtcp2_range_intersect(const ngtcp2_range *a, const ngtcp2_range *b) { ngtcp2_range r = {0, 0}; - uint64_t begin = ngtcp2_max(a->begin, b->begin); - uint64_t end = ngtcp2_min(a->end, b->end); + uint64_t begin = ngtcp2_max_uint64(a->begin, b->begin); + uint64_t end = ngtcp2_min_uint64(a->end, b->end); if (begin < end) { ngtcp2_range_init(&r, begin, end); } diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.c index b8587e3..862fa8d 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.c @@ -88,7 +88,7 @@ void ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat, return; } - rs->interval = ngtcp2_max(rs->send_elapsed, rs->ack_elapsed); + rs->interval = ngtcp2_max_uint64(rs->send_elapsed, rs->ack_elapsed); rs->delivered = rst->delivered - rs->prior_delivered; rs->lost = rst->lost - rs->prior_lost; diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c index 89a0cb5..fc79287 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c @@ -579,9 +579,11 @@ static int rtb_process_acked_pkt(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent, conn->pmtud->tx_pkt_num <= ent->hd.pkt_num) { ngtcp2_pmtud_probe_success(conn->pmtud, ent->pktlen); - conn->dcid.current.max_udp_payload_size = - conn->cstat.max_tx_udp_payload_size = - ngtcp2_max(conn->dcid.current.max_udp_payload_size, ent->pktlen); + if (conn->dcid.current.max_udp_payload_size < ent->pktlen) { + conn->dcid.current.max_udp_payload_size = ent->pktlen; + conn->cstat.max_tx_udp_payload_size = + ngtcp2_conn_get_path_max_tx_udp_payload_size(conn); + } if (ngtcp2_pmtud_finished(conn->pmtud)) { ngtcp2_conn_stop_pmtud(conn); @@ -985,8 +987,8 @@ static int rtb_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat, static ngtcp2_duration compute_pkt_loss_delay(const ngtcp2_conn_stat *cstat) { /* 9/8 is kTimeThreshold */ ngtcp2_duration loss_delay = - ngtcp2_max(cstat->latest_rtt, cstat->smoothed_rtt) * 9 / 8; - return ngtcp2_max(loss_delay, NGTCP2_GRANULARITY); + ngtcp2_max_uint64(cstat->latest_rtt, cstat->smoothed_rtt) * 9 / 8; + return ngtcp2_max_uint64(loss_delay, NGTCP2_GRANULARITY); } /* @@ -1024,8 +1026,8 @@ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost, uint64_t bytes_lost = 0; ngtcp2_duration max_ack_delay; - pkt_thres = ngtcp2_max(pkt_thres, NGTCP2_PKT_THRESHOLD); - pkt_thres = ngtcp2_min(pkt_thres, 256); + pkt_thres = ngtcp2_max_uint64(pkt_thres, NGTCP2_PKT_THRESHOLD); + pkt_thres = ngtcp2_min_uint64(pkt_thres, 256); cstat->loss_time[rtb->pktns_id] = UINT64_MAX; loss_delay = compute_pkt_loss_delay(cstat); @@ -1053,8 +1055,8 @@ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost, max_ack_delay) * NGTCP2_PERSISTENT_CONGESTION_THRESHOLD; - start_ts = ngtcp2_max(rtb->persistent_congestion_start_ts, - cstat->first_rtt_sample_ts); + start_ts = ngtcp2_max_uint64(rtb->persistent_congestion_start_ts, + cstat->first_rtt_sample_ts); for (; !ngtcp2_ksl_it_end(&it);) { ent = ngtcp2_ksl_it_get(&it); diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c index c00e86f..15b3827 100644 --- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c +++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c @@ -367,7 +367,7 @@ static int strm_streamfrq_unacked_pop(ngtcp2_strm *strm, int ngtcp2_strm_streamfrq_pop(ngtcp2_strm *strm, ngtcp2_frame_chain **pfrc, size_t left) { ngtcp2_stream *fr, *nfr; - ngtcp2_frame_chain *frc, *nfrc; + ngtcp2_frame_chain *frc, *nfrc, *sfrc; int rv; size_t nmerged; uint64_t datalen; @@ -491,7 +491,9 @@ int ngtcp2_strm_streamfrq_pop(ngtcp2_strm *strm, ngtcp2_frame_chain **pfrc, break; } - nmerged = ngtcp2_vec_merge(a, &acnt, nfr->data, &nfr->datacnt, left, + bcnt = nfr->datacnt; + + nmerged = ngtcp2_vec_merge(a, &acnt, nfr->data, &bcnt, left, NGTCP2_MAX_STREAM_DATACNT); if (nmerged == 0) { rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc); @@ -507,19 +509,46 @@ int ngtcp2_strm_streamfrq_pop(ngtcp2_strm *strm, ngtcp2_frame_chain **pfrc, datalen += nmerged; left -= nmerged; - if (nfr->datacnt == 0) { + if (bcnt == 0) { fr->fin = nfr->fin; ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem); continue; } - nfr->offset += nmerged; + if (nfr->datacnt <= NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES || + bcnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) { + nfr->offset += nmerged; + nfr->datacnt = bcnt; + + rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc); + if (rv != 0) { + ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem); + ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem); + return rv; + } + } else { + rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new( + &sfrc, bcnt, strm->frc_objalloc, strm->mem); + if (rv != 0) { + ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem); + ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem); + return rv; + } + + sfrc->fr.stream = nfrc->fr.stream; + sfrc->fr.stream.offset += nmerged; + sfrc->fr.stream.datacnt = bcnt; + ngtcp2_vec_copy(sfrc->fr.stream.data, nfrc->fr.stream.data, bcnt); - rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc); - if (rv != 0) { ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem); - ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem); - return rv; + + rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &sfrc->fr.stream.offset, + sfrc); + if (rv != 0) { + ngtcp2_frame_chain_objalloc_del(sfrc, strm->frc_objalloc, strm->mem); + ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem); + return rv; + } } break; diff --git a/src/contrib/libngtcp2/ngtcp2/version.h b/src/contrib/libngtcp2/ngtcp2/version.h index 9eb076d..85ef77b 100644 --- a/src/contrib/libngtcp2/ngtcp2/version.h +++ b/src/contrib/libngtcp2/ngtcp2/version.h @@ -36,7 +36,7 @@ * * Version number of the ngtcp2 library release. */ -#define NGTCP2_VERSION "1.5.0" +#define NGTCP2_VERSION "1.6.0" /** * @macro @@ -46,6 +46,6 @@ * number, 8 bits for minor and 8 bits for patch. Version 1.2.3 * becomes 0x010203. */ -#define NGTCP2_VERSION_NUM 0x010500 +#define NGTCP2_VERSION_NUM 0x010600 #endif /* VERSION_H */ diff --git a/src/knot/events/handlers/refresh.c b/src/knot/events/handlers/refresh.c index 83fb376..1a23f42 100644 --- a/src/knot/events/handlers/refresh.c +++ b/src/knot/events/handlers/refresh.c @@ -16,6 +16,7 @@ #include <assert.h> #include <stdint.h> +#include <urcu.h> #include "contrib/mempattern.h" #include "libdnssec/random.h" @@ -652,8 +653,12 @@ static int ixfr_finalize(struct refresh_data *data) if (dnssec_enable) { ret = knot_dnssec_sign_update(&up, data->conf); } else if (digest_alg != ZONE_DIGEST_NONE) { - assert(zone_update_to(&up) != NULL); - ret = zone_update_add_digest(&up, digest_alg, false); + if (zone_update_to(&up) == NULL) { + ret = zone_update_increment_soa(&up, data->conf); + } + if (ret == KNOT_EOK) { + ret = zone_update_add_digest(&up, digest_alg, false); + } } if (ret != KNOT_EOK) { zone_update_clear(&up); @@ -1332,16 +1337,22 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master, try_refresh_ctx_t *trctx = ctx; - knot_rrset_t soa = { 0 }; + knot_rrset_t *soa = NULL; if (zone->contents) { - soa = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); + rcu_read_lock(); + knot_rrset_t tmp = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); + soa = knot_rrset_copy(&tmp, NULL); + rcu_read_unlock(); + if (soa == NULL) { + return KNOT_ENOMEM; + } } struct refresh_data data = { .zone = zone, .conf = conf, .remote = master, - .soa = zone->contents && !trctx->force_axfr ? &soa : NULL, + .soa = zone->contents && !trctx->force_axfr ? soa : NULL, .max_zone_size = max_zone_size(conf, zone->name), .edns = query_edns_data_init(conf, master, QUERY_EDNS_OPT_EXPIRE), .expire_timer = EXPIRE_TIMER_INVALID, @@ -1357,6 +1368,7 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master, knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); if (pkt == NULL) { knot_requestor_clear(&requestor); + knot_rrset_free(soa, NULL); return KNOT_ENOMEM; } @@ -1365,6 +1377,7 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master, &data.edns, flags); if (req == NULL) { knot_requestor_clear(&requestor); + knot_rrset_free(soa, NULL); return KNOT_ENOMEM; } @@ -1388,6 +1401,7 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master, } knot_request_free(req, NULL); knot_requestor_clear(&requestor); + knot_rrset_free(soa, NULL); if (ret == KNOT_EOK) { trctx->send_notify = trctx->send_notify || (data.updated && !master->block_notify_after_xfr); diff --git a/src/knot/journal/journal_basic.c b/src/knot/journal/journal_basic.c index 947eeb8..da905ce 100644 --- a/src/knot/journal/journal_basic.c +++ b/src/knot/journal/journal_basic.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,6 +36,11 @@ MDB_val journal_make_chunk_key(const knot_dname_t *apex, uint32_t ch_from, bool } } +bool journal_correct_prefix(MDB_val *prefix, MDB_val *found_key) +{ + return knot_lmdb_is_prefix_of2(prefix, found_key, sizeof(uint32_t) /* chunk_id */); +} + MDB_val journal_zone_prefix(const knot_dname_t *zone) { return knot_lmdb_make_key("NI", zone, (uint32_t)0); @@ -69,8 +74,8 @@ uint64_t journal_ch_timestamp(const MDB_val *chunk) bool journal_serial_to(knot_lmdb_txn_t *txn, bool zij, uint32_t serial, const knot_dname_t *zone, uint32_t *serial_to) { - MDB_val key = journal_changeset_id_to_key(zij, serial, zone); - bool found = knot_lmdb_find_prefix(txn, &key); + MDB_val key = journal_make_chunk_key(zone, serial, zij, 0); + bool found = knot_lmdb_find(txn, &key, KNOT_LMDB_EXACT); if (found && serial_to != NULL) { *serial_to = journal_next_serial(&txn->cur_val); } diff --git a/src/knot/journal/journal_basic.h b/src/knot/journal/journal_basic.h index cd7bc0e..4c8f748 100644 --- a/src/knot/journal/journal_basic.h +++ b/src/knot/journal/journal_basic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -62,6 +62,16 @@ MDB_val journal_changeset_id_to_key(bool zone_in_journal, uint32_t serial, const MDB_val journal_make_chunk_key(const knot_dname_t *apex, uint32_t ch_from, bool zij, uint32_t chunk_id); /*! + * \brief Check that found LMDB key belongs to a changest chunk of given prefix. + * + * \param prefix Prefix from journal_changeset_id_to_key(). + * \param found_key Found database record key. + * + * \return All OK (hopefully). + */ +bool journal_correct_prefix(MDB_val *prefix, MDB_val *found_key); + +/*! * \brief Return a key prefix to operate with all zone-related records. */ MDB_val journal_zone_prefix(const knot_dname_t *zone); diff --git a/src/knot/journal/journal_read.c b/src/knot/journal/journal_read.c index 0aa5f1a..c066b52 100644 --- a/src/knot/journal/journal_read.c +++ b/src/knot/journal/journal_read.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,6 +48,16 @@ static void update_ctx_wire(journal_read_t *ctx) wire_ctx_skip(&ctx->wire, JOURNAL_HEADER_SIZE); } +static bool go_correct_prefix(journal_read_t *ctx) +{ + while (!journal_correct_prefix(&ctx->key_prefix, &ctx->txn.cur_key)) { + if (!knot_lmdb_next(&ctx->txn) || !knot_lmdb_is_prefix_of(&ctx->key_prefix, &ctx->txn.cur_key)) { + return false; + } + } + return true; +} + static bool go_next_changeset(journal_read_t *ctx, bool go_zone, const knot_dname_t *zone) { free(ctx->key_prefix.mv_data); @@ -55,6 +65,9 @@ static bool go_next_changeset(journal_read_t *ctx, bool go_zone, const knot_dnam if (!knot_lmdb_find_prefix(&ctx->txn, &ctx->key_prefix)) { return false; } + if (!go_correct_prefix(ctx)) { + return false; + } if (!go_zone && ctx->next == journal_next_serial(&ctx->txn.cur_val)) { ctx->txn.ret = KNOT_ELOOP; return false; @@ -117,7 +130,7 @@ static bool make_data_available(journal_read_t *ctx) if (!knot_lmdb_next(&ctx->txn)) { return false; } - if (!knot_lmdb_is_prefix_of(&ctx->key_prefix, &ctx->txn.cur_key)) { + if (!go_correct_prefix(ctx)) { return false; } if (ctx->next != journal_next_serial(&ctx->txn.cur_val)) { diff --git a/src/knot/journal/journal_write.c b/src/knot/journal/journal_write.c index 1cd450a..55f2048 100644 --- a/src/knot/journal/journal_write.c +++ b/src/knot/journal/journal_write.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,6 +92,9 @@ static bool delete_one(knot_lmdb_txn_t *txn, bool del_zij, uint32_t del_serial, *freed = 0; MDB_val prefix = journal_changeset_id_to_key(del_zij, del_serial, zone); knot_lmdb_foreach(txn, &prefix) { + if (!journal_correct_prefix(&prefix, &txn->cur_key)) { + continue; + } *freed += txn->cur_val.mv_size; *next_serial = journal_next_serial(&txn->cur_val); knot_lmdb_del_cur(txn); diff --git a/src/knot/journal/knot_lmdb.c b/src/knot/journal/knot_lmdb.c index ee5fbed..c63a3c4 100644 --- a/src/knot/journal/knot_lmdb.c +++ b/src/knot/journal/knot_lmdb.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -453,6 +453,12 @@ bool knot_lmdb_is_prefix_of(const MDB_val *prefix, const MDB_val *of) memcmp(prefix->mv_data, of->mv_data, prefix->mv_size) == 0; } +bool knot_lmdb_is_prefix_of2(const MDB_val *prefix, const MDB_val *of, size_t expected_rest) +{ + return prefix->mv_size + expected_rest == of->mv_size && + memcmp(prefix->mv_data, of->mv_data, prefix->mv_size) == 0; +} + void knot_lmdb_del_cur(knot_lmdb_txn_t *txn) { if (txn_semcheck(txn)) { diff --git a/src/knot/journal/knot_lmdb.h b/src/knot/journal/knot_lmdb.h index f08ea2f..762fbb4 100644 --- a/src/knot/journal/knot_lmdb.h +++ b/src/knot/journal/knot_lmdb.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -248,6 +248,17 @@ bool knot_lmdb_next(knot_lmdb_txn_t *txn); bool knot_lmdb_is_prefix_of(const MDB_val *prefix, const MDB_val *of); /*! + * \brief Check if DB key is prefix of another, with given extra number of bytes. + * + * \param prefix DB key prefix. + * \param of Another DB key. + * \param expected_rest Extra length of "of". + * + * \return True iff 'prefix'+expected_rest == 'of'. + */ +bool knot_lmdb_is_prefix_of2(const MDB_val *prefix, const MDB_val *of, size_t expected_rest); + +/*! * \brief Find leftmost key in DB matching given prefix. * * \param txn DB transaction. diff --git a/src/knot/zone/zone.c b/src/knot/zone/zone.c index 6bdfb1d..7c84202 100644 --- a/src/knot/zone/zone.c +++ b/src/knot/zone/zone.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,12 +94,14 @@ static int flush_journal(conf_t *conf, zone_t *zone, bool allow_empty_zone, bool } /* Check for updated zone. */ + rcu_read_lock(); zone_contents_t *contents = zone->contents; uint32_t serial_to = zone_contents_serial(contents); if (!force && !user_flush && zone->zonefile.exists && zone->zonefile.serial == serial_to && !zone->zonefile.retransfer && !zone->zonefile.resigned) { ret = KNOT_EOK; /* No differences. */ + rcu_read_unlock(); goto flush_journal_replan; } @@ -107,6 +109,7 @@ static int flush_journal(conf_t *conf, zone_t *zone, bool allow_empty_zone, bool /* Synchronize journal. */ ret = zonefile_write(zonefile, contents); + rcu_read_unlock(); if (ret != KNOT_EOK) { log_zone_warning(zone->name, "failed to update zone file (%s)", knot_strerror(ret)); @@ -285,6 +288,7 @@ int selective_zone_purge(conf_t *conf, zone_t *zone, purge_flag_t params) zone->timers = (zone_timers_t) { .catalog_member = zone->timers.catalog_member }; + zone_timers_sanitize(conf, zone); zone->zonefile.bootstrap_cnt = 0; ret = zone_timers_sweep(&zone->server->timerdb, (sweep_cb)knot_dname_cmp, zone->name); diff --git a/src/libdnssec/version.h b/src/libdnssec/version.h index ad691c7..c8edcd0 100644 --- a/src/libdnssec/version.h +++ b/src/libdnssec/version.h @@ -18,7 +18,7 @@ #define DNSSEC_VERSION_MAJOR 3 #define DNSSEC_VERSION_MINOR 3 -#define DNSSEC_VERSION_PATCH 0x06 +#define DNSSEC_VERSION_PATCH 0x07 #define DNSSEC_VERSION_HEX ((DNSSEC_VERSION_MAJOR << 16) | \ (DNSSEC_VERSION_MINOR << 8) | \ diff --git a/src/libknot/version.h b/src/libknot/version.h index 66b1793..cca89f7 100644 --- a/src/libknot/version.h +++ b/src/libknot/version.h @@ -18,7 +18,7 @@ #define KNOT_VERSION_MAJOR 3 #define KNOT_VERSION_MINOR 3 -#define KNOT_VERSION_PATCH 0x06 +#define KNOT_VERSION_PATCH 0x07 #define KNOT_VERSION_HEX ((KNOT_VERSION_MAJOR << 16) | \ (KNOT_VERSION_MINOR << 8) | \ diff --git a/src/libzscanner/version.h b/src/libzscanner/version.h index 12d0d9e..ed64fa2 100644 --- a/src/libzscanner/version.h +++ b/src/libzscanner/version.h @@ -18,7 +18,7 @@ #define ZSCANNER_VERSION_MAJOR 3 #define ZSCANNER_VERSION_MINOR 3 -#define ZSCANNER_VERSION_PATCH 0x06 +#define ZSCANNER_VERSION_PATCH 0x07 #define ZSCANNER_VERSION_HEX ((ZSCANNER_VERSION_MAJOR << 16) | \ (ZSCANNER_VERSION_MINOR << 8) | \ |