summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-14 16:17:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-14 16:17:58 +0000
commita04a7c41c9327144cc11ffd030c0efc2a4f85534 (patch)
tree812fe9d19c0c90324f80b838b1b1e2976a416999 /src
parentAdding upstream version 3.3.5. (diff)
downloadknot-a04a7c41c9327144cc11ffd030c0efc2a4f85534.tar.xz
knot-a04a7c41c9327144cc11ffd030c0efc2a4f85534.zip
Adding upstream version 3.3.6.upstream/3.3.6
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in57
-rw-r--r--src/contrib/Makefile.inc6
-rw-r--r--src/contrib/conn_pool.c6
-rw-r--r--src/contrib/json.c4
-rw-r--r--src/contrib/libngtcp2/ngtcp2/crypto/shared.c33
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c34
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h15
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c40
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c591
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h31
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c66
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c819
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h44
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h36
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c18
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.h5
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c43
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.h9
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.c43
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.h28
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pq.c2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h5
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c8
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c9
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c91
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h73
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h3
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c886
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.h (renamed from src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.h)53
-rw-r--r--src/contrib/libngtcp2/ngtcp2/ngtcp2.h62
-rw-r--r--src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/version.h4
-rw-r--r--src/knot/conf/base.c228
-rw-r--r--src/knot/conf/base.h13
-rw-r--r--src/knot/conf/conf.c4
-rw-r--r--src/knot/conf/conf.h15
-rw-r--r--src/knot/conf/confio.h16
-rw-r--r--src/knot/conf/schema.c10
-rw-r--r--src/knot/conf/schema.h2
-rw-r--r--src/knot/conf/tools.c51
-rw-r--r--src/knot/ctl/commands.c33
-rw-r--r--src/knot/dnssec/context.c10
-rw-r--r--src/knot/dnssec/ds_query.c16
-rw-r--r--src/knot/dnssec/kasp/policy.h4
-rw-r--r--src/knot/dnssec/zone-events.c14
-rw-r--r--src/knot/dnssec/zone-keys.c6
-rw-r--r--src/knot/events/handlers/dnskey_sync.c14
-rw-r--r--src/knot/events/handlers/ds_push.c16
-rw-r--r--src/knot/events/handlers/notify.c28
-rw-r--r--src/knot/events/handlers/refresh.c16
-rw-r--r--src/knot/events/handlers/update.c6
-rw-r--r--src/knot/modules/authsignal/authsignal.rst1
-rw-r--r--src/knot/modules/dnstap/dnstap.c74
-rw-r--r--src/knot/modules/dnstap/dnstap.rst9
-rw-r--r--src/knot/nameserver/axfr.c9
-rw-r--r--src/knot/nameserver/ixfr.c9
-rw-r--r--src/knot/nameserver/log.h18
-rw-r--r--src/knot/nameserver/notify.c6
-rw-r--r--src/knot/nameserver/xfr.h9
-rw-r--r--src/knot/server/xdp-handler.c14
-rw-r--r--src/knot/updates/zone-update.c2
-rw-r--r--src/knot/zone/backup.h3
-rw-r--r--src/knot/zone/zone.c2
-rw-r--r--src/libdnssec/version.h2
-rw-r--r--src/libknot/control/control.c12
-rw-r--r--src/libknot/control/control.h7
-rw-r--r--src/libknot/quic/quic.c28
-rw-r--r--src/libknot/version.h2
-rw-r--r--src/libknot/xdp/tcp.c2
-rw-r--r--src/libknot/yparser/ypbody.c97
-rw-r--r--src/libzscanner/version.h2
-rw-r--r--src/utils/common/params.c11
-rw-r--r--src/utils/common/quic.c12
-rw-r--r--src/utils/kdig/kdig_params.c2
-rw-r--r--src/utils/knotc/commands.c38
-rw-r--r--src/utils/knotd/main.c3
-rw-r--r--src/utils/kxdpgun/main.c58
78 files changed, 2452 insertions, 1610 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index df978b4..0018a7d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -493,8 +493,6 @@ am__libembngtcp2_la_SOURCES_DIST = \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.h \
- contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c \
- contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_err.c \
@@ -545,10 +543,14 @@ am__libembngtcp2_la_SOURCES_DIST = \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_tstamp.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h \
@@ -572,7 +574,6 @@ am__libembngtcp2_la_SOURCES_DIST = \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_cid.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conn.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conv.lo \
-@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_crypto.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_err.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_frame_chain.lo \
@@ -596,8 +597,10 @@ am__libembngtcp2_la_SOURCES_DIST = \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rob.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rst.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rtb.lo \
+@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_str.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_strm.lo \
+@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_unreachable.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_vec.lo \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_version.lo \
@@ -1149,7 +1152,6 @@ am__depfiles_remade = contrib/$(DEPDIR)/libcontrib_la-base32hex.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_cid.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conn.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conv.Plo \
- contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_err.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_frame_chain.Plo \
@@ -1173,8 +1175,10 @@ am__depfiles_remade = contrib/$(DEPDIR)/libcontrib_la-base32hex.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rob.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rst.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rtb.Plo \
+ contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_strm.Plo \
+ contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_vec.Plo \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_version.Plo \
@@ -1961,8 +1965,6 @@ libcontrib_la_SOURCES = \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.c \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.h \
-@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c \
-@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_err.c \
@@ -2013,10 +2015,14 @@ libcontrib_la_SOURCES = \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h \
+@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c \
+@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h \
+@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c \
+@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_tstamp.h \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c \
@EMBEDDED_LIBNGTCP2_TRUE@ contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h \
@@ -3191,9 +3197,6 @@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conn.lo: \
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conv.lo: \
contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
-contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo: \
- contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
- contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_crypto.lo: \
contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
@@ -3263,12 +3266,18 @@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rst.lo: \
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rtb.lo: \
contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
+contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo: \
+ contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
+ contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_str.lo: \
contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_strm.lo: \
contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
+contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo: \
+ contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
+ contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_unreachable.lo: \
contrib/libngtcp2/ngtcp2/lib/$(am__dirstamp) \
contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/$(am__dirstamp)
@@ -4197,7 +4206,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_cid.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conn.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conv.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_err.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_frame_chain.Plo@am__quote@ # am--include-marker
@@ -4221,8 +4229,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rob.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rst.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rtb.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_strm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_vec.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_version.Plo@am__quote@ # am--include-marker
@@ -5110,13 +5120,6 @@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conv.lo: contrib/libngtcp2/n
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conv.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.c
-contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo: contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo -MD -MP -MF contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Tpo -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Tpo contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c' object='contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_conversion.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c
-
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_crypto.lo: contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_crypto.lo -MD -MP -MF contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Tpo -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_crypto.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Tpo contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Plo
@@ -5278,6 +5281,13 @@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rtb.lo: contrib/libngtcp2/ng
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_rtb.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
+contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo: contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo -MD -MP -MF contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Tpo -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Tpo contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c' object='contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_settings.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c
+
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_str.lo: contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_str.lo -MD -MP -MF contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Tpo -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_str.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Tpo contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Plo
@@ -5292,6 +5302,13 @@ contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_strm.lo: contrib/libngtcp2/n
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_strm.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c
+contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo: contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo -MD -MP -MF contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Tpo -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Tpo contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c' object='contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_transport_params.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
+
contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_unreachable.lo: contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libembngtcp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_unreachable.lo -MD -MP -MF contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Tpo -c -o contrib/libngtcp2/ngtcp2/lib/libembngtcp2_la-ngtcp2_unreachable.lo `test -f 'contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c' || echo '$(srcdir)/'`contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Tpo contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Plo
@@ -7492,7 +7509,6 @@ distclean: distclean-recursive
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_cid.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conn.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conv.Plo
- -rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_err.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_frame_chain.Plo
@@ -7516,8 +7532,10 @@ distclean: distclean-recursive
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rob.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rst.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rtb.Plo
+ -rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_strm.Plo
+ -rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_vec.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_version.Plo
@@ -7859,7 +7877,6 @@ maintainer-clean: maintainer-clean-recursive
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_cid.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conn.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conv.Plo
- -rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_conversion.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_crypto.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_err.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_frame_chain.Plo
@@ -7883,8 +7900,10 @@ maintainer-clean: maintainer-clean-recursive
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rob.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rst.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_rtb.Plo
+ -rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_settings.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_str.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_strm.Plo
+ -rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_transport_params.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_unreachable.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_vec.Plo
-rm -f contrib/libngtcp2/ngtcp2/lib/$(DEPDIR)/libembngtcp2_la-ngtcp2_version.Plo
diff --git a/src/contrib/Makefile.inc b/src/contrib/Makefile.inc
index c316b5f..e1577d5 100644
--- a/src/contrib/Makefile.inc
+++ b/src/contrib/Makefile.inc
@@ -151,8 +151,6 @@ libembngtcp2_la_SOURCES = \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.h \
- contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c \
- contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_err.c \
@@ -203,10 +201,14 @@ libembngtcp2_la_SOURCES = \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_rst.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c \
+ contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_tstamp.h \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c \
contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h \
diff --git a/src/contrib/conn_pool.c b/src/contrib/conn_pool.c
index a344c57..6f61e09 100644
--- a/src/contrib/conn_pool.c
+++ b/src/contrib/conn_pool.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
@@ -15,6 +15,7 @@
*/
#include <assert.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -255,8 +256,9 @@ void conn_pool_close_cb_dflt(conn_pool_fd_t fd)
bool conn_pool_invalid_cb_dflt(conn_pool_fd_t fd)
{
uint8_t unused;
+ errno = 0;
int peek = recv((int)fd, &unused, 1, MSG_PEEK | MSG_DONTWAIT);
- return (peek >= 0); // closed or pending data
+ return (peek == 0 || peek > 0 || errno == ECONNRESET); // closed || pending data || reset (alternative: errno != 0 && errno != EAGAIN)
}
bool conn_pool_invalid_cb_allvalid(conn_pool_fd_t fd)
diff --git a/src/contrib/json.c b/src/contrib/json.c
index 3a35fc6..d44da87 100644
--- a/src/contrib/json.c
+++ b/src/contrib/json.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
@@ -22,7 +22,7 @@
#include "contrib/string.h"
-#define MAX_DEPTH 8
+#define MAX_DEPTH 16
enum {
BLOCK_INVALID = 0,
diff --git a/src/contrib/libngtcp2/ngtcp2/crypto/shared.c b/src/contrib/libngtcp2/ngtcp2/crypto/shared.c
index 162094a..604cb96 100644
--- a/src/contrib/libngtcp2/ngtcp2/crypto/shared.c
+++ b/src/contrib/libngtcp2/ngtcp2/crypto/shared.c
@@ -923,10 +923,11 @@ ngtcp2_ssize ngtcp2_crypto_generate_retry_token(
uint8_t *token, const uint8_t *secret, size_t secretlen, uint32_t version,
const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
const ngtcp2_cid *retry_scid, const ngtcp2_cid *odcid, ngtcp2_tstamp ts) {
- uint8_t plaintext[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
+ uint8_t
+ plaintext[/* cid len = */ 1 + NGTCP2_MAX_CIDLEN + sizeof(ngtcp2_tstamp)];
uint8_t rand_data[NGTCP2_CRYPTO_TOKEN_RAND_DATALEN];
- uint8_t key[32];
- uint8_t iv[32];
+ uint8_t key[16];
+ uint8_t iv[12];
size_t keylen;
size_t ivlen;
ngtcp2_crypto_aead aead;
@@ -962,8 +963,8 @@ ngtcp2_ssize ngtcp2_crypto_generate_retry_token(
keylen = ngtcp2_crypto_aead_keylen(&aead);
ivlen = ngtcp2_crypto_aead_noncelen(&aead);
- assert(sizeof(key) >= keylen);
- assert(sizeof(iv) >= ivlen);
+ assert(sizeof(key) == keylen);
+ assert(sizeof(iv) == ivlen);
if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
rand_data, sizeof(rand_data),
@@ -1005,8 +1006,8 @@ int ngtcp2_crypto_verify_retry_token(
const ngtcp2_cid *dcid, ngtcp2_duration timeout, ngtcp2_tstamp ts) {
uint8_t
plaintext[/* cid len = */ 1 + NGTCP2_MAX_CIDLEN + sizeof(ngtcp2_tstamp)];
- uint8_t key[32];
- uint8_t iv[32];
+ uint8_t key[16];
+ uint8_t iv[12];
size_t keylen;
size_t ivlen;
ngtcp2_crypto_aead_ctx aead_ctx;
@@ -1039,6 +1040,9 @@ int ngtcp2_crypto_verify_retry_token(
keylen = ngtcp2_crypto_aead_keylen(&aead);
ivlen = ngtcp2_crypto_aead_noncelen(&aead);
+ assert(sizeof(key) == keylen);
+ assert(sizeof(iv) == ivlen);
+
if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
retry_token_info_prefix,
@@ -1114,8 +1118,8 @@ ngtcp2_ssize ngtcp2_crypto_generate_regular_token(
ngtcp2_tstamp ts) {
uint8_t plaintext[sizeof(ngtcp2_tstamp)];
uint8_t rand_data[NGTCP2_CRYPTO_TOKEN_RAND_DATALEN];
- uint8_t key[32];
- uint8_t iv[32];
+ uint8_t key[16];
+ uint8_t iv[12];
size_t keylen;
size_t ivlen;
ngtcp2_crypto_aead aead;
@@ -1144,8 +1148,8 @@ ngtcp2_ssize ngtcp2_crypto_generate_regular_token(
keylen = ngtcp2_crypto_aead_keylen(&aead);
ivlen = ngtcp2_crypto_aead_noncelen(&aead);
- assert(sizeof(key) >= keylen);
- assert(sizeof(iv) >= ivlen);
+ assert(sizeof(key) == keylen);
+ assert(sizeof(iv) == ivlen);
if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
rand_data, sizeof(rand_data),
@@ -1186,8 +1190,8 @@ int ngtcp2_crypto_verify_regular_token(const uint8_t *token, size_t tokenlen,
ngtcp2_duration timeout,
ngtcp2_tstamp ts) {
uint8_t plaintext[sizeof(ngtcp2_tstamp)];
- uint8_t key[32];
- uint8_t iv[32];
+ uint8_t key[16];
+ uint8_t iv[12];
size_t keylen;
size_t ivlen;
ngtcp2_crypto_aead_ctx aead_ctx;
@@ -1217,6 +1221,9 @@ int ngtcp2_crypto_verify_regular_token(const uint8_t *token, size_t tokenlen,
keylen = ngtcp2_crypto_aead_keylen(&aead);
ivlen = ngtcp2_crypto_aead_noncelen(&aead);
+ assert(sizeof(key) == keylen);
+ assert(sizeof(iv) == ivlen);
+
if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
regular_token_info_prefix,
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c
index d4778d6..3ed581f 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c
@@ -60,31 +60,18 @@ static int greater(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
return *(int64_t *)lhs > *(int64_t *)rhs;
}
-int ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
- const ngtcp2_mem *mem) {
- int rv;
-
+void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
+ const ngtcp2_mem *mem) {
ngtcp2_objalloc_acktr_entry_init(&acktr->objalloc, 32, mem);
- rv = ngtcp2_ringbuf_init(&acktr->acks, 32, sizeof(ngtcp2_acktr_ack_entry),
- mem);
- if (rv != 0) {
- goto fail_acks_init;
- }
+ ngtcp2_static_ringbuf_acks_init(&acktr->acks);
ngtcp2_ksl_init(&acktr->ents, greater, sizeof(int64_t), mem);
acktr->log = log;
- acktr->mem = mem;
acktr->flags = NGTCP2_ACKTR_FLAG_NONE;
acktr->first_unacked_ts = UINT64_MAX;
acktr->rx_npkt = 0;
-
- return 0;
-
-fail_acks_init:
- ngtcp2_objalloc_free(&acktr->objalloc);
- return rv;
}
void ngtcp2_acktr_free(ngtcp2_acktr *acktr) {
@@ -105,8 +92,6 @@ void ngtcp2_acktr_free(ngtcp2_acktr *acktr) {
ngtcp2_ksl_free(&acktr->ents);
- ngtcp2_ringbuf_free(&acktr->acks);
-
ngtcp2_objalloc_free(&acktr->objalloc);
}
@@ -225,7 +210,7 @@ int ngtcp2_acktr_empty(ngtcp2_acktr *acktr) {
ngtcp2_acktr_ack_entry *ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr,
int64_t pkt_num,
int64_t largest_ack) {
- ngtcp2_acktr_ack_entry *ent = ngtcp2_ringbuf_push_front(&acktr->acks);
+ ngtcp2_acktr_ack_entry *ent = ngtcp2_ringbuf_push_front(&acktr->acks.rb);
ent->largest_ack = largest_ack;
ent->pkt_num = pkt_num;
@@ -266,8 +251,10 @@ static void acktr_on_ack(ngtcp2_acktr *acktr, ngtcp2_ringbuf *rb,
ngtcp2_ksl_it_prev(&it);
ent = ngtcp2_ksl_it_get(&it);
- if (ent->pkt_num > ack_ent->largest_ack &&
- ack_ent->largest_ack >= ent->pkt_num - (int64_t)(ent->len - 1)) {
+
+ assert(ent->pkt_num > ack_ent->largest_ack);
+
+ if (ack_ent->largest_ack >= ent->pkt_num - (int64_t)(ent->len - 1)) {
ent->len = (size_t)(ent->pkt_num - ack_ent->largest_ack);
}
}
@@ -279,7 +266,7 @@ void ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr) {
ngtcp2_acktr_ack_entry *ent;
int64_t largest_ack = fr->largest_ack, min_ack;
size_t i, j;
- ngtcp2_ringbuf *rb = &acktr->acks;
+ ngtcp2_ringbuf *rb = &acktr->acks.rb;
size_t nacks = ngtcp2_ringbuf_len(rb);
/* Assume that ngtcp2_pkt_validate_ack(fr) returns 0 */
@@ -306,8 +293,7 @@ void ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr) {
for (;;) {
if (ent->pkt_num > largest_ack) {
- ++j;
- if (j == nacks) {
+ if (++j == nacks) {
return;
}
ent = ngtcp2_ringbuf_get(rb, j);
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h
index 809fb69..0cbb490 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h
@@ -108,17 +108,18 @@ typedef struct ngtcp2_acktr_ack_entry {
expired and canceled. */
#define NGTCP2_ACKTR_FLAG_CANCEL_TIMER 0x0100u
+ngtcp2_static_ringbuf_def(acks, 32, sizeof(ngtcp2_acktr_ack_entry));
+
/*
* ngtcp2_acktr tracks received packets which we have to send ack.
*/
typedef struct ngtcp2_acktr {
ngtcp2_objalloc objalloc;
- ngtcp2_ringbuf acks;
+ ngtcp2_static_ringbuf_acks acks;
/* ents includes ngtcp2_acktr_entry sorted by decreasing order of
packet number. */
ngtcp2_ksl ents;
ngtcp2_log *log;
- const ngtcp2_mem *mem;
/* flags is bitwise OR of zero, or more of NGTCP2_ACKTR_FLAG_*. */
uint16_t flags;
/* first_unacked_ts is timestamp when ngtcp2_acktr_entry is added
@@ -131,15 +132,9 @@ typedef struct ngtcp2_acktr {
/*
* ngtcp2_acktr_init initializes |acktr|.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGTCP2_ERR_NOMEM
- * Out of memory.
*/
-int ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
- const ngtcp2_mem *mem);
+void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
+ const ngtcp2_mem *mem);
/*
* ngtcp2_acktr_free frees resources allocated for |acktr|. It frees
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
index 27c4667..ebc6f48 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
@@ -558,11 +558,12 @@ static void bbr_init_lower_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
}
static void bbr_loss_lower_bounds(ngtcp2_cc_bbr *bbr) {
- bbr->bw_lo = ngtcp2_max(bbr->bw_latest, bbr->bw_lo * NGTCP2_BBR_BETA_NUMER /
- NGTCP2_BBR_BETA_DENOM);
- bbr->inflight_lo = ngtcp2_max(bbr->inflight_latest,
- bbr->inflight_lo * NGTCP2_BBR_BETA_NUMER /
- NGTCP2_BBR_BETA_DENOM);
+ bbr->bw_lo =
+ ngtcp2_max_uint64(bbr->bw_latest, bbr->bw_lo * NGTCP2_BBR_BETA_NUMER /
+ NGTCP2_BBR_BETA_DENOM);
+ bbr->inflight_lo = ngtcp2_max_uint64(
+ bbr->inflight_latest,
+ bbr->inflight_lo * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
}
static void bbr_bound_bw_for_model(ngtcp2_cc_bbr *bbr) {
@@ -801,13 +802,13 @@ static uint64_t bbr_inflight_with_headroom(ngtcp2_cc_bbr *bbr,
return UINT64_MAX;
}
- headroom = ngtcp2_max(cstat->max_tx_udp_payload_size,
- bbr->inflight_hi * NGTCP2_BBR_HEADROOM_NUMER /
- NGTCP2_BBR_HEADROOM_DENOM);
+ headroom = ngtcp2_max_uint64(cstat->max_tx_udp_payload_size,
+ bbr->inflight_hi * NGTCP2_BBR_HEADROOM_NUMER /
+ NGTCP2_BBR_HEADROOM_DENOM);
mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
if (bbr->inflight_hi > headroom) {
- return ngtcp2_max(bbr->inflight_hi - headroom, mpcwnd);
+ return ngtcp2_max_uint64(bbr->inflight_hi - headroom, mpcwnd);
}
return mpcwnd;
@@ -818,8 +819,8 @@ static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
uint64_t growth_this_round = cstat->max_tx_udp_payload_size
<< bbr->bw_probe_up_rounds;
- bbr->bw_probe_up_rounds = ngtcp2_min(bbr->bw_probe_up_rounds + 1, 30);
- bbr->probe_up_cnt = ngtcp2_max(cstat->cwnd / growth_this_round, 1) *
+ bbr->bw_probe_up_rounds = ngtcp2_min_size(bbr->bw_probe_up_rounds + 1, 30);
+ bbr->probe_up_cnt = ngtcp2_max_uint64(cstat->cwnd / growth_this_round, 1) *
cstat->max_tx_udp_payload_size;
}
@@ -946,7 +947,7 @@ static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
bbr->bw_probe_samples = 0;
if (!rs->is_app_limited) {
- bbr->inflight_hi = ngtcp2_max(
+ bbr->inflight_hi = ngtcp2_max_uint64(
rs->tx_in_flight, bbr_target_inflight(bbr, cstat) *
NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
}
@@ -1154,8 +1155,8 @@ static uint64_t bbr_quantization_budget(ngtcp2_cc_bbr *bbr,
bbr_update_offload_budget(bbr, cstat);
inflight = ngtcp2_max(inflight, bbr->offload_budget);
- inflight =
- ngtcp2_max(inflight, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
+ inflight = ngtcp2_max_uint64(inflight,
+ min_pipe_cwnd(cstat->max_tx_udp_payload_size));
if (bbr->state == NGTCP2_BBR_STATE_PROBE_BW_UP) {
inflight += 2 * cstat->max_tx_udp_payload_size;
@@ -1198,15 +1199,16 @@ static void bbr_modulate_cwnd_for_recovery(ngtcp2_cc_bbr *bbr,
if (ack->bytes_lost > 0) {
if (cstat->cwnd > ack->bytes_lost) {
cstat->cwnd -= ack->bytes_lost;
- cstat->cwnd = ngtcp2_max(cstat->cwnd, 2 * cstat->max_tx_udp_payload_size);
+ cstat->cwnd =
+ ngtcp2_max_uint64(cstat->cwnd, 2 * cstat->max_tx_udp_payload_size);
} else {
cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
}
}
if (bbr->packet_conservation) {
- cstat->cwnd =
- ngtcp2_max(cstat->cwnd, cstat->bytes_in_flight + ack->bytes_delivered);
+ cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, cstat->bytes_in_flight +
+ ack->bytes_delivered);
}
}
@@ -1400,8 +1402,8 @@ static void bbr_cc_on_persistent_congestion(ngtcp2_cc *cc,
bbr_save_cwnd(bbr, cstat);
cstat->cwnd = cstat->bytes_in_flight + cstat->max_tx_udp_payload_size;
- cstat->cwnd =
- ngtcp2_max(cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
+ cstat->cwnd = ngtcp2_max_uint64(
+ cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
}
static void bbr_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c
index 9ad37fb..bade016 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c
@@ -41,7 +41,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);
- return ngtcp2_min(10 * max_udp_payload_size, n);
+ return ngtcp2_min_uint64(10 * max_udp_payload_size, n);
}
ngtcp2_cc_pkt *ngtcp2_cc_pkt_init(ngtcp2_cc_pkt *pkt, int64_t pkt_num,
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
index c8caf47..a8e8874 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
@@ -37,7 +37,8 @@
#include "ngtcp2_rcvry.h"
#include "ngtcp2_unreachable.h"
#include "ngtcp2_net.h"
-#include "ngtcp2_conversion.h"
+#include "ngtcp2_transport_params.h"
+#include "ngtcp2_settings.h"
#include "ngtcp2_tstamp.h"
#include "ngtcp2_frame_chain.h"
@@ -663,13 +664,11 @@ static int conn_call_recv_tx_key(ngtcp2_conn *conn,
return 0;
}
-static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
- ngtcp2_rst *rst, ngtcp2_cc *cc, int64_t initial_pkt_num,
- ngtcp2_log *log, ngtcp2_qlog *qlog,
- ngtcp2_objalloc *rtb_entry_objalloc,
- ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
- int rv;
-
+static void pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
+ ngtcp2_rst *rst, ngtcp2_cc *cc, int64_t initial_pkt_num,
+ ngtcp2_log *log, ngtcp2_qlog *qlog,
+ ngtcp2_objalloc *rtb_entry_objalloc,
+ ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
memset(pktns, 0, sizeof(*pktns));
ngtcp2_gaptr_init(&pktns->rx.pngap, mem);
@@ -679,10 +678,7 @@ static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
pktns->rx.max_pkt_num = -1;
pktns->rx.max_ack_eliciting_pkt_num = -1;
- rv = ngtcp2_acktr_init(&pktns->acktr, log, mem);
- if (rv != 0) {
- goto fail_acktr_init;
- }
+ ngtcp2_acktr_init(&pktns->acktr, log, mem);
ngtcp2_strm_init(&pktns->crypto.strm, 0, NGTCP2_STRM_FLAG_NONE, 0, 0, NULL,
frc_objalloc, mem);
@@ -690,13 +686,6 @@ static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
ngtcp2_rtb_init(&pktns->rtb, pktns_id, &pktns->crypto.strm, rst, cc,
initial_pkt_num, log, qlog, rtb_entry_objalloc, frc_objalloc,
mem);
-
- return 0;
-
-fail_acktr_init:
- ngtcp2_gaptr_free(&pktns->rx.pngap);
-
- return rv;
}
static int pktns_new(ngtcp2_pktns **ppktns, ngtcp2_pktns_id pktns_id,
@@ -704,20 +693,15 @@ static int pktns_new(ngtcp2_pktns **ppktns, ngtcp2_pktns_id pktns_id,
ngtcp2_log *log, ngtcp2_qlog *qlog,
ngtcp2_objalloc *rtb_entry_objalloc,
ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
- int rv;
-
*ppktns = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_pktns));
if (*ppktns == NULL) {
return NGTCP2_ERR_NOMEM;
}
- rv = pktns_init(*ppktns, pktns_id, rst, cc, initial_pkt_num, log, qlog,
- rtb_entry_objalloc, frc_objalloc, mem);
- if (rv != 0) {
- ngtcp2_mem_free(mem, *ppktns);
- }
+ pktns_init(*ppktns, pktns_id, rst, cc, initial_pkt_num, log, qlog,
+ rtb_entry_objalloc, frc_objalloc, mem);
- return rv;
+ return 0;
}
static int cycle_less(const ngtcp2_pq_entry *lhs, const ngtcp2_pq_entry *rhs) {
@@ -803,8 +787,9 @@ static void conn_reset_conn_stat_cc(ngtcp2_conn *conn,
cstat->first_rtt_sample_ts = UINT64_MAX;
cstat->pto_count = 0;
cstat->loss_detection_timer = UINT64_MAX;
- cstat->cwnd =
- ngtcp2_cc_compute_initcwnd(conn->local.settings.max_tx_udp_payload_size);
+ cstat->max_tx_udp_payload_size =
+ ngtcp2_conn_get_path_max_tx_udp_payload_size(conn);
+ cstat->cwnd = ngtcp2_cc_compute_initcwnd(cstat->max_tx_udp_payload_size);
cstat->ssthresh = UINT64_MAX;
cstat->congestion_recovery_start_ts = UINT64_MAX;
cstat->bytes_in_flight = 0;
@@ -847,7 +832,7 @@ static void delete_scid(ngtcp2_ksl *scids, const ngtcp2_mem *mem) {
static ngtcp2_duration compute_pto(ngtcp2_duration smoothed_rtt,
ngtcp2_duration rttvar,
ngtcp2_duration max_ack_delay) {
- ngtcp2_duration var = ngtcp2_max(4 * rttvar, NGTCP2_GRANULARITY);
+ ngtcp2_duration var = ngtcp2_max_uint64(4 * rttvar, NGTCP2_GRANULARITY);
return smoothed_rtt + var + max_ack_delay;
}
@@ -1007,28 +992,15 @@ static void conn_reset_ecn_validation_state(ngtcp2_conn *conn) {
static uint8_t server_default_available_versions[] = {0, 0, 0, 1};
/*
- * available_versions_new allocates new buffer, and writes |versions|
- * of length |versionslen| in network byte order, suitable for sending
- * in available_versions field of version_information QUIC transport
- * parameter. The pointer to the allocated buffer is assigned to
- * |*pbuf|.
- *
- * This function returns 0 if it succeeds, or one of the negative
- * error codes:
- *
- * NGTCP2_ERR_NOMEM
- * Out of memory.
+ * available_versions_init writes |versions| of length |versionslen|
+ * in network byte order to the buffer pointed by |buf|, suitable for
+ * sending in available_versions field of version_information QUIC
+ * transport parameter. This function returns the pointer to the one
+ * beyond the last byte written.
*/
-static int available_versions_new(uint8_t **pbuf, const uint32_t *versions,
- size_t versionslen, const ngtcp2_mem *mem) {
+static void *available_versions_init(void *buf, const uint32_t *versions,
+ size_t versionslen) {
size_t i;
- uint8_t *buf = ngtcp2_mem_malloc(mem, sizeof(uint32_t) * versionslen);
-
- if (buf == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
-
- *pbuf = buf;
for (i = 0; i < versionslen; ++i) {
buf = ngtcp2_put_uint32be(buf, versions[i]);
@@ -1055,6 +1027,16 @@ conn_set_local_transport_params(ngtcp2_conn *conn,
p->version_info_present = 1;
}
+static size_t buflen_align(size_t buflen) {
+ return (buflen + 0x7) & (size_t)~0x7;
+}
+
+static void *buf_align(void *buf) {
+ return (void *)((uintptr_t)((uint8_t *)buf + 0x7) & (uintptr_t)~0x7);
+}
+
+static void *buf_advance(void *buf, size_t n) { return (uint8_t *)buf + n; }
+
static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
const ngtcp2_cid *scid, const ngtcp2_path *path,
uint32_t client_chosen_version, int callbacks_version,
@@ -1065,14 +1047,18 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
const ngtcp2_mem *mem, void *user_data, int server) {
int rv;
ngtcp2_scid *scident;
- uint8_t *buf;
+ void *buf, *tokenbuf;
+ size_t buflen;
uint8_t fixed_bit_byte;
size_t i;
uint32_t *preferred_versions;
+ ngtcp2_settings settingsbuf;
ngtcp2_transport_params paramsbuf;
(void)callbacks_version;
(void)settings_version;
+ settings = ngtcp2_settings_convert_to_latest(&settingsbuf, settings_version,
+ settings);
params = ngtcp2_transport_params_convert_to_latest(
&paramsbuf, transport_params_version, params);
@@ -1111,16 +1097,54 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
assert(callbacks->get_path_challenge_data);
assert(!server || !ngtcp2_is_reserved_version(client_chosen_version));
+ for (i = 0; i < settings->pmtud_probeslen; ++i) {
+ assert(settings->pmtud_probes[i] > NGTCP2_MAX_UDP_PAYLOAD_SIZE);
+ }
+
if (mem == NULL) {
mem = ngtcp2_mem_default();
}
- *pconn = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_conn));
- if (*pconn == NULL) {
- rv = NGTCP2_ERR_NOMEM;
- goto fail_conn;
+ buflen = sizeof(ngtcp2_conn);
+ if (settings->qlog_write) {
+ buflen = buflen_align(buflen);
+ buflen += NGTCP2_QLOG_BUFLEN;
+ }
+
+ if (settings->pmtud_probeslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->pmtud_probes[0]) * settings->pmtud_probeslen;
+ }
+
+ if (settings->preferred_versionslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->preferred_versions[0]) *
+ settings->preferred_versionslen;
+ }
+
+ if (settings->available_versionslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->available_versions[0]) *
+ settings->available_versionslen;
+ } else if (server) {
+ if (settings->preferred_versionslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->preferred_versions[0]) *
+ settings->preferred_versionslen;
+ }
+ } else if (!ngtcp2_is_reserved_version(client_chosen_version)) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(client_chosen_version);
}
+ buf = ngtcp2_mem_calloc(mem, 1, buflen);
+ if (buf == NULL) {
+ return NGTCP2_ERR_NOMEM;
+ }
+
+ *pconn = buf;
+ buf = buf_advance(buf, sizeof(ngtcp2_conn));
+
(*pconn)->server = server;
ngtcp2_objalloc_frame_chain_init(&(*pconn)->frc_objalloc, 64, mem);
@@ -1154,36 +1178,47 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
ngtcp2_qlog_init(&(*pconn)->qlog, settings->qlog_write, settings->initial_ts,
user_data);
if ((*pconn)->qlog.write) {
- buf = ngtcp2_mem_malloc(mem, NGTCP2_QLOG_BUFLEN);
- if (buf == NULL) {
- rv = NGTCP2_ERR_NOMEM;
- goto fail_qlog_buf;
- }
+ buf = buf_align(buf);
ngtcp2_buf_init(&(*pconn)->qlog.buf, buf, NGTCP2_QLOG_BUFLEN);
+ buf = buf_advance(buf, NGTCP2_QLOG_BUFLEN);
}
(*pconn)->local.settings = *settings;
if (settings->tokenlen) {
- buf = ngtcp2_mem_malloc(mem, settings->tokenlen);
- if (buf == NULL) {
+ tokenbuf = ngtcp2_mem_malloc(mem, settings->tokenlen);
+ if (tokenbuf == NULL) {
rv = NGTCP2_ERR_NOMEM;
goto fail_token;
}
- memcpy(buf, settings->token, settings->tokenlen);
- (*pconn)->local.settings.token = buf;
+ memcpy(tokenbuf, settings->token, settings->tokenlen);
+ (*pconn)->local.settings.token = tokenbuf;
} else {
(*pconn)->local.settings.token = NULL;
}
+ if (settings->pmtud_probeslen) {
+ (*pconn)->local.settings.pmtud_probes = buf_align(buf);
+ buf = ngtcp2_cpymem((uint16_t *)(*pconn)->local.settings.pmtud_probes,
+ settings->pmtud_probes,
+ sizeof(settings->pmtud_probes[0]) *
+ settings->pmtud_probeslen);
+ }
+
if (!(*pconn)->local.settings.original_version) {
(*pconn)->local.settings.original_version = client_chosen_version;
}
+ ngtcp2_dcid_init(&(*pconn)->dcid.current, 0, dcid, NULL);
+ ngtcp2_dcid_set_path(&(*pconn)->dcid.current, path);
+
+ rv = ngtcp2_gaptr_push(&(*pconn)->dcid.seqgap, 0, 1);
+ if (rv != 0) {
+ goto fail_seqgap_push;
+ }
+
conn_reset_conn_stat(*pconn, &(*pconn)->cstat);
(*pconn)->cstat.initial_rtt = settings->initial_rtt;
- (*pconn)->cstat.max_tx_udp_payload_size =
- (*pconn)->local.settings.max_tx_udp_payload_size;
ngtcp2_rst_init(&(*pconn)->rst);
@@ -1224,13 +1259,10 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
goto fail_hs_pktns_init;
}
- rv = pktns_init(&(*pconn)->pktns, NGTCP2_PKTNS_ID_APPLICATION, &(*pconn)->rst,
- &(*pconn)->cc, settings->initial_pkt_num, &(*pconn)->log,
- &(*pconn)->qlog, &(*pconn)->rtb_entry_objalloc,
- &(*pconn)->frc_objalloc, mem);
- if (rv != 0) {
- goto fail_pktns_init;
- }
+ pktns_init(&(*pconn)->pktns, NGTCP2_PKTNS_ID_APPLICATION, &(*pconn)->rst,
+ &(*pconn)->cc, settings->initial_pkt_num, &(*pconn)->log,
+ &(*pconn)->qlog, &(*pconn)->rtb_entry_objalloc,
+ &(*pconn)->frc_objalloc, mem);
scident = ngtcp2_mem_malloc(mem, sizeof(*scident));
if (scident == NULL) {
@@ -1249,14 +1281,6 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
scident = NULL;
- ngtcp2_dcid_init(&(*pconn)->dcid.current, 0, dcid, NULL);
- ngtcp2_dcid_set_path(&(*pconn)->dcid.current, path);
-
- rv = ngtcp2_gaptr_push(&(*pconn)->dcid.seqgap, 0, 1);
- if (rv != 0) {
- goto fail_seqgap_push;
- }
-
if (settings->preferred_versionslen) {
if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
for (i = 0; i < settings->preferred_versionslen; ++i) {
@@ -1268,12 +1292,9 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
assert(i < settings->preferred_versionslen);
}
- preferred_versions = ngtcp2_mem_malloc(
- mem, sizeof(uint32_t) * settings->preferred_versionslen);
- if (preferred_versions == NULL) {
- rv = NGTCP2_ERR_NOMEM;
- goto fail_preferred_versions;
- }
+ preferred_versions = buf_align(buf);
+ buf = buf_advance(preferred_versions, sizeof(preferred_versions[0]) *
+ settings->preferred_versionslen);
for (i = 0; i < settings->preferred_versionslen; ++i) {
assert(ngtcp2_is_supported_version(settings->preferred_versions[i]));
@@ -1304,39 +1325,33 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
ngtcp2_is_supported_version(settings->available_versions[i]));
}
- rv = available_versions_new(&buf, settings->available_versions,
- settings->available_versionslen, mem);
- if (rv != 0) {
- goto fail_available_versions;
- }
-
- (*pconn)->vneg.available_versions = buf;
+ (*pconn)->vneg.available_versions = buf_align(buf);
(*pconn)->vneg.available_versionslen =
sizeof(uint32_t) * settings->available_versionslen;
+
+ buf = available_versions_init((*pconn)->vneg.available_versions,
+ settings->available_versions,
+ settings->available_versionslen);
} else if (server) {
if (settings->preferred_versionslen) {
- rv = available_versions_new(&buf, settings->preferred_versions,
- settings->preferred_versionslen, mem);
- if (rv != 0) {
- goto fail_available_versions;
- }
-
- (*pconn)->vneg.available_versions = buf;
+ (*pconn)->vneg.available_versions = buf_align(buf);
(*pconn)->vneg.available_versionslen =
sizeof(uint32_t) * settings->preferred_versionslen;
+
+ buf = available_versions_init((*pconn)->vneg.available_versions,
+ settings->preferred_versions,
+ settings->preferred_versionslen);
} else {
(*pconn)->vneg.available_versions = server_default_available_versions;
(*pconn)->vneg.available_versionslen =
sizeof(server_default_available_versions);
}
- } else if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
- rv = available_versions_new(&buf, &client_chosen_version, 1, mem);
- if (rv != 0) {
- goto fail_available_versions;
- }
-
- (*pconn)->vneg.available_versions = buf;
+ } else if (!ngtcp2_is_reserved_version(client_chosen_version)) {
+ (*pconn)->vneg.available_versions = buf_align(buf);
(*pconn)->vneg.available_versionslen = sizeof(uint32_t);
+
+ buf = available_versions_init((*pconn)->vneg.available_versions,
+ &client_chosen_version, 1);
}
(*pconn)->local.settings.available_versions = NULL;
@@ -1377,34 +1392,19 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
return 0;
-fail_available_versions:
- ngtcp2_mem_free(mem, (*pconn)->vneg.preferred_versions);
-fail_preferred_versions:
-fail_seqgap_push:
fail_scid_set_insert:
ngtcp2_mem_free(mem, scident);
fail_scident:
- pktns_free(&(*pconn)->pktns, mem);
-fail_pktns_init:
pktns_del((*pconn)->hs_pktns, mem);
fail_hs_pktns_init:
pktns_del((*pconn)->in_pktns, mem);
fail_in_pktns_init:
+ ngtcp2_gaptr_free(&(*pconn)->dcid.seqgap);
+fail_seqgap_push:
ngtcp2_mem_free(mem, (uint8_t *)(*pconn)->local.settings.token);
fail_token:
- ngtcp2_mem_free(mem, (*pconn)->qlog.buf.begin);
-fail_qlog_buf:
- ngtcp2_idtr_free(&(*pconn)->remote.uni.idtr);
- ngtcp2_idtr_free(&(*pconn)->remote.bidi.idtr);
- ngtcp2_map_free(&(*pconn)->strms);
- delete_scid(&(*pconn)->scid.set, mem);
- ngtcp2_ksl_free(&(*pconn)->scid.set);
- ngtcp2_gaptr_free(&(*pconn)->dcid.seqgap);
- ngtcp2_objalloc_free(&(*pconn)->strm_objalloc);
- ngtcp2_objalloc_free(&(*pconn)->rtb_entry_objalloc);
- ngtcp2_objalloc_free(&(*pconn)->frc_objalloc);
ngtcp2_mem_free(mem, *pconn);
-fail_conn:
+
return rv;
}
@@ -1471,8 +1471,8 @@ int ngtcp2_conn_server_new_versioned(
* credits are considered.
*/
static uint64_t conn_fc_credits(ngtcp2_conn *conn, ngtcp2_strm *strm) {
- return ngtcp2_min(strm->tx.max_offset - strm->tx.offset,
- conn->tx.max_offset - conn->tx.offset);
+ return ngtcp2_min_uint64(strm->tx.max_offset - strm->tx.offset,
+ conn->tx.max_offset - conn->tx.offset);
}
/*
@@ -1582,11 +1582,6 @@ void ngtcp2_conn_del(ngtcp2_conn *conn) {
conn_vneg_crypto_free(conn);
- ngtcp2_mem_free(conn->mem, conn->vneg.preferred_versions);
- if (conn->vneg.available_versions != server_default_available_versions) {
- ngtcp2_mem_free(conn->mem, conn->vneg.available_versions);
- }
-
ngtcp2_mem_free(conn->mem, conn->crypto.decrypt_buf.base);
ngtcp2_mem_free(conn->mem, conn->crypto.decrypt_hp_buf.base);
ngtcp2_mem_free(conn->mem, (uint8_t *)conn->local.settings.token);
@@ -1600,8 +1595,6 @@ void ngtcp2_conn_del(ngtcp2_conn *conn) {
pktns_del(conn->hs_pktns, conn->mem);
pktns_del(conn->in_pktns, conn->mem);
- ngtcp2_mem_free(conn->mem, conn->qlog.buf.begin);
-
ngtcp2_pmtud_del(conn->pmtud);
ngtcp2_pv_del(conn->pv);
@@ -1665,8 +1658,8 @@ static int conn_ensure_ack_ranges(ngtcp2_conn *conn, size_t n) {
* ACK.
*/
static ngtcp2_duration conn_compute_ack_delay(ngtcp2_conn *conn) {
- return ngtcp2_min(conn->local.transport_params.max_ack_delay,
- conn->cstat.smoothed_rtt / 8);
+ return ngtcp2_min_uint64(conn->local.transport_params.max_ack_delay,
+ conn->cstat.smoothed_rtt / 8);
}
int ngtcp2_conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
@@ -2021,12 +2014,13 @@ static int conn_should_pad_pkt(ngtcp2_conn *conn, uint8_t type, size_t left,
return 0;
}
- if (conn->hs_pktns->crypto.tx.ckm &&
- (conn->hs_pktns->rtb.probe_pkt_left ||
- !ngtcp2_strm_streamfrq_empty(&conn->hs_pktns->crypto.strm) ||
- !ngtcp2_acktr_empty(&conn->hs_pktns->acktr))) {
- /* If we have something to send in Handshake packet, then add
- PADDING in Handshake packet. */
+ if ((conn->hs_pktns->crypto.tx.ckm &&
+ (conn->hs_pktns->rtb.probe_pkt_left ||
+ !ngtcp2_strm_streamfrq_empty(&conn->hs_pktns->crypto.strm) ||
+ !ngtcp2_acktr_empty(&conn->hs_pktns->acktr))) ||
+ conn->pktns.crypto.tx.ckm) {
+ /* If we have something to send in Handshake or 1RTT packet,
+ then add PADDING in that packet. */
min_payloadlen = NGTCP2_MIN_COALESCED_PAYLOADLEN;
} else {
return 1;
@@ -2195,9 +2189,10 @@ static uint8_t conn_pkt_flags_short(ngtcp2_conn *conn) {
/*
* conn_write_handshake_pkt writes handshake packet in the buffer
- * pointed by |dest| whose length is |destlen|. |type| specifies long
- * packet type. It should be either NGTCP2_PKT_INITIAL or
- * NGTCP2_PKT_HANDSHAKE_PKT.
+ * pointed by |dest| whose length is |destlen|. |dgram_offset| is the
+ * offset in UDP datagram payload where this QUIC packet is positioned
+ * at. |type| specifies long packet type. It should be either
+ * NGTCP2_PKT_INITIAL or NGTCP2_PKT_HANDSHAKE_PKT.
*
* |write_datalen| is the minimum length of application data ready to
* send in subsequent 0RTT packet.
@@ -2212,8 +2207,9 @@ static uint8_t conn_pkt_flags_short(ngtcp2_conn *conn) {
*/
static ngtcp2_ssize
conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
- size_t destlen, uint8_t type, uint8_t flags,
- uint64_t write_datalen, ngtcp2_tstamp ts) {
+ size_t destlen, size_t dgram_offset, uint8_t type,
+ uint8_t flags, uint64_t write_datalen,
+ ngtcp2_tstamp ts) {
int rv;
ngtcp2_ppe ppe;
ngtcp2_pkt_hd hd;
@@ -2282,7 +2278,7 @@ conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
hd.tokenlen = conn->local.settings.tokenlen;
}
- ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
+ ngtcp2_ppe_init(&ppe, dest, destlen, dgram_offset, &cc);
rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
if (rv != 0) {
@@ -2433,7 +2429,7 @@ conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) != 0,
require_padding)) {
lfr.type = NGTCP2_FRAME_PADDING;
- lfr.padding.len = ngtcp2_ppe_padding(&ppe);
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(&ppe);
} else if (pkt_empty) {
return 0;
} else {
@@ -2602,11 +2598,7 @@ static void conn_discard_pktns(ngtcp2_conn *conn, ngtcp2_pktns **ppktns,
ngtcp2_conn_set_loss_detection_timer(conn, ts);
}
-/*
- * conn_discard_initial_state discards state for Initial packet number
- * space.
- */
-static void conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
+void ngtcp2_conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
if (!conn->in_pktns) {
return;
}
@@ -2622,11 +2614,7 @@ static void conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
memset(&conn->vneg.tx, 0, sizeof(conn->vneg.tx));
}
-/*
- * conn_discard_handshake_state discards state for Handshake packet
- * number space.
- */
-static void conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
+void ngtcp2_conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
if (!conn->hs_pktns) {
return;
}
@@ -2694,7 +2682,7 @@ static ngtcp2_ssize conn_write_handshake_ack_pkts(ngtcp2_conn *conn,
res += nwrite;
if (!conn->server && nwrite) {
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
}
}
@@ -2725,9 +2713,9 @@ static ngtcp2_ssize conn_write_client_initial(ngtcp2_conn *conn,
return rv;
}
- return conn_write_handshake_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
- NGTCP2_WRITE_PKT_FLAG_NONE, early_datalen,
- ts);
+ return conn_write_handshake_pkt(
+ conn, pi, dest, destlen, 0, NGTCP2_PKT_INITIAL,
+ NGTCP2_WRITE_PKT_FLAG_NONE, early_datalen, ts);
}
/*
@@ -2807,10 +2795,10 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
conn->hs_pktns->rtb.probe_pkt_left)) {
/* Discard Initial state here so that Handshake packet is not
padded. */
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
} else if (conn->in_pktns) {
nwrite =
- conn_write_handshake_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
+ conn_write_handshake_pkt(conn, pi, dest, destlen, 0, NGTCP2_PKT_INITIAL,
NGTCP2_WRITE_PKT_FLAG_NONE, write_datalen, ts);
if (nwrite < 0) {
assert(nwrite != NGTCP2_ERR_NOBUF);
@@ -2837,10 +2825,10 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
dest += nwrite;
destlen -= (size_t)nwrite;
- if (destlen) {
- /* We might have already added padding to Initial, but in that
- case, we should have destlen == 0 and no Handshake packet
- will be written. */
+ /* If initial packet size is at least
+ NGTCP2_MAX_UDP_PAYLOAD_SIZE, no extra padding is needed in a
+ subsequent packet. */
+ if (nwrite < NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
if (conn->server) {
it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
if (!ngtcp2_ksl_it_end(&it)) {
@@ -2856,8 +2844,9 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
}
}
- nwrite = conn_write_handshake_pkt(
- conn, pi, dest, destlen, NGTCP2_PKT_HANDSHAKE, wflags, write_datalen, ts);
+ nwrite =
+ conn_write_handshake_pkt(conn, pi, dest, destlen, (size_t)res,
+ NGTCP2_PKT_HANDSHAKE, wflags, write_datalen, ts);
if (nwrite < 0) {
assert(nwrite != NGTCP2_ERR_NOBUF);
return nwrite;
@@ -2869,7 +2858,7 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
/* We don't need to send further Initial packet if we have
Handshake key and sent something with it. So discard initial
state here. */
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
}
return res;
@@ -3097,7 +3086,8 @@ static int conn_remove_retired_connection_id(ngtcp2_conn *conn,
* this endpoint sends.
*/
static size_t conn_min_short_pktlen(ngtcp2_conn *conn) {
- return conn->dcid.current.cid.datalen + NGTCP2_MIN_PKT_EXPANDLEN;
+ return ngtcp2_max(conn->dcid.current.cid.datalen, conn->oscid.datalen) +
+ NGTCP2_MIN_PKT_EXPANDLEN;
}
/*
@@ -3155,8 +3145,10 @@ static void conn_reset_ppe_pending(ngtcp2_conn *conn) {
/*
* conn_write_pkt writes a protected packet in the buffer pointed by
- * |dest| whose length if |destlen|. |type| specifies the type of
- * packet. It can be NGTCP2_PKT_1RTT or NGTCP2_PKT_0RTT.
+ * |dest| whose length if |destlen|. |dgram_offset| is the offset in
+ * UDP datagram payload where this QUIC packet is positioned at.
+ * |type| specifies the type of packet. It can be NGTCP2_PKT_1RTT or
+ * NGTCP2_PKT_0RTT.
*
* This function can send new stream data. In order to send stream
* data, specify the underlying stream and parameters to
@@ -3183,8 +3175,9 @@ static void conn_reset_ppe_pending(ngtcp2_conn *conn) {
*/
static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
uint8_t *dest, size_t destlen,
- ngtcp2_vmsg *vmsg, uint8_t type,
- uint8_t flags, ngtcp2_tstamp ts) {
+ size_t dgram_offset, ngtcp2_vmsg *vmsg,
+ uint8_t type, uint8_t flags,
+ ngtcp2_tstamp ts) {
int rv = 0;
ngtcp2_crypto_cc *cc = &conn->pkt.cc;
ngtcp2_ppe *ppe = &conn->pkt.ppe;
@@ -3369,7 +3362,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
pktns->tx.last_pkt_num + 1,
pktns_select_pkt_numlen(pktns), version, 0);
- ngtcp2_ppe_init(ppe, dest, destlen, cc);
+ ngtcp2_ppe_init(ppe, dest, destlen, dgram_offset, cc);
rv = ngtcp2_ppe_encode_hd(ppe, hd);
if (rv != 0) {
@@ -3944,6 +3937,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
vmsg->stream.strm->tx.offset += ndatalen;
conn->tx.offset += ndatalen;
+ vmsg->stream.strm->flags |= NGTCP2_STRM_FLAG_ANY_SENT;
if (fin) {
ngtcp2_strm_shutdown(vmsg->stream.strm, NGTCP2_STRM_FLAG_SHUT_WR);
@@ -4166,10 +4160,8 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
/* TODO Push STREAM frame back to ngtcp2_strm if there is an error
before ngtcp2_rtb_entry is safely created and added. */
- if (require_padding ||
- /* Making full sized packet will help GSO a bit */
- ngtcp2_ppe_left(ppe) < 10) {
- lfr.padding.len = ngtcp2_ppe_padding(ppe);
+ if (require_padding) {
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(ppe);
} else if (type == NGTCP2_PKT_1RTT) {
lfr.padding.len = ngtcp2_ppe_padding_size(ppe, min_pktlen);
} else {
@@ -4332,7 +4324,7 @@ ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
pktns->tx.last_pkt_num + 1, pktns_select_pkt_numlen(pktns),
version, 0);
- ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
+ ngtcp2_ppe_init(&ppe, dest, destlen, 0, &cc);
rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
if (rv != 0) {
@@ -4354,14 +4346,16 @@ ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
}
lfr.type = NGTCP2_FRAME_PADDING;
- if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) {
- lfr.padding.len = ngtcp2_ppe_padding(&ppe);
+ if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL) {
+ lfr.padding.len = ngtcp2_ppe_dgram_padding_size(&ppe, destlen);
+ } else if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) {
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(&ppe);
} else {
switch (fr->type) {
case NGTCP2_FRAME_PATH_CHALLENGE:
case NGTCP2_FRAME_PATH_RESPONSE:
if (!conn->server || destlen >= NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
- lfr.padding.len = ngtcp2_ppe_padding(&ppe);
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(&ppe);
} else {
lfr.padding.len = 0;
}
@@ -4522,6 +4516,10 @@ static int conn_retire_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
ngtcp2_frame_chain *nfrc;
int rv;
+ if (ngtcp2_conn_check_retired_dcid_tracked(conn, seq)) {
+ return 0;
+ }
+
rv = ngtcp2_conn_track_retired_dcid_seq(conn, seq);
if (rv != 0) {
return rv;
@@ -4664,7 +4662,9 @@ static int conn_start_pmtud(ngtcp2_conn *conn) {
rv = ngtcp2_pmtud_new(&conn->pmtud, conn->dcid.current.max_udp_payload_size,
hard_max_udp_payload_size,
- conn->pktns.tx.last_pkt_num + 1, conn->mem);
+ conn->pktns.tx.last_pkt_num + 1,
+ conn->local.settings.pmtud_probes,
+ conn->local.settings.pmtud_probeslen, conn->mem);
if (rv != 0) {
return rv;
}
@@ -4716,7 +4716,7 @@ static ngtcp2_ssize conn_write_pmtud_probe(ngtcp2_conn *conn,
nwrite = ngtcp2_conn_write_single_frame_pkt(
conn, pi, dest, probelen, NGTCP2_PKT_1RTT,
- NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING, &conn->dcid.current.cid, &lfr,
+ NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL, &conn->dcid.current.cid, &lfr,
NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE,
@@ -6833,6 +6833,12 @@ static int conn_emit_pending_stream_data(ngtcp2_conn *conn, ngtcp2_strm *strm,
return rv;
}
+ /* ngtcp2_conn_shutdown_stream_read from a callback will free
+ strm->rx.rob. */
+ if (!strm->rx.rob) {
+ return 0;
+ }
+
ngtcp2_rob_pop(strm->rx.rob, rx_offset - datalen, datalen);
}
}
@@ -8221,7 +8227,7 @@ static int conn_recv_handshake_done(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
conn->pktns.rtb.persistent_congestion_start_ts = ts;
- conn_discard_handshake_state(conn, ts);
+ ngtcp2_conn_discard_handshake_state(conn, ts);
assert(conn->remote.transport_params);
@@ -8550,13 +8556,13 @@ static int conn_recv_non_probing_pkt_on_new_path(ngtcp2_conn *conn,
pv->fallback_pto = pto;
}
+ ngtcp2_dcid_copy(&conn->dcid.current, &dcid);
+
if (!local_addr_eq || (remote_addr_cmp & (NGTCP2_ADDR_COMPARE_FLAG_ADDR |
NGTCP2_ADDR_COMPARE_FLAG_FAMILY))) {
conn_reset_congestion_state(conn, ts);
}
- ngtcp2_dcid_copy(&conn->dcid.current, &dcid);
-
conn_reset_ecn_validation_state(conn);
ngtcp2_conn_stop_pmtud(conn);
@@ -9822,7 +9828,7 @@ static ngtcp2_ssize conn_read_handshake(ngtcp2_conn *conn,
}
if (conn->hs_pktns->rx.max_pkt_num != -1) {
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
}
if (!conn_is_tls_handshake_completed(conn)) {
@@ -9888,7 +9894,7 @@ static ngtcp2_ssize conn_read_handshake(ngtcp2_conn *conn,
return rv;
}
- conn_discard_handshake_state(conn, ts);
+ ngtcp2_conn_discard_handshake_state(conn, ts);
rv = conn_enqueue_handshake_done(conn);
if (rv != 0) {
@@ -9936,7 +9942,7 @@ int ngtcp2_conn_read_pkt_versioned(ngtcp2_conn *conn, const ngtcp2_path *path,
pktlen);
if (pktlen == 0) {
- return NGTCP2_ERR_INVALID_ARGUMENT;
+ return 0;
}
/* client does not expect a packet from unknown path. */
@@ -10035,13 +10041,12 @@ static int conn_check_pkt_num_exhausted(ngtcp2_conn *conn) {
* conn_retransmit_retry_early retransmits 0RTT packet after Retry is
* received from server.
*/
-static ngtcp2_ssize conn_retransmit_retry_early(ngtcp2_conn *conn,
- ngtcp2_pkt_info *pi,
- uint8_t *dest, size_t destlen,
- uint8_t flags,
- ngtcp2_tstamp ts) {
- return conn_write_pkt(conn, pi, dest, destlen, NULL, NGTCP2_PKT_0RTT, flags,
- ts);
+static ngtcp2_ssize
+conn_retransmit_retry_early(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
+ uint8_t *dest, size_t destlen, size_t dgram_offset,
+ uint8_t flags, ngtcp2_tstamp ts) {
+ return conn_write_pkt(conn, pi, dest, destlen, dgram_offset, NULL,
+ NGTCP2_PKT_0RTT, flags, ts);
}
/*
@@ -10137,7 +10142,7 @@ static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
}
} else {
nwrite = conn_write_handshake_pkt(
- conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
+ conn, pi, dest, destlen, 0, NGTCP2_PKT_INITIAL,
NGTCP2_WRITE_PKT_FLAG_NONE, write_datalen, ts);
if (nwrite < 0) {
return nwrite;
@@ -10146,7 +10151,7 @@ static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
if (pending_early_datalen) {
early_spktlen = conn_retransmit_retry_early(
- conn, pi, dest + nwrite, destlen - (size_t)nwrite,
+ conn, pi, dest + nwrite, destlen - (size_t)nwrite, (size_t)nwrite,
nwrite ? NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING
: NGTCP2_WRITE_PKT_FLAG_NONE,
ts);
@@ -10186,8 +10191,9 @@ static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
if (!conn_is_tls_handshake_completed(conn)) {
if (!(conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED)) {
- nwrite = conn_retransmit_retry_early(conn, pi, dest, destlen,
- NGTCP2_WRITE_PKT_FLAG_NONE, ts);
+ nwrite =
+ conn_retransmit_retry_early(conn, pi, dest, destlen, (size_t)res,
+ NGTCP2_WRITE_PKT_FLAG_NONE, ts);
if (nwrite < 0) {
return nwrite;
}
@@ -10363,8 +10369,8 @@ static ngtcp2_ssize conn_client_write_handshake(ngtcp2_conn *conn,
datalen = ngtcp2_vec_len(vmsg->stream.data, vmsg->stream.datacnt);
send_stream = conn_retry_early_payloadlen(conn) == 0;
if (send_stream) {
- write_datalen = ngtcp2_min(datalen + NGTCP2_STREAM_OVERHEAD,
- NGTCP2_MIN_COALESCED_PAYLOADLEN);
+ write_datalen = ngtcp2_min_uint64(datalen + NGTCP2_STREAM_OVERHEAD,
+ NGTCP2_MIN_COALESCED_PAYLOADLEN);
if (vmsg->stream.flags & NGTCP2_WRITE_STREAM_FLAG_MORE) {
wflags |= NGTCP2_WRITE_PKT_FLAG_MORE;
@@ -10428,8 +10434,8 @@ static ngtcp2_ssize conn_client_write_handshake(ngtcp2_conn *conn,
return spktlen;
}
- early_spktlen = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_0RTT,
- wflags, ts);
+ early_spktlen = conn_write_pkt(conn, pi, dest, destlen, (size_t)spktlen, vmsg,
+ NGTCP2_PKT_0RTT, wflags, ts);
if (early_spktlen < 0) {
switch (early_spktlen) {
case NGTCP2_ERR_STREAM_DATA_BLOCKED:
@@ -10905,7 +10911,7 @@ ngtcp2_tstamp ngtcp2_conn_loss_detection_expiry(ngtcp2_conn *conn) {
}
ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
- ngtcp2_tstamp res = UINT64_MAX, t;
+ ngtcp2_tstamp res = UINT64_MAX;
ngtcp2_duration pto = conn_compute_pto(conn, &conn->pktns);
ngtcp2_scid *scid;
ngtcp2_dcid *dcid;
@@ -10922,15 +10928,13 @@ ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
if (!ngtcp2_pq_empty(&conn->scid.used)) {
scid = ngtcp2_struct_of(ngtcp2_pq_top(&conn->scid.used), ngtcp2_scid, pe);
if (scid->retired_ts != UINT64_MAX) {
- t = scid->retired_ts + pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, scid->retired_ts + pto);
}
}
if (ngtcp2_ringbuf_len(&conn->dcid.retired.rb)) {
dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, 0);
- t = dcid->retired_ts + pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, dcid->retired_ts + pto);
}
if (conn->dcid.current.cid.datalen) {
@@ -10941,15 +10945,13 @@ ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
assert(dcid->cid.datalen);
assert(dcid->bound_ts != UINT64_MAX);
- t = dcid->bound_ts + 3 * pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, dcid->bound_ts + 3 * pto);
}
}
if (conn->server && conn->early.ckm &&
conn->early.discard_started_ts != UINT64_MAX) {
- t = conn->early.discard_started_ts + 3 * pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, conn->early.discard_started_ts + 3 * pto);
}
return res;
@@ -10978,19 +10980,13 @@ static ngtcp2_tstamp conn_handshake_expiry(ngtcp2_conn *conn) {
}
ngtcp2_tstamp ngtcp2_conn_get_expiry(ngtcp2_conn *conn) {
- ngtcp2_tstamp t1 = ngtcp2_conn_loss_detection_expiry(conn);
- ngtcp2_tstamp t2 = ngtcp2_conn_ack_delay_expiry(conn);
- ngtcp2_tstamp t3 = ngtcp2_conn_internal_expiry(conn);
- ngtcp2_tstamp t4 = ngtcp2_conn_lost_pkt_expiry(conn);
- ngtcp2_tstamp t5 = conn_keep_alive_expiry(conn);
- ngtcp2_tstamp t6 = conn_handshake_expiry(conn);
- ngtcp2_tstamp t7 = ngtcp2_conn_get_idle_expiry(conn);
- ngtcp2_tstamp res = ngtcp2_min(t1, t2);
- res = ngtcp2_min(res, t3);
- res = ngtcp2_min(res, t4);
- res = ngtcp2_min(res, t5);
- res = ngtcp2_min(res, t6);
- res = ngtcp2_min(res, t7);
+ ngtcp2_tstamp res = ngtcp2_min_uint64(ngtcp2_conn_loss_detection_expiry(conn),
+ ngtcp2_conn_ack_delay_expiry(conn));
+ res = ngtcp2_min_uint64(res, ngtcp2_conn_internal_expiry(conn));
+ res = ngtcp2_min_uint64(res, ngtcp2_conn_lost_pkt_expiry(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);
}
@@ -11734,19 +11730,24 @@ ngtcp2_ssize ngtcp2_conn_writev_stream_versioned(
return NGTCP2_ERR_INVALID_ARGUMENT;
}
- if ((uint64_t)datalen > NGTCP2_MAX_VARINT - strm->tx.offset ||
- (uint64_t)datalen > NGTCP2_MAX_VARINT - conn->tx.offset) {
- return NGTCP2_ERR_INVALID_ARGUMENT;
- }
+ if (datalen == 0 && !(flags & NGTCP2_WRITE_STREAM_FLAG_FIN) &&
+ (strm->flags & NGTCP2_STRM_FLAG_ANY_SENT)) {
+ pvmsg = NULL;
+ } else {
+ if ((uint64_t)datalen > NGTCP2_MAX_VARINT - strm->tx.offset ||
+ (uint64_t)datalen > NGTCP2_MAX_VARINT - conn->tx.offset) {
+ return NGTCP2_ERR_INVALID_ARGUMENT;
+ }
- vmsg.type = NGTCP2_VMSG_TYPE_STREAM;
- vmsg.stream.strm = strm;
- vmsg.stream.flags = flags;
- vmsg.stream.data = datav;
- vmsg.stream.datacnt = datavcnt;
- vmsg.stream.pdatalen = pdatalen;
+ vmsg.type = NGTCP2_VMSG_TYPE_STREAM;
+ vmsg.stream.strm = strm;
+ vmsg.stream.flags = flags;
+ vmsg.stream.data = datav;
+ vmsg.stream.datacnt = datavcnt;
+ vmsg.stream.pdatalen = pdatalen;
- pvmsg = &vmsg;
+ pvmsg = &vmsg;
+ }
} else {
pvmsg = NULL;
}
@@ -11867,10 +11868,9 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
assert(dest[0] & NGTCP2_HEADER_FORM_BIT);
assert(conn->negotiated_version);
- if (ngtcp2_pkt_get_type_long(conn->negotiated_version, dest[0]) ==
- NGTCP2_PKT_INITIAL) {
- /* We have added padding already, but in that case, there is no
- space left to write 1RTT packet. */
+ if (nwrite < NGTCP2_MAX_UDP_PAYLOAD_SIZE &&
+ ngtcp2_pkt_get_type_long(conn->negotiated_version, dest[0]) ==
+ NGTCP2_PKT_INITIAL) {
wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
}
@@ -11931,14 +11931,12 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
dest += nwrite;
destlen -= (size_t)nwrite;
- if (conn->in_pktns && nwrite > 0) {
+ if (res < NGTCP2_MAX_UDP_PAYLOAD_SIZE && conn->in_pktns && nwrite > 0) {
it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
if (!ngtcp2_ksl_it_end(&it)) {
rtbent = ngtcp2_ksl_it_get(&it);
if (rtbent->hd.pkt_num != prev_in_pkt_num &&
(rtbent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
- /* We have added padding already, but in that case, there
- is no space left to write 1RTT packet. */
wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
}
}
@@ -12004,8 +12002,8 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
}
/* dest and destlen have already been adjusted in ppe in the first
run. They are adjusted for probe packet later. */
- nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
- wflags, ts);
+ nwrite = conn_write_pkt(conn, pi, dest, destlen, (size_t)res, vmsg,
+ NGTCP2_PKT_1RTT, wflags, ts);
goto fin;
} else {
conn->pkt.require_padding =
@@ -12100,14 +12098,14 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
"transmit probe pkt left=%zu",
conn->pktns.rtb.probe_pkt_left);
- nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
- wflags, ts);
+ nwrite = conn_write_pkt(conn, pi, dest, destlen, (size_t)res, vmsg,
+ NGTCP2_PKT_1RTT, wflags, ts);
goto fin;
}
- nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
- wflags, ts);
+ nwrite = conn_write_pkt(conn, pi, dest, destlen, (size_t)res, vmsg,
+ NGTCP2_PKT_1RTT, wflags, ts);
if (nwrite) {
assert(nwrite != NGTCP2_ERR_NOBUF);
goto fin;
@@ -12326,12 +12324,9 @@ ngtcp2_ssize ngtcp2_conn_write_application_close_pkt(
destlen -= (size_t)nwrite;
}
- if (conn->state != NGTCP2_CS_POST_HANDSHAKE) {
- assert(res);
-
- if (!conn->server || !conn->pktns.crypto.tx.ckm) {
- return res;
- }
+ if (conn->state != NGTCP2_CS_POST_HANDSHAKE &&
+ (!conn->server || !conn->pktns.crypto.tx.ckm)) {
+ return res;
}
assert(conn->pktns.crypto.tx.ckm);
@@ -12393,6 +12388,16 @@ void ngtcp2_ccerr_set_liberr(ngtcp2_ccerr *ccerr, int liberr,
reasonlen);
return;
+ case NGTCP2_ERR_DROP_CONN:
+ ccerr_init(ccerr, NGTCP2_CCERR_TYPE_DROP_CONN, NGTCP2_NO_ERROR, reason,
+ reasonlen);
+
+ return;
+ case NGTCP2_ERR_RETRY:
+ ccerr_init(ccerr, NGTCP2_CCERR_TYPE_RETRY, NGTCP2_NO_ERROR, reason,
+ reasonlen);
+
+ return;
};
ngtcp2_ccerr_set_transport_error(
@@ -13597,20 +13602,11 @@ size_t ngtcp2_conn_get_send_quantum(ngtcp2_conn *conn) {
}
int ngtcp2_conn_track_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
- size_t i;
-
if (conn->dcid.retire_unacked.len >=
ngtcp2_arraylen(conn->dcid.retire_unacked.seqs)) {
return NGTCP2_ERR_CONNECTION_ID_LIMIT;
}
- /* Make sure that we do not have a duplicate */
- for (i = 0; i < conn->dcid.retire_unacked.len; ++i) {
- if (conn->dcid.retire_unacked.seqs[i] == seq) {
- ngtcp2_unreachable();
- }
- }
-
conn->dcid.retire_unacked.seqs[conn->dcid.retire_unacked.len++] = seq;
return 0;
@@ -13635,6 +13631,18 @@ void ngtcp2_conn_untrack_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
}
}
+int ngtcp2_conn_check_retired_dcid_tracked(ngtcp2_conn *conn, uint64_t seq) {
+ size_t i;
+
+ for (i = 0; i < conn->dcid.retire_unacked.len; ++i) {
+ if (conn->dcid.retire_unacked.seqs[i] == seq) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
size_t ngtcp2_conn_get_stream_loss_count(ngtcp2_conn *conn, int64_t stream_id) {
ngtcp2_strm *strm = ngtcp2_conn_find_stream(conn, stream_id);
@@ -13652,45 +13660,6 @@ void ngtcp2_path_challenge_entry_init(ngtcp2_path_challenge_entry *pcent,
memcpy(pcent->data, data, sizeof(pcent->data));
}
-void ngtcp2_settings_default_versioned(int settings_version,
- ngtcp2_settings *settings) {
- (void)settings_version;
-
- memset(settings, 0, sizeof(*settings));
- settings->cc_algo = NGTCP2_CC_ALGO_CUBIC;
- settings->initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT;
- settings->ack_thresh = 2;
- settings->max_tx_udp_payload_size = 1500 - 48;
- settings->handshake_timeout = UINT64_MAX;
-}
-
-void ngtcp2_transport_params_default_versioned(
- int transport_params_version, ngtcp2_transport_params *params) {
- size_t len;
-
- switch (transport_params_version) {
- case NGTCP2_TRANSPORT_PARAMS_VERSION:
- len = sizeof(*params);
-
- break;
- default:
- ngtcp2_unreachable();
- }
-
- memset(params, 0, len);
-
- switch (transport_params_version) {
- case NGTCP2_TRANSPORT_PARAMS_VERSION:
- params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
- params->active_connection_id_limit =
- NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
- params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
- params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
-
- break;
- }
-}
-
/* The functions prefixed with ngtcp2_pkt_ are usually put inside
ngtcp2_pkt.c. This function uses encryption construct and uses
test data defined only in ngtcp2_conn_test.c, so it is written
@@ -13726,7 +13695,7 @@ ngtcp2_ssize ngtcp2_pkt_write_connection_close(
cc.encrypt = encrypt;
cc.hp_mask = hp_mask;
- ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
+ ngtcp2_ppe_init(&ppe, dest, destlen, 0, &cc);
rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
if (rv != 0) {
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h
index 4ed6787..1172816 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h
@@ -65,9 +65,6 @@ typedef enum {
NGTCP2_CS_DRAINING,
} ngtcp2_conn_state;
-/* NGTCP2_MAX_STREAMS is the maximum number of streams. */
-#define NGTCP2_MAX_STREAMS (1LL << 60)
-
/* NGTCP2_MAX_NUM_BUFFED_RX_PKTS is the maximum number of buffered
reordered packets. */
#define NGTCP2_MAX_NUM_BUFFED_RX_PKTS 4
@@ -121,12 +118,18 @@ typedef enum {
/* NGTCP2_WRITE_PKT_FLAG_NONE indicates that no flag is set. */
#define NGTCP2_WRITE_PKT_FLAG_NONE 0x00u
/* NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING indicates that packet other
- than Initial packet should be padded. Initial packet might be
- padded based on QUIC requirement regardless of this flag. */
+ than Initial packet should be padded so that UDP datagram payload
+ is at least NGTCP2_MAX_UDP_PAYLOAD_SIZE bytes. Initial packet
+ might be padded based on QUIC requirement regardless of this
+ flag. */
#define NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING 0x01u
/* NGTCP2_WRITE_PKT_FLAG_MORE indicates that more frames might come
and it should be encoded into the current packet. */
#define NGTCP2_WRITE_PKT_FLAG_MORE 0x02u
+/* NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL is just like
+ NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING, but it requests to add
+ padding to the full UDP datagram payload size. */
+#define NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL 0x04u
/*
* ngtcp2_max_frame is defined so that it covers the largest ACK
@@ -974,6 +977,12 @@ int ngtcp2_conn_track_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq);
void ngtcp2_conn_untrack_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq);
/*
+ * ngtcp2_conn_check_retired_dcid_tracked returns nonzero if |seq| has
+ * already been tracked.
+ */
+int ngtcp2_conn_check_retired_dcid_tracked(ngtcp2_conn *conn, uint64_t seq);
+
+/*
* ngtcp2_conn_server_negotiate_version negotiates QUIC version. It
* is compatible version negotiation. It returns the negotiated QUIC
* version. This function must not be called by client.
@@ -1156,4 +1165,16 @@ int ngtcp2_conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
ngtcp2_tstamp ts, ngtcp2_duration ack_delay,
uint64_t ack_delay_exponent);
+/*
+ * ngtcp2_conn_discard_initial_state discards state for Initial packet
+ * number space.
+ */
+void ngtcp2_conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts);
+
+/*
+ * ngtcp2_conn_discard_handshake_state discards state for Handshake
+ * packet number space.
+ */
+void ngtcp2_conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts);
+
#endif /* NGTCP2_CONN_H */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c
deleted file mode 100644
index eb85687..0000000
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ngtcp2
- *
- * Copyright (c) 2023 ngtcp2 contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ngtcp2_conversion.h"
-
-#include <string.h>
-#include <assert.h>
-
-static void transport_params_copy(int transport_params_version,
- ngtcp2_transport_params *dest,
- const ngtcp2_transport_params *src) {
- assert(transport_params_version != NGTCP2_TRANSPORT_PARAMS_VERSION);
-
- switch (transport_params_version) {
- case NGTCP2_TRANSPORT_PARAMS_V1:
- memcpy(dest, src,
- offsetof(ngtcp2_transport_params, version_info_present) +
- sizeof(src->version_info_present));
-
- break;
- }
-}
-
-const ngtcp2_transport_params *
-ngtcp2_transport_params_convert_to_latest(ngtcp2_transport_params *dest,
- int transport_params_version,
- const ngtcp2_transport_params *src) {
- if (transport_params_version == NGTCP2_TRANSPORT_PARAMS_VERSION) {
- return src;
- }
-
- ngtcp2_transport_params_default(dest);
-
- transport_params_copy(transport_params_version, dest, src);
-
- return dest;
-}
-
-void ngtcp2_transport_params_convert_to_old(
- int transport_params_version, ngtcp2_transport_params *dest,
- const ngtcp2_transport_params *src) {
- assert(transport_params_version != NGTCP2_TRANSPORT_PARAMS_VERSION);
-
- transport_params_copy(transport_params_version, dest, src);
-}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c
index 0a3ecf6..9f61791 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.c
@@ -27,11 +27,7 @@
#include <string.h>
#include <assert.h>
-#include "ngtcp2_str.h"
-#include "ngtcp2_conv.h"
-#include "ngtcp2_conn.h"
#include "ngtcp2_net.h"
-#include "ngtcp2_conversion.h"
int ngtcp2_crypto_km_new(ngtcp2_crypto_km **pckm, const uint8_t *secret,
size_t secretlen,
@@ -85,6 +81,16 @@ void ngtcp2_crypto_km_del(ngtcp2_crypto_km *ckm, const ngtcp2_mem *mem) {
return;
}
+ if (ckm->secret.len) {
+#ifdef WIN32
+ SecureZeroMemory(ckm->secret.base, ckm->secret.len);
+#elif defined(HAVE_EXPLICIT_BZERO)
+ explicit_bzero(ckm->secret.base, ckm->secret.len);
+#elif defined(HAVE_MEMSET_S)
+ memset_s(ckm->secret.base, ckm->secret.len, 0, ckm->secret.len);
+#endif /* HAVE_MEMSET_S */
+ }
+
ngtcp2_mem_free(mem, ckm);
}
@@ -102,808 +108,3 @@ void ngtcp2_crypto_create_nonce(uint8_t *dest, const uint8_t *iv, size_t ivlen,
dest[ivlen - 8 + i] ^= ((uint8_t *)&n)[i];
}
}
-
-/*
- * varint_paramlen returns the length of a single transport parameter
- * which has variable integer in its parameter.
- */
-static size_t varint_paramlen(ngtcp2_transport_param_id id, uint64_t param) {
- size_t valuelen = ngtcp2_put_uvarintlen(param);
- return ngtcp2_put_uvarintlen(id) + ngtcp2_put_uvarintlen(valuelen) + valuelen;
-}
-
-/*
- * write_varint_param writes parameter |id| of the given |value| in
- * varint encoding. It returns p + the number of bytes written.
- */
-static uint8_t *write_varint_param(uint8_t *p, ngtcp2_transport_param_id id,
- uint64_t value) {
- p = ngtcp2_put_uvarint(p, id);
- p = ngtcp2_put_uvarint(p, ngtcp2_put_uvarintlen(value));
- return ngtcp2_put_uvarint(p, value);
-}
-
-/*
- * zero_paramlen returns the length of a single transport parameter
- * which has zero length value in its parameter.
- */
-static size_t zero_paramlen(ngtcp2_transport_param_id id) {
- return ngtcp2_put_uvarintlen(id) + 1;
-}
-
-/*
- * write_zero_param writes parameter |id| that has zero length value.
- * It returns p + the number of bytes written.
- */
-static uint8_t *write_zero_param(uint8_t *p, ngtcp2_transport_param_id id) {
- p = ngtcp2_put_uvarint(p, id);
- *p++ = 0;
-
- return p;
-}
-
-/*
- * cid_paramlen returns the length of a single transport parameter
- * which has |cid| as value.
- */
-static size_t cid_paramlen(ngtcp2_transport_param_id id,
- const ngtcp2_cid *cid) {
- return ngtcp2_put_uvarintlen(id) + ngtcp2_put_uvarintlen(cid->datalen) +
- cid->datalen;
-}
-
-/*
- * write_cid_param writes parameter |id| of the given |cid|. It
- * returns p + the number of bytes written.
- */
-static uint8_t *write_cid_param(uint8_t *p, ngtcp2_transport_param_id id,
- const ngtcp2_cid *cid) {
- assert(cid->datalen == 0 || cid->datalen >= NGTCP2_MIN_CIDLEN);
- assert(cid->datalen <= NGTCP2_MAX_CIDLEN);
-
- p = ngtcp2_put_uvarint(p, id);
- p = ngtcp2_put_uvarint(p, cid->datalen);
- if (cid->datalen) {
- p = ngtcp2_cpymem(p, cid->data, cid->datalen);
- }
- return p;
-}
-
-static const uint8_t empty_address[16];
-
-ngtcp2_ssize ngtcp2_transport_params_encode_versioned(
- uint8_t *dest, size_t destlen, int transport_params_version,
- const ngtcp2_transport_params *params) {
- uint8_t *p;
- size_t len = 0;
- /* For some reason, gcc 7.3.0 requires this initialization. */
- size_t preferred_addrlen = 0;
- size_t version_infolen = 0;
- const ngtcp2_sockaddr_in *sa_in;
- const ngtcp2_sockaddr_in6 *sa_in6;
- ngtcp2_transport_params paramsbuf;
-
- params = ngtcp2_transport_params_convert_to_latest(
- &paramsbuf, transport_params_version, params);
-
- if (params->original_dcid_present) {
- len +=
- cid_paramlen(NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID,
- &params->original_dcid);
- }
-
- if (params->stateless_reset_token_present) {
- len += ngtcp2_put_uvarintlen(NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN) +
- ngtcp2_put_uvarintlen(NGTCP2_STATELESS_RESET_TOKENLEN) +
- NGTCP2_STATELESS_RESET_TOKENLEN;
- }
-
- if (params->preferred_addr_present) {
- assert(params->preferred_addr.cid.datalen >= NGTCP2_MIN_CIDLEN);
- assert(params->preferred_addr.cid.datalen <= NGTCP2_MAX_CIDLEN);
- preferred_addrlen = 4 /* ipv4Address */ + 2 /* ipv4Port */ +
- 16 /* ipv6Address */ + 2 /* ipv6Port */
- + 1 + params->preferred_addr.cid.datalen /* CID */ +
- NGTCP2_STATELESS_RESET_TOKENLEN;
- len += ngtcp2_put_uvarintlen(NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS) +
- ngtcp2_put_uvarintlen(preferred_addrlen) + preferred_addrlen;
- }
- if (params->retry_scid_present) {
- len += cid_paramlen(NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID,
- &params->retry_scid);
- }
-
- if (params->initial_scid_present) {
- len += cid_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID,
- &params->initial_scid);
- }
-
- if (params->initial_max_stream_data_bidi_local) {
- len += varint_paramlen(
- NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
- params->initial_max_stream_data_bidi_local);
- }
- if (params->initial_max_stream_data_bidi_remote) {
- len += varint_paramlen(
- NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,
- params->initial_max_stream_data_bidi_remote);
- }
- if (params->initial_max_stream_data_uni) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI,
- params->initial_max_stream_data_uni);
- }
- if (params->initial_max_data) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA,
- params->initial_max_data);
- }
- if (params->initial_max_streams_bidi) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI,
- params->initial_max_streams_bidi);
- }
- if (params->initial_max_streams_uni) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI,
- params->initial_max_streams_uni);
- }
- if (params->max_udp_payload_size !=
- NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE,
- params->max_udp_payload_size);
- }
- if (params->ack_delay_exponent != NGTCP2_DEFAULT_ACK_DELAY_EXPONENT) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT,
- params->ack_delay_exponent);
- }
- if (params->disable_active_migration) {
- len += zero_paramlen(NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION);
- }
- if (params->max_ack_delay != NGTCP2_DEFAULT_MAX_ACK_DELAY) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY,
- params->max_ack_delay / NGTCP2_MILLISECONDS);
- }
- if (params->max_idle_timeout) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT,
- params->max_idle_timeout / NGTCP2_MILLISECONDS);
- }
- if (params->active_connection_id_limit &&
- params->active_connection_id_limit !=
- NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT,
- params->active_connection_id_limit);
- }
- if (params->max_datagram_frame_size) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE,
- params->max_datagram_frame_size);
- }
- if (params->grease_quic_bit) {
- len += zero_paramlen(NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT);
- }
- if (params->version_info_present) {
- version_infolen =
- sizeof(uint32_t) + params->version_info.available_versionslen;
- len += ngtcp2_put_uvarintlen(NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION) +
- ngtcp2_put_uvarintlen(version_infolen) + version_infolen;
- }
-
- if (dest == NULL && destlen == 0) {
- return (ngtcp2_ssize)len;
- }
-
- if (destlen < len) {
- return NGTCP2_ERR_NOBUF;
- }
-
- p = dest;
-
- if (params->original_dcid_present) {
- p = write_cid_param(
- p, NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID,
- &params->original_dcid);
- }
-
- if (params->stateless_reset_token_present) {
- p = ngtcp2_put_uvarint(p, NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN);
- p = ngtcp2_put_uvarint(p, sizeof(params->stateless_reset_token));
- p = ngtcp2_cpymem(p, params->stateless_reset_token,
- sizeof(params->stateless_reset_token));
- }
-
- if (params->preferred_addr_present) {
- p = ngtcp2_put_uvarint(p, NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS);
- p = ngtcp2_put_uvarint(p, preferred_addrlen);
-
- if (params->preferred_addr.ipv4_present) {
- sa_in = &params->preferred_addr.ipv4;
- p = ngtcp2_cpymem(p, &sa_in->sin_addr, sizeof(sa_in->sin_addr));
- p = ngtcp2_put_uint16(p, sa_in->sin_port);
- } else {
- p = ngtcp2_cpymem(p, empty_address, sizeof(sa_in->sin_addr));
- p = ngtcp2_put_uint16(p, 0);
- }
-
- if (params->preferred_addr.ipv6_present) {
- sa_in6 = &params->preferred_addr.ipv6;
- p = ngtcp2_cpymem(p, &sa_in6->sin6_addr, sizeof(sa_in6->sin6_addr));
- p = ngtcp2_put_uint16(p, sa_in6->sin6_port);
- } else {
- p = ngtcp2_cpymem(p, empty_address, sizeof(sa_in6->sin6_addr));
- p = ngtcp2_put_uint16(p, 0);
- }
-
- *p++ = (uint8_t)params->preferred_addr.cid.datalen;
- if (params->preferred_addr.cid.datalen) {
- p = ngtcp2_cpymem(p, params->preferred_addr.cid.data,
- params->preferred_addr.cid.datalen);
- }
- p = ngtcp2_cpymem(p, params->preferred_addr.stateless_reset_token,
- sizeof(params->preferred_addr.stateless_reset_token));
- }
-
- if (params->retry_scid_present) {
- p = write_cid_param(p, NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID,
- &params->retry_scid);
- }
-
- if (params->initial_scid_present) {
- p = write_cid_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID,
- &params->initial_scid);
- }
-
- if (params->initial_max_stream_data_bidi_local) {
- p = write_varint_param(
- p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
- params->initial_max_stream_data_bidi_local);
- }
-
- if (params->initial_max_stream_data_bidi_remote) {
- p = write_varint_param(
- p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,
- params->initial_max_stream_data_bidi_remote);
- }
-
- if (params->initial_max_stream_data_uni) {
- p = write_varint_param(p,
- NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI,
- params->initial_max_stream_data_uni);
- }
-
- if (params->initial_max_data) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA,
- params->initial_max_data);
- }
-
- if (params->initial_max_streams_bidi) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI,
- params->initial_max_streams_bidi);
- }
-
- if (params->initial_max_streams_uni) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI,
- params->initial_max_streams_uni);
- }
-
- if (params->max_udp_payload_size !=
- NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE,
- params->max_udp_payload_size);
- }
-
- if (params->ack_delay_exponent != NGTCP2_DEFAULT_ACK_DELAY_EXPONENT) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT,
- params->ack_delay_exponent);
- }
-
- if (params->disable_active_migration) {
- p = write_zero_param(p, NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION);
- }
-
- if (params->max_ack_delay != NGTCP2_DEFAULT_MAX_ACK_DELAY) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY,
- params->max_ack_delay / NGTCP2_MILLISECONDS);
- }
-
- if (params->max_idle_timeout) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT,
- params->max_idle_timeout / NGTCP2_MILLISECONDS);
- }
-
- if (params->active_connection_id_limit &&
- params->active_connection_id_limit !=
- NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT,
- params->active_connection_id_limit);
- }
-
- if (params->max_datagram_frame_size) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE,
- params->max_datagram_frame_size);
- }
-
- if (params->grease_quic_bit) {
- p = write_zero_param(p, NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT);
- }
-
- if (params->version_info_present) {
- p = ngtcp2_put_uvarint(p, NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION);
- p = ngtcp2_put_uvarint(p, version_infolen);
- p = ngtcp2_put_uint32be(p, params->version_info.chosen_version);
- if (params->version_info.available_versionslen) {
- p = ngtcp2_cpymem(p, params->version_info.available_versions,
- params->version_info.available_versionslen);
- }
- }
-
- assert((size_t)(p - dest) == len);
-
- return (ngtcp2_ssize)len;
-}
-
-/*
- * decode_varint decodes a single varint from the buffer pointed by
- * |*pp| of length |end - *pp|. If it decodes an integer
- * successfully, it stores the integer in |*pdest|, increment |*pp| by
- * the number of bytes read from |*pp|, and returns 0. Otherwise it
- * returns -1.
- */
-static int decode_varint(uint64_t *pdest, const uint8_t **pp,
- const uint8_t *end) {
- const uint8_t *p = *pp;
- size_t len;
-
- if (p == end) {
- return -1;
- }
-
- len = ngtcp2_get_uvarintlen(p);
- if ((uint64_t)(end - p) < len) {
- return -1;
- }
-
- *pp = ngtcp2_get_uvarint(pdest, p);
-
- return 0;
-}
-
-/*
- * decode_varint_param decodes length prefixed value from the buffer
- * pointed by |*pp| of length |end - *pp|. The length and value are
- * encoded in varint form. If it decodes a value successfully, it
- * stores the value in |*pdest|, increment |*pp| by the number of
- * bytes read from |*pp|, and returns 0. Otherwise it returns -1.
- */
-static int decode_varint_param(uint64_t *pdest, const uint8_t **pp,
- const uint8_t *end) {
- const uint8_t *p = *pp;
- uint64_t valuelen;
-
- if (decode_varint(&valuelen, &p, end) != 0) {
- return -1;
- }
-
- if (p == end) {
- return -1;
- }
-
- if ((uint64_t)(end - p) < valuelen) {
- return -1;
- }
-
- if (ngtcp2_get_uvarintlen(p) != valuelen) {
- return -1;
- }
-
- *pp = ngtcp2_get_uvarint(pdest, p);
-
- return 0;
-}
-
-/*
- * decode_zero_param decodes zero length value from the buffer pointed
- * by |*pp| of length |end - *pp|. The length is encoded in varint
- * form. If it decodes zero length value successfully, it increments
- * |*pp| by 1, and returns 0. Otherwise it returns -1.
- */
-static int decode_zero_param(const uint8_t **pp, const uint8_t *end) {
- if (*pp == end || **pp != 0) {
- return -1;
- }
-
- ++*pp;
-
- return 0;
-}
-
-/*
- * decode_cid_param decodes length prefixed ngtcp2_cid from the buffer
- * pointed by |*pp| of length |end - *pp|. The length is encoded in
- * varint form. If it decodes a value successfully, it stores the
- * value in |*pdest|, increment |*pp| by the number of read from
- * |*pp|, and returns the number of bytes read. Otherwise it returns
- * the one of the negative error code:
- *
- * NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM
- * Could not decode Connection ID.
- */
-static int decode_cid_param(ngtcp2_cid *pdest, const uint8_t **pp,
- const uint8_t *end) {
- const uint8_t *p = *pp;
- uint64_t valuelen;
-
- if (decode_varint(&valuelen, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
-
- if ((valuelen != 0 && valuelen < NGTCP2_MIN_CIDLEN) ||
- valuelen > NGTCP2_MAX_CIDLEN || (size_t)(end - p) < valuelen) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
-
- ngtcp2_cid_init(pdest, p, (size_t)valuelen);
-
- p += valuelen;
-
- *pp = p;
-
- return 0;
-}
-
-int ngtcp2_transport_params_decode_versioned(int transport_params_version,
- ngtcp2_transport_params *dest,
- const uint8_t *data,
- size_t datalen) {
- const uint8_t *p, *end, *lend;
- size_t len;
- uint64_t param_type;
- uint64_t valuelen;
- int rv;
- ngtcp2_sockaddr_in *sa_in;
- ngtcp2_sockaddr_in6 *sa_in6;
- uint32_t version;
- ngtcp2_transport_params *params, paramsbuf;
-
- if (transport_params_version == NGTCP2_TRANSPORT_PARAMS_VERSION) {
- params = dest;
- } else {
- params = &paramsbuf;
- }
-
- /* Set default values */
- memset(params, 0, sizeof(*params));
- params->original_dcid_present = 0;
- params->initial_scid_present = 0;
- params->initial_max_streams_bidi = 0;
- params->initial_max_streams_uni = 0;
- params->initial_max_stream_data_bidi_local = 0;
- params->initial_max_stream_data_bidi_remote = 0;
- params->initial_max_stream_data_uni = 0;
- params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
- params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
- params->stateless_reset_token_present = 0;
- params->preferred_addr_present = 0;
- params->disable_active_migration = 0;
- params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
- params->max_idle_timeout = 0;
- params->active_connection_id_limit =
- NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
- params->retry_scid_present = 0;
- params->max_datagram_frame_size = 0;
- memset(&params->retry_scid, 0, sizeof(params->retry_scid));
- memset(&params->initial_scid, 0, sizeof(params->initial_scid));
- memset(&params->original_dcid, 0, sizeof(params->original_dcid));
- params->version_info_present = 0;
-
- p = data;
- end = data + datalen;
-
- for (; (size_t)(end - p) >= 2;) {
- if (decode_varint(&param_type, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
-
- switch (param_type) {
- case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:
- if (decode_varint_param(&params->initial_max_stream_data_bidi_local, &p,
- end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE:
- if (decode_varint_param(&params->initial_max_stream_data_bidi_remote, &p,
- end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI:
- if (decode_varint_param(&params->initial_max_stream_data_uni, &p, end) !=
- 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA:
- if (decode_varint_param(&params->initial_max_data, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI:
- if (decode_varint_param(&params->initial_max_streams_bidi, &p, end) !=
- 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (params->initial_max_streams_bidi > NGTCP2_MAX_STREAMS) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI:
- if (decode_varint_param(&params->initial_max_streams_uni, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (params->initial_max_streams_uni > NGTCP2_MAX_STREAMS) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT:
- if (decode_varint_param(&params->max_idle_timeout, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- params->max_idle_timeout *= NGTCP2_MILLISECONDS;
- break;
- case NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE:
- if (decode_varint_param(&params->max_udp_payload_size, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN:
- if (decode_varint(&valuelen, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if ((size_t)valuelen != sizeof(params->stateless_reset_token)) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if ((size_t)(end - p) < sizeof(params->stateless_reset_token)) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
-
- p = ngtcp2_get_bytes(params->stateless_reset_token, p,
- sizeof(params->stateless_reset_token));
- params->stateless_reset_token_present = 1;
-
- break;
- case NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT:
- if (decode_varint_param(&params->ack_delay_exponent, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (params->ack_delay_exponent > 20) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS:
- if (decode_varint(&valuelen, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if ((size_t)(end - p) < valuelen) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- len = 4 /* ipv4Address */ + 2 /* ipv4Port */ + 16 /* ipv6Address */ +
- 2 /* ipv6Port */
- + 1 /* cid length */ + NGTCP2_STATELESS_RESET_TOKENLEN;
- if (valuelen < len) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
-
- sa_in = &params->preferred_addr.ipv4;
-
- p = ngtcp2_get_bytes(&sa_in->sin_addr, p, sizeof(sa_in->sin_addr));
- p = ngtcp2_get_uint16be(&sa_in->sin_port, p);
-
- if (sa_in->sin_port || memcmp(empty_address, &sa_in->sin_addr,
- sizeof(sa_in->sin_addr)) != 0) {
- sa_in->sin_family = NGTCP2_AF_INET;
- params->preferred_addr.ipv4_present = 1;
- }
-
- sa_in6 = &params->preferred_addr.ipv6;
-
- p = ngtcp2_get_bytes(&sa_in6->sin6_addr, p, sizeof(sa_in6->sin6_addr));
- p = ngtcp2_get_uint16be(&sa_in6->sin6_port, p);
-
- if (sa_in6->sin6_port || memcmp(empty_address, &sa_in6->sin6_addr,
- sizeof(sa_in6->sin6_addr)) != 0) {
- sa_in6->sin6_family = NGTCP2_AF_INET6;
- params->preferred_addr.ipv6_present = 1;
- }
-
- /* cid */
- params->preferred_addr.cid.datalen = *p++;
- len += params->preferred_addr.cid.datalen;
- if (valuelen != len ||
- params->preferred_addr.cid.datalen > NGTCP2_MAX_CIDLEN ||
- params->preferred_addr.cid.datalen < NGTCP2_MIN_CIDLEN) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (params->preferred_addr.cid.datalen) {
- p = ngtcp2_get_bytes(params->preferred_addr.cid.data, p,
- params->preferred_addr.cid.datalen);
- }
-
- /* stateless reset token */
- p = ngtcp2_get_bytes(
- params->preferred_addr.stateless_reset_token, p,
- sizeof(params->preferred_addr.stateless_reset_token));
- params->preferred_addr_present = 1;
- break;
- case NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION:
- if (decode_zero_param(&p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- params->disable_active_migration = 1;
- break;
- case NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID:
- rv = decode_cid_param(&params->original_dcid, &p, end);
- if (rv != 0) {
- return rv;
- }
- params->original_dcid_present = 1;
- break;
- case NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID:
- rv = decode_cid_param(&params->retry_scid, &p, end);
- if (rv != 0) {
- return rv;
- }
- params->retry_scid_present = 1;
- break;
- case NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID:
- rv = decode_cid_param(&params->initial_scid, &p, end);
- if (rv != 0) {
- return rv;
- }
- params->initial_scid_present = 1;
- break;
- case NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY:
- if (decode_varint_param(&params->max_ack_delay, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (params->max_ack_delay >= 16384) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- params->max_ack_delay *= NGTCP2_MILLISECONDS;
- break;
- case NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT:
- if (decode_varint_param(&params->active_connection_id_limit, &p, end) !=
- 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE:
- if (decode_varint_param(&params->max_datagram_frame_size, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- break;
- case NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT:
- if (decode_zero_param(&p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- params->grease_quic_bit = 1;
- break;
- case NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION:
- if (decode_varint(&valuelen, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if ((size_t)(end - p) < valuelen) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (valuelen < sizeof(uint32_t) || (valuelen & 0x3)) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- p = ngtcp2_get_uint32(&params->version_info.chosen_version, p);
- if (params->version_info.chosen_version == 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if (valuelen > sizeof(uint32_t)) {
- params->version_info.available_versions = (uint8_t *)p;
- params->version_info.available_versionslen =
- (size_t)valuelen - sizeof(uint32_t);
-
- for (lend = p + (valuelen - sizeof(uint32_t)); p != lend;) {
- p = ngtcp2_get_uint32(&version, p);
- if (version == 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- }
- }
- params->version_info_present = 1;
- break;
- default:
- /* Ignore unknown parameter */
- if (decode_varint(&valuelen, &p, end) != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- if ((size_t)(end - p) < valuelen) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- p += valuelen;
- break;
- }
- }
-
- if (end - p != 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
-
- if (transport_params_version != NGTCP2_TRANSPORT_PARAMS_VERSION) {
- ngtcp2_transport_params_convert_to_old(transport_params_version, dest,
- params);
- }
-
- return 0;
-}
-
-static int transport_params_copy_new(ngtcp2_transport_params **pdest,
- const ngtcp2_transport_params *src,
- const ngtcp2_mem *mem) {
- size_t len = sizeof(**pdest);
- ngtcp2_transport_params *dest;
- uint8_t *p;
-
- if (src->version_info_present) {
- len += src->version_info.available_versionslen;
- }
-
- dest = ngtcp2_mem_malloc(mem, len);
- if (dest == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
-
- *dest = *src;
-
- if (src->version_info_present && src->version_info.available_versionslen) {
- p = (uint8_t *)dest + sizeof(*dest);
- memcpy(p, src->version_info.available_versions,
- src->version_info.available_versionslen);
- dest->version_info.available_versions = p;
- }
-
- *pdest = dest;
-
- return 0;
-}
-
-int ngtcp2_transport_params_decode_new(ngtcp2_transport_params **pparams,
- const uint8_t *data, size_t datalen,
- const ngtcp2_mem *mem) {
- int rv;
- ngtcp2_transport_params params;
-
- rv = ngtcp2_transport_params_decode(&params, data, datalen);
- if (rv < 0) {
- return rv;
- }
-
- if (mem == NULL) {
- mem = ngtcp2_mem_default();
- }
-
- return transport_params_copy_new(pparams, &params, mem);
-}
-
-void ngtcp2_transport_params_del(ngtcp2_transport_params *params,
- const ngtcp2_mem *mem) {
- if (params == NULL) {
- return;
- }
-
- if (mem == NULL) {
- mem = ngtcp2_mem_default();
- }
-
- ngtcp2_mem_free(mem, params);
-}
-
-int ngtcp2_transport_params_copy_new(ngtcp2_transport_params **pdest,
- const ngtcp2_transport_params *src,
- const ngtcp2_mem *mem) {
- if (src == NULL) {
- *pdest = NULL;
- return 0;
- }
-
- return transport_params_copy_new(pdest, src, mem);
-}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h
index b78429b..c561723 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_crypto.h
@@ -41,33 +41,6 @@
/* NGTCP2_MAX_AEAD_OVERHEAD is expected maximum AEAD overhead. */
#define NGTCP2_MAX_AEAD_OVERHEAD 16
-/* ngtcp2_transport_param_id is the registry of QUIC transport
- parameter ID. */
-typedef uint64_t ngtcp2_transport_param_id;
-
-#define NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID 0x00
-#define NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT 0x01
-#define NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN 0x02
-#define NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE 0x03
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA 0x04
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE 0x06
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI 0x07
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI 0x08
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI 0x09
-#define NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT 0x0a
-#define NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY 0x0b
-#define NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION 0x0c
-#define NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS 0x0d
-#define NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT 0x0e
-#define NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID 0x0f
-#define NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID 0x10
-/* https://datatracker.ietf.org/doc/html/rfc9221 */
-#define NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE 0x20
-#define NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT 0x2ab2
-/* https://datatracker.ietf.org/doc/html/rfc9368 */
-#define NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION 0x11
-
/* NGTCP2_CRYPTO_KM_FLAG_NONE indicates that no flag is set. */
#define NGTCP2_CRYPTO_KM_FLAG_NONE 0x00u
/* NGTCP2_CRYPTO_KM_FLAG_KEY_PHASE_ONE is set if key phase bit is
@@ -127,21 +100,4 @@ typedef struct ngtcp2_crypto_cc {
void ngtcp2_crypto_create_nonce(uint8_t *dest, const uint8_t *iv, size_t ivlen,
int64_t pkt_num);
-/*
- * ngtcp2_transport_params_copy_new makes a copy of |src|, and assigns
- * it to |*pdest|. If |src| is NULL, NULL is assigned to |*pdest|.
- *
- * Caller is responsible to call ngtcp2_transport_params_del to free
- * the memory assigned to |*pdest|.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGTCP2_ERR_NOMEM
- * Out of memory.
- */
-int ngtcp2_transport_params_copy_new(ngtcp2_transport_params **pdest,
- const ngtcp2_transport_params *src,
- const ngtcp2_mem *mem);
-
#endif /* NGTCP2_CRYPTO_H */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
index 28d3461..8974c86 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
@@ -55,4 +55,40 @@
*/
#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; }
+
+ngtcp2_max_def(int8, int8_t);
+ngtcp2_max_def(int16, int16_t);
+ngtcp2_max_def(int32, int32_t);
+ngtcp2_max_def(int64, int64_t);
+ngtcp2_max_def(uint8, uint8_t);
+ngtcp2_max_def(uint16, uint16_t);
+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; }
+
+ngtcp2_min_def(int8, int8_t);
+ngtcp2_min_def(int16, int16_t);
+ngtcp2_min_def(int32, int32_t);
+ngtcp2_min_def(int64, int64_t);
+ngtcp2_min_def(uint8, uint8_t);
+ngtcp2_min_def(uint16, uint16_t);
+ngtcp2_min_def(uint32, uint32_t);
+ngtcp2_min_def(uint64, uint64_t);
+ngtcp2_min_def(size, size_t);
+
#endif /* NGTCP2_MACRO_H */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c
index 1687ff2..f4ceb32 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c
@@ -2208,7 +2208,7 @@ ngtcp2_pkt_write_stateless_reset(uint8_t *dest, size_t destlen,
p = dest;
- randlen = ngtcp2_min(destlen - NGTCP2_STATELESS_RESET_TOKENLEN, randlen);
+ randlen = ngtcp2_min_size(destlen - NGTCP2_STATELESS_RESET_TOKENLEN, randlen);
p = ngtcp2_cpymem(p, rand, randlen);
p = ngtcp2_cpymem(p, stateless_reset_token, NGTCP2_STATELESS_RESET_TOKENLEN);
@@ -2384,21 +2384,21 @@ size_t ngtcp2_pkt_stream_max_datalen(int64_t stream_id, uint64_t offset,
#if SIZE_MAX > UINT32_MAX
len = ngtcp2_min(len, 4611686018427387903lu);
#endif /* SIZE_MAX > UINT32_MAX */
- return (size_t)ngtcp2_min(len, (uint64_t)(left - 8));
+ return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 8));
}
if (left > 4 + 16383 && len > 16383) {
len = ngtcp2_min(len, 1073741823);
- return (size_t)ngtcp2_min(len, (uint64_t)(left - 4));
+ return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 4));
}
if (left > 2 + 63 && len > 63) {
len = ngtcp2_min(len, 16383);
- return (size_t)ngtcp2_min(len, (uint64_t)(left - 2));
+ return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 2));
}
len = ngtcp2_min(len, 63);
- return (size_t)ngtcp2_min(len, (uint64_t)(left - 1));
+ return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 1));
}
size_t ngtcp2_pkt_crypto_max_datalen(uint64_t offset, size_t len, size_t left) {
@@ -2416,21 +2416,21 @@ size_t ngtcp2_pkt_crypto_max_datalen(uint64_t offset, size_t len, size_t left) {
#if SIZE_MAX > UINT32_MAX
len = ngtcp2_min(len, 4611686018427387903lu);
#endif /* SIZE_MAX > UINT32_MAX */
- return ngtcp2_min(len, left - 8);
+ return ngtcp2_min_size(len, left - 8);
}
if (left > 4 + 16383 && len > 16383) {
len = ngtcp2_min(len, 1073741823);
- return ngtcp2_min(len, left - 4);
+ return ngtcp2_min_size(len, left - 4);
}
if (left > 2 + 63 && len > 63) {
len = ngtcp2_min(len, 16383);
- return ngtcp2_min(len, left - 2);
+ return ngtcp2_min_size(len, left - 2);
}
len = ngtcp2_min(len, 63);
- return ngtcp2_min(len, left - 1);
+ return ngtcp2_min_size(len, left - 1);
}
size_t ngtcp2_pkt_datagram_framelen(size_t len) {
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.h
index feec4d3..5f2e448 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.h
@@ -95,9 +95,8 @@
/* NGTCP2_MAX_PKT_NUM is the maximum packet number. */
#define NGTCP2_MAX_PKT_NUM ((int64_t)((1ll << 62) - 1))
-/* NGTCP2_MIN_PKT_EXPANDLEN is the minimum packet size expansion in
- addition to the minimum DCID length to hide/trigger Stateless
- Reset. */
+/* NGTCP2_MIN_PKT_EXPANDLEN is the minimum packet size expansion to
+ hide/trigger Stateless Reset. */
#define NGTCP2_MIN_PKT_EXPANDLEN 22
/* NGTCP2_RETRY_TAGLEN is the length of Retry packet integrity tag. */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c
index 771ef5e..6010e42 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c
@@ -33,7 +33,7 @@
for each probe. */
#define NGTCP2_PMTUD_PROBE_NUM_MAX 3
-static size_t mtu_probes[] = {
+static uint16_t pmtud_default_probes[] = {
1454 - 48, /* The well known MTU used by a domestic optic fiber
service in Japan. */
1390 - 48, /* Typical Tunneled MTU */
@@ -41,10 +41,9 @@ static size_t mtu_probes[] = {
1492 - 48, /* PPPoE */
};
-#define NGTCP2_MTU_PROBESLEN ngtcp2_arraylen(mtu_probes)
-
int ngtcp2_pmtud_new(ngtcp2_pmtud **ppmtud, size_t max_udp_payload_size,
size_t hard_max_udp_payload_size, int64_t tx_pkt_num,
+ const uint16_t *probes, size_t probeslen,
const ngtcp2_mem *mem) {
ngtcp2_pmtud *pmtud = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_pmtud));
@@ -61,11 +60,19 @@ int ngtcp2_pmtud_new(ngtcp2_pmtud **ppmtud, size_t max_udp_payload_size,
pmtud->hard_max_udp_payload_size = hard_max_udp_payload_size;
pmtud->min_fail_udp_payload_size = SIZE_MAX;
- for (; pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN; ++pmtud->mtu_idx) {
- if (mtu_probes[pmtud->mtu_idx] > pmtud->hard_max_udp_payload_size) {
+ if (probeslen) {
+ pmtud->probes = probes;
+ pmtud->probeslen = probeslen;
+ } else {
+ pmtud->probes = pmtud_default_probes;
+ pmtud->probeslen = ngtcp2_arraylen(pmtud_default_probes);
+ }
+
+ for (; pmtud->mtu_idx < pmtud->probeslen; ++pmtud->mtu_idx) {
+ if (pmtud->probes[pmtud->mtu_idx] > pmtud->hard_max_udp_payload_size) {
continue;
}
- if (mtu_probes[pmtud->mtu_idx] > pmtud->max_udp_payload_size) {
+ if (pmtud->probes[pmtud->mtu_idx] > pmtud->max_udp_payload_size) {
break;
}
}
@@ -84,9 +91,9 @@ void ngtcp2_pmtud_del(ngtcp2_pmtud *pmtud) {
}
size_t ngtcp2_pmtud_probelen(ngtcp2_pmtud *pmtud) {
- assert(pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN);
+ assert(pmtud->mtu_idx < pmtud->probeslen);
- return mtu_probes[pmtud->mtu_idx];
+ return pmtud->probes[pmtud->mtu_idx];
}
void ngtcp2_pmtud_probe_sent(ngtcp2_pmtud *pmtud, ngtcp2_duration pto,
@@ -107,19 +114,19 @@ int ngtcp2_pmtud_require_probe(ngtcp2_pmtud *pmtud) {
}
static void pmtud_next_probe(ngtcp2_pmtud *pmtud) {
- assert(pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN);
+ assert(pmtud->mtu_idx < pmtud->probeslen);
++pmtud->mtu_idx;
pmtud->num_pkts_sent = 0;
pmtud->expiry = UINT64_MAX;
- for (; pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN; ++pmtud->mtu_idx) {
- if (mtu_probes[pmtud->mtu_idx] <= pmtud->max_udp_payload_size ||
- mtu_probes[pmtud->mtu_idx] > pmtud->hard_max_udp_payload_size) {
+ for (; pmtud->mtu_idx < pmtud->probeslen; ++pmtud->mtu_idx) {
+ if (pmtud->probes[pmtud->mtu_idx] <= pmtud->max_udp_payload_size ||
+ pmtud->probes[pmtud->mtu_idx] > pmtud->hard_max_udp_payload_size) {
continue;
}
- if (mtu_probes[pmtud->mtu_idx] < pmtud->min_fail_udp_payload_size) {
+ if (pmtud->probes[pmtud->mtu_idx] < pmtud->min_fail_udp_payload_size) {
break;
}
}
@@ -129,9 +136,9 @@ void ngtcp2_pmtud_probe_success(ngtcp2_pmtud *pmtud, size_t payloadlen) {
pmtud->max_udp_payload_size =
ngtcp2_max(pmtud->max_udp_payload_size, payloadlen);
- assert(pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN);
+ assert(pmtud->mtu_idx < pmtud->probeslen);
- if (mtu_probes[pmtud->mtu_idx] > pmtud->max_udp_payload_size) {
+ if (pmtud->probes[pmtud->mtu_idx] > pmtud->max_udp_payload_size) {
return;
}
@@ -149,12 +156,12 @@ void ngtcp2_pmtud_handle_expiry(ngtcp2_pmtud *pmtud, ngtcp2_tstamp ts) {
return;
}
- pmtud->min_fail_udp_payload_size =
- ngtcp2_min(pmtud->min_fail_udp_payload_size, mtu_probes[pmtud->mtu_idx]);
+ pmtud->min_fail_udp_payload_size = ngtcp2_min_size(
+ pmtud->min_fail_udp_payload_size, pmtud->probes[pmtud->mtu_idx]);
pmtud_next_probe(pmtud);
}
int ngtcp2_pmtud_finished(ngtcp2_pmtud *pmtud) {
- return pmtud->mtu_idx >= NGTCP2_MTU_PROBESLEN;
+ return pmtud->mtu_idx >= pmtud->probeslen;
}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.h
index 6b2e691..59876d5 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.h
@@ -58,6 +58,10 @@ typedef struct ngtcp2_pmtud {
/* min_fail_udp_payload_size is the minimum UDP payload size that is
known to fail. */
size_t min_fail_udp_payload_size;
+ /* probes is the array of UDP datagram payload size to probe. */
+ const uint16_t *probes;
+ /* probeslen is the number of probes pointed by probes. */
+ size_t probeslen;
} ngtcp2_pmtud;
/*
@@ -70,6 +74,10 @@ typedef struct ngtcp2_pmtud {
* larger than or equal to all UDP payload probe candidates.
* Therefore, call ngtcp2_pmtud_finished to check this situation.
*
+ * The array pointed by |pmtud_probes| of length |pmtud_probeslen|
+ * specifies UDP datagram payload size to probe. If |pmtud_probeslen|
+ * is zero, the default probes are used.
+ *
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
@@ -78,6 +86,7 @@ typedef struct ngtcp2_pmtud {
*/
int ngtcp2_pmtud_new(ngtcp2_pmtud **ppmtud, size_t max_udp_payload_size,
size_t hard_max_udp_payload_size, int64_t tx_pkt_num,
+ const uint16_t *pmtud_probes, size_t pmtud_probeslen,
const ngtcp2_mem *mem);
/*
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.c
index f7c122b..34363d0 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.c
@@ -29,11 +29,13 @@
#include "ngtcp2_str.h"
#include "ngtcp2_conv.h"
+#include "ngtcp2_macro.h"
void ngtcp2_ppe_init(ngtcp2_ppe *ppe, uint8_t *out, size_t outlen,
- ngtcp2_crypto_cc *cc) {
+ size_t dgram_offset, ngtcp2_crypto_cc *cc) {
ngtcp2_buf_init(&ppe->buf, out, outlen);
+ ppe->dgram_offset = dgram_offset;
ppe->hdlen = 0;
ppe->len_offset = 0;
ppe->pkt_num_offset = 0;
@@ -180,20 +182,6 @@ size_t ngtcp2_ppe_pktlen(ngtcp2_ppe *ppe) {
return ngtcp2_buf_len(&ppe->buf) + cc->aead.max_overhead;
}
-size_t ngtcp2_ppe_padding(ngtcp2_ppe *ppe) {
- ngtcp2_crypto_cc *cc = ppe->cc;
- ngtcp2_buf *buf = &ppe->buf;
- size_t len;
-
- assert(ngtcp2_buf_left(buf) >= cc->aead.max_overhead);
-
- len = ngtcp2_buf_left(buf) - cc->aead.max_overhead;
- memset(buf->last, 0, len);
- buf->last += len;
-
- return len;
-}
-
size_t ngtcp2_ppe_padding_hp_sample(ngtcp2_ppe *ppe) {
ngtcp2_crypto_cc *cc = ppe->cc;
ngtcp2_buf *buf = &ppe->buf;
@@ -220,6 +208,8 @@ size_t ngtcp2_ppe_padding_size(ngtcp2_ppe *ppe, size_t n) {
size_t pktlen = ngtcp2_buf_len(buf) + cc->aead.max_overhead;
size_t len;
+ n = ngtcp2_min_size(n, ngtcp2_buf_cap(buf));
+
if (pktlen >= n) {
return 0;
}
@@ -230,6 +220,29 @@ size_t ngtcp2_ppe_padding_size(ngtcp2_ppe *ppe, size_t n) {
return len;
}
+size_t ngtcp2_ppe_dgram_padding(ngtcp2_ppe *ppe) {
+ return ngtcp2_ppe_dgram_padding_size(ppe, NGTCP2_MAX_UDP_PAYLOAD_SIZE);
+}
+
+size_t ngtcp2_ppe_dgram_padding_size(ngtcp2_ppe *ppe, size_t n) {
+ ngtcp2_crypto_cc *cc = ppe->cc;
+ ngtcp2_buf *buf = &ppe->buf;
+ size_t dgramlen =
+ ppe->dgram_offset + ngtcp2_buf_len(buf) + cc->aead.max_overhead;
+ size_t len;
+
+ n = ngtcp2_min_size(n, ppe->dgram_offset + ngtcp2_buf_cap(buf));
+
+ if (dgramlen >= n) {
+ return 0;
+ }
+
+ len = n - dgramlen;
+ buf->last = ngtcp2_setmem(buf->last, 0, len);
+
+ return len;
+}
+
int ngtcp2_ppe_ensure_hp_sample(ngtcp2_ppe *ppe) {
ngtcp2_buf *buf = &ppe->buf;
return ngtcp2_buf_left(buf) >= (4 - ppe->pkt_numlen) + NGTCP2_HP_SAMPLELEN;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.h
index 2a069ef..2f9275c 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ppe.h
@@ -41,6 +41,9 @@
typedef struct ngtcp2_ppe {
ngtcp2_buf buf;
ngtcp2_crypto_cc *cc;
+ /* dgram_offset is the offset in UDP datagram payload that this QUIC
+ packet is positioned at. */
+ size_t dgram_offset;
/* hdlen is the number of bytes for packet header written in buf. */
size_t hdlen;
/* len_offset is the offset to Length field. */
@@ -61,7 +64,7 @@ typedef struct ngtcp2_ppe {
* ngtcp2_ppe_init initializes |ppe| with the given buffer.
*/
void ngtcp2_ppe_init(ngtcp2_ppe *ppe, uint8_t *out, size_t outlen,
- ngtcp2_crypto_cc *cc);
+ size_t dgram_offset, ngtcp2_crypto_cc *cc);
/*
* ngtcp2_ppe_encode_hd encodes |hd|.
@@ -110,13 +113,26 @@ size_t ngtcp2_ppe_left(ngtcp2_ppe *ppe);
*/
size_t ngtcp2_ppe_pktlen(ngtcp2_ppe *ppe);
-/**
- * @function
+/*
+ * ngtcp2_ppe_dgram_padding is equivalent to call
+ * ngtcp2_ppe_dgram_padding_size(ppe, NGTCP2_MAX_UDP_PAYLOAD_SIZE).
+ * This function should be called just before calling
+ * ngtcp2_ppe_final().
+ *
+ * This function returns the number of bytes padded.
+ */
+size_t ngtcp2_ppe_dgram_padding(ngtcp2_ppe *ppe);
+
+/*
+ * ngtcp2_ppe_dgram_padding_size adds PADDING frame so that the size
+ * of a UDP datagram payload is at least |n| bytes long. If it is
+ * unable to add PADDING in that way, this function still adds PADDING
+ * frame as much as possible. This function should be called just
+ * before calling ngtcp2_ppe_final().
*
- * `ngtcp2_ppe_padding` encodes PADDING frames to the end of the
- * buffer. This function returns the number of bytes padded.
+ * This function returns the number of bytes added as padding.
*/
-size_t ngtcp2_ppe_padding(ngtcp2_ppe *ppe);
+size_t ngtcp2_ppe_dgram_padding_size(ngtcp2_ppe *ppe, size_t n);
/*
* ngtcp2_ppe_padding_hp_sample adds PADDING frame if the current
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pq.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pq.c
index 5e1003d..96cde8f 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pq.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pq.c
@@ -69,7 +69,7 @@ int ngtcp2_pq_push(ngtcp2_pq *pq, ngtcp2_pq_entry *item) {
void *nq;
size_t ncapacity;
- ncapacity = ngtcp2_max(4, (pq->capacity * 2));
+ ncapacity = ngtcp2_max_size(4, pq->capacity * 2);
nq = ngtcp2_mem_realloc(pq->mem, pq->q,
ncapacity * sizeof(ngtcp2_pq_entry *));
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
index b28a882..205ac62 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
@@ -115,9 +115,8 @@ void *ngtcp2_ringbuf_get(ngtcp2_ringbuf *rb, size_t offset);
int ngtcp2_ringbuf_full(ngtcp2_ringbuf *rb);
/* ngtcp2_static_ringbuf_def defines ngtcp2_ringbuf struct wrapper
- which uses a statically allocated buffer that is suitable for a
- usage that does not change buffer size with ngtcp2_ringbuf_resize.
- ngtcp2_ringbuf_free should never be called for rb field. */
+ which uses a statically allocated buffer. ngtcp2_ringbuf_free
+ should never be called for rb field. */
#define ngtcp2_static_ringbuf_def(NAME, NMEMB, SIZE) \
typedef struct ngtcp2_static_ringbuf_##NAME { \
ngtcp2_ringbuf rb; \
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c
index 5cac383..4fa3b83 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c
@@ -149,7 +149,8 @@ static int rob_write_data(ngtcp2_rob *rob, uint64_t offset, const uint8_t *data,
}
}
- n = (size_t)ngtcp2_min((uint64_t)len, d->range.begin + rob->chunk - offset);
+ n = (size_t)ngtcp2_min_uint64((uint64_t)len,
+ d->range.begin + rob->chunk - offset);
memcpy(d->begin + (offset - d->range.begin), data, n);
offset += n;
data += n;
@@ -278,8 +279,9 @@ size_t ngtcp2_rob_data_at(ngtcp2_rob *rob, const uint8_t **pdest,
*pdest = d->begin + (offset - d->range.begin);
- return (size_t)(ngtcp2_min(g->range.begin, d->range.begin + rob->chunk) -
- offset);
+ return (
+ size_t)(ngtcp2_min_uint64(g->range.begin, d->range.begin + rob->chunk) -
+ offset);
}
void ngtcp2_rob_pop(ngtcp2_rob *rob, uint64_t offset, size_t len) {
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
index 5ebdce7..89a0cb5 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
@@ -53,7 +53,6 @@ static void rtb_entry_init(ngtcp2_rtb_entry *ent, const ngtcp2_pkt_hd *hd,
ent->lost_ts = UINT64_MAX;
ent->pktlen = pktlen;
ent->flags = flags;
- ent->next = NULL;
}
int ngtcp2_rtb_entry_objalloc_new(ngtcp2_rtb_entry **pent,
@@ -581,7 +580,8 @@ static int rtb_process_acked_pkt(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
ngtcp2_pmtud_probe_success(conn->pmtud, ent->pktlen);
conn->dcid.current.max_udp_payload_size =
- ngtcp2_max(conn->dcid.current.max_udp_payload_size, ent->pktlen);
+ conn->cstat.max_tx_udp_payload_size =
+ ngtcp2_max(conn->dcid.current.max_udp_payload_size, ent->pktlen);
if (ngtcp2_pmtud_finished(conn->pmtud)) {
ngtcp2_conn_stop_pmtud(conn);
@@ -971,7 +971,7 @@ static int rtb_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat,
if (loss_time == UINT64_MAX) {
loss_time = ent->ts + loss_delay;
} else {
- loss_time = ngtcp2_min(loss_time, ent->ts + loss_delay);
+ loss_time = ngtcp2_min_uint64(loss_time, ent->ts + loss_delay);
}
cstat->loss_time[rtb->pktns_id] = loss_time;
@@ -1049,7 +1049,8 @@ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
congestion_period =
(cstat->smoothed_rtt +
- ngtcp2_max(4 * cstat->rttvar, NGTCP2_GRANULARITY) + max_ack_delay) *
+ ngtcp2_max_uint64(4 * cstat->rttvar, NGTCP2_GRANULARITY) +
+ max_ack_delay) *
NGTCP2_PERSISTENT_CONGESTION_THRESHOLD;
start_ts = ngtcp2_max(rtb->persistent_congestion_start_ts,
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c
new file mode 100644
index 0000000..77a68bd
--- /dev/null
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.c
@@ -0,0 +1,91 @@
+/*
+ * ngtcp2
+ *
+ * Copyright (c) 2024 ngtcp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "ngtcp2_settings.h"
+
+#include <string.h>
+#include <assert.h>
+
+#include "ngtcp2_unreachable.h"
+
+void ngtcp2_settings_default_versioned(int settings_version,
+ ngtcp2_settings *settings) {
+ size_t len = ngtcp2_settingslen_version(settings_version);
+
+ memset(settings, 0, len);
+
+ switch (settings_version) {
+ case NGTCP2_SETTINGS_VERSION:
+ case NGTCP2_SETTINGS_V1:
+ settings->cc_algo = NGTCP2_CC_ALGO_CUBIC;
+ settings->initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT;
+ settings->ack_thresh = 2;
+ settings->max_tx_udp_payload_size = 1500 - 48;
+ settings->handshake_timeout = UINT64_MAX;
+
+ break;
+ }
+}
+
+static void settings_copy(ngtcp2_settings *dest, const ngtcp2_settings *src,
+ int settings_version) {
+ assert(settings_version != NGTCP2_SETTINGS_VERSION);
+
+ memcpy(dest, src, ngtcp2_settingslen_version(settings_version));
+}
+
+const ngtcp2_settings *
+ngtcp2_settings_convert_to_latest(ngtcp2_settings *dest, int settings_version,
+ const ngtcp2_settings *src) {
+ if (settings_version == NGTCP2_SETTINGS_VERSION) {
+ return src;
+ }
+
+ ngtcp2_settings_default(dest);
+
+ settings_copy(dest, src, settings_version);
+
+ return dest;
+}
+
+void ngtcp2_settings_convert_to_old(int settings_version, ngtcp2_settings *dest,
+ const ngtcp2_settings *src) {
+ assert(settings_version != NGTCP2_SETTINGS_VERSION);
+
+ settings_copy(dest, src, settings_version);
+}
+
+size_t ngtcp2_settingslen_version(int settings_version) {
+ ngtcp2_settings settings;
+
+ switch (settings_version) {
+ case NGTCP2_SETTINGS_VERSION:
+ return sizeof(settings);
+ case NGTCP2_SETTINGS_V1:
+ return offsetof(ngtcp2_settings, initial_pkt_num) +
+ sizeof(settings.initial_pkt_num);
+ default:
+ ngtcp2_unreachable();
+ }
+}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h
new file mode 100644
index 0000000..8a8ddc2
--- /dev/null
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_settings.h
@@ -0,0 +1,73 @@
+/*
+ * ngtcp2
+ *
+ * Copyright (c) 2024 ngtcp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGTCP2_SETTINGS_H
+#define NGTCP2_SETTINGS_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <ngtcp2/ngtcp2.h>
+
+/*
+ * ngtcp2_settings_convert_to_latest converts |src| of version
+ * |settings_version| to the latest version NGTCP2_SETTINGS_VERSION.
+ *
+ * |dest| must point to the latest version. |src| may be the older
+ * version, and if so, it may have fewer fields. Accessing those
+ * fields causes undefined behavior.
+ *
+ * If |settings_version| == NGTCP2_SETTINGS_VERSION, no conversion is
+ * made, and |src| is returned. Otherwise, first |dest| is
+ * initialized via ngtcp2_settings_default, and then all valid fields
+ * in |src| are copied into |dest|. Finally, |dest| is returned.
+ */
+const ngtcp2_settings *
+ngtcp2_settings_convert_to_latest(ngtcp2_settings *dest, int settings_version,
+ const ngtcp2_settings *src);
+
+/*
+ * ngtcp2_settings_convert_to_old converts |src| of the latest version
+ * to |dest| of version |settings_version|.
+ *
+ * |settings_version| must not be the latest version
+ * NGTCP2_SETTINGS_VERSION.
+ *
+ * |dest| points to the older version, and it may have fewer fields.
+ * Accessing those fields causes undefined behavior.
+ *
+ * This function copies all valid fields in version |settings_version|
+ * from |src| to |dest|.
+ */
+void ngtcp2_settings_convert_to_old(int settings_version, ngtcp2_settings *dest,
+ const ngtcp2_settings *src);
+
+/*
+ * ngtcp2_settingslen_version returns the effective length of
+ * ngtcp2_settings at the version |settings_version|.
+ */
+size_t ngtcp2_settingslen_version(int settings_version);
+
+#endif /* NGTCP2_SETTINGS_H */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h
index 385302a..e396b24 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h
@@ -86,6 +86,9 @@ typedef struct ngtcp2_frame_chain ngtcp2_frame_chain;
received from the remote endpoint. In this case,
NGTCP2_STRM_FLAG_SHUT_WR is also set. */
#define NGTCP2_STRM_FLAG_STOP_SENDING_RECVED 0x800u
+/* NGTCP2_STRM_FLAG_ANY_SENT indicates that any STREAM frame,
+ including empty one, has been sent. */
+#define NGTCP2_STRM_FLAG_ANY_SENT 0x1000u
typedef struct ngtcp2_strm ngtcp2_strm;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
new file mode 100644
index 0000000..5a2b346
--- /dev/null
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
@@ -0,0 +1,886 @@
+/*
+ * ngtcp2
+ *
+ * Copyright (c) 2023 ngtcp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "ngtcp2_transport_params.h"
+
+#include <string.h>
+#include <assert.h>
+
+#include "ngtcp2_conv.h"
+#include "ngtcp2_str.h"
+#include "ngtcp2_mem.h"
+#include "ngtcp2_unreachable.h"
+
+void ngtcp2_transport_params_default_versioned(
+ int transport_params_version, ngtcp2_transport_params *params) {
+ size_t len;
+
+ switch (transport_params_version) {
+ case NGTCP2_TRANSPORT_PARAMS_VERSION:
+ len = sizeof(*params);
+
+ break;
+ default:
+ ngtcp2_unreachable();
+ }
+
+ memset(params, 0, len);
+
+ switch (transport_params_version) {
+ case NGTCP2_TRANSPORT_PARAMS_VERSION:
+ params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
+ params->active_connection_id_limit =
+ NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
+ params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
+ params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
+
+ break;
+ }
+}
+
+/*
+ * varint_paramlen returns the length of a single transport parameter
+ * which has variable integer in its parameter.
+ */
+static size_t varint_paramlen(ngtcp2_transport_param_id id, uint64_t param) {
+ size_t valuelen = ngtcp2_put_uvarintlen(param);
+ return ngtcp2_put_uvarintlen(id) + ngtcp2_put_uvarintlen(valuelen) + valuelen;
+}
+
+/*
+ * write_varint_param writes parameter |id| of the given |value| in
+ * varint encoding. It returns p + the number of bytes written.
+ */
+static uint8_t *write_varint_param(uint8_t *p, ngtcp2_transport_param_id id,
+ uint64_t value) {
+ p = ngtcp2_put_uvarint(p, id);
+ p = ngtcp2_put_uvarint(p, ngtcp2_put_uvarintlen(value));
+ return ngtcp2_put_uvarint(p, value);
+}
+
+/*
+ * zero_paramlen returns the length of a single transport parameter
+ * which has zero length value in its parameter.
+ */
+static size_t zero_paramlen(ngtcp2_transport_param_id id) {
+ return ngtcp2_put_uvarintlen(id) + 1;
+}
+
+/*
+ * write_zero_param writes parameter |id| that has zero length value.
+ * It returns p + the number of bytes written.
+ */
+static uint8_t *write_zero_param(uint8_t *p, ngtcp2_transport_param_id id) {
+ p = ngtcp2_put_uvarint(p, id);
+ *p++ = 0;
+
+ return p;
+}
+
+/*
+ * cid_paramlen returns the length of a single transport parameter
+ * which has |cid| as value.
+ */
+static size_t cid_paramlen(ngtcp2_transport_param_id id,
+ const ngtcp2_cid *cid) {
+ return ngtcp2_put_uvarintlen(id) + ngtcp2_put_uvarintlen(cid->datalen) +
+ cid->datalen;
+}
+
+/*
+ * write_cid_param writes parameter |id| of the given |cid|. It
+ * returns p + the number of bytes written.
+ */
+static uint8_t *write_cid_param(uint8_t *p, ngtcp2_transport_param_id id,
+ const ngtcp2_cid *cid) {
+ assert(cid->datalen == 0 || cid->datalen >= NGTCP2_MIN_CIDLEN);
+ assert(cid->datalen <= NGTCP2_MAX_CIDLEN);
+
+ p = ngtcp2_put_uvarint(p, id);
+ p = ngtcp2_put_uvarint(p, cid->datalen);
+ if (cid->datalen) {
+ p = ngtcp2_cpymem(p, cid->data, cid->datalen);
+ }
+ return p;
+}
+
+static const uint8_t empty_address[16];
+
+ngtcp2_ssize ngtcp2_transport_params_encode_versioned(
+ uint8_t *dest, size_t destlen, int transport_params_version,
+ const ngtcp2_transport_params *params) {
+ uint8_t *p;
+ size_t len = 0;
+ /* For some reason, gcc 7.3.0 requires this initialization. */
+ size_t preferred_addrlen = 0;
+ size_t version_infolen = 0;
+ const ngtcp2_sockaddr_in *sa_in;
+ const ngtcp2_sockaddr_in6 *sa_in6;
+ ngtcp2_transport_params paramsbuf;
+
+ params = ngtcp2_transport_params_convert_to_latest(
+ &paramsbuf, transport_params_version, params);
+
+ if (params->original_dcid_present) {
+ len +=
+ cid_paramlen(NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID,
+ &params->original_dcid);
+ }
+
+ if (params->stateless_reset_token_present) {
+ len += ngtcp2_put_uvarintlen(NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN) +
+ ngtcp2_put_uvarintlen(NGTCP2_STATELESS_RESET_TOKENLEN) +
+ NGTCP2_STATELESS_RESET_TOKENLEN;
+ }
+
+ if (params->preferred_addr_present) {
+ assert(params->preferred_addr.cid.datalen >= NGTCP2_MIN_CIDLEN);
+ assert(params->preferred_addr.cid.datalen <= NGTCP2_MAX_CIDLEN);
+ preferred_addrlen = 4 /* ipv4Address */ + 2 /* ipv4Port */ +
+ 16 /* ipv6Address */ + 2 /* ipv6Port */
+ + 1 + params->preferred_addr.cid.datalen /* CID */ +
+ NGTCP2_STATELESS_RESET_TOKENLEN;
+ len += ngtcp2_put_uvarintlen(NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS) +
+ ngtcp2_put_uvarintlen(preferred_addrlen) + preferred_addrlen;
+ }
+ if (params->retry_scid_present) {
+ len += cid_paramlen(NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID,
+ &params->retry_scid);
+ }
+
+ if (params->initial_scid_present) {
+ len += cid_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID,
+ &params->initial_scid);
+ }
+
+ if (params->initial_max_stream_data_bidi_local) {
+ len += varint_paramlen(
+ NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
+ params->initial_max_stream_data_bidi_local);
+ }
+ if (params->initial_max_stream_data_bidi_remote) {
+ len += varint_paramlen(
+ NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,
+ params->initial_max_stream_data_bidi_remote);
+ }
+ if (params->initial_max_stream_data_uni) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI,
+ params->initial_max_stream_data_uni);
+ }
+ if (params->initial_max_data) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA,
+ params->initial_max_data);
+ }
+ if (params->initial_max_streams_bidi) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI,
+ params->initial_max_streams_bidi);
+ }
+ if (params->initial_max_streams_uni) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI,
+ params->initial_max_streams_uni);
+ }
+ if (params->max_udp_payload_size !=
+ NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE,
+ params->max_udp_payload_size);
+ }
+ if (params->ack_delay_exponent != NGTCP2_DEFAULT_ACK_DELAY_EXPONENT) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT,
+ params->ack_delay_exponent);
+ }
+ if (params->disable_active_migration) {
+ len += zero_paramlen(NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION);
+ }
+ if (params->max_ack_delay != NGTCP2_DEFAULT_MAX_ACK_DELAY) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY,
+ params->max_ack_delay / NGTCP2_MILLISECONDS);
+ }
+ if (params->max_idle_timeout) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT,
+ params->max_idle_timeout / NGTCP2_MILLISECONDS);
+ }
+ if (params->active_connection_id_limit &&
+ params->active_connection_id_limit !=
+ NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT,
+ params->active_connection_id_limit);
+ }
+ if (params->max_datagram_frame_size) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE,
+ params->max_datagram_frame_size);
+ }
+ if (params->grease_quic_bit) {
+ len += zero_paramlen(NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT);
+ }
+ if (params->version_info_present) {
+ version_infolen =
+ sizeof(uint32_t) + params->version_info.available_versionslen;
+ len += ngtcp2_put_uvarintlen(NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION) +
+ ngtcp2_put_uvarintlen(version_infolen) + version_infolen;
+ }
+
+ if (dest == NULL && destlen == 0) {
+ return (ngtcp2_ssize)len;
+ }
+
+ if (destlen < len) {
+ return NGTCP2_ERR_NOBUF;
+ }
+
+ p = dest;
+
+ if (params->original_dcid_present) {
+ p = write_cid_param(
+ p, NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID,
+ &params->original_dcid);
+ }
+
+ if (params->stateless_reset_token_present) {
+ p = ngtcp2_put_uvarint(p, NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN);
+ p = ngtcp2_put_uvarint(p, sizeof(params->stateless_reset_token));
+ p = ngtcp2_cpymem(p, params->stateless_reset_token,
+ sizeof(params->stateless_reset_token));
+ }
+
+ if (params->preferred_addr_present) {
+ p = ngtcp2_put_uvarint(p, NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS);
+ p = ngtcp2_put_uvarint(p, preferred_addrlen);
+
+ if (params->preferred_addr.ipv4_present) {
+ sa_in = &params->preferred_addr.ipv4;
+ p = ngtcp2_cpymem(p, &sa_in->sin_addr, sizeof(sa_in->sin_addr));
+ p = ngtcp2_put_uint16(p, sa_in->sin_port);
+ } else {
+ p = ngtcp2_cpymem(p, empty_address, sizeof(sa_in->sin_addr));
+ p = ngtcp2_put_uint16(p, 0);
+ }
+
+ if (params->preferred_addr.ipv6_present) {
+ sa_in6 = &params->preferred_addr.ipv6;
+ p = ngtcp2_cpymem(p, &sa_in6->sin6_addr, sizeof(sa_in6->sin6_addr));
+ p = ngtcp2_put_uint16(p, sa_in6->sin6_port);
+ } else {
+ p = ngtcp2_cpymem(p, empty_address, sizeof(sa_in6->sin6_addr));
+ p = ngtcp2_put_uint16(p, 0);
+ }
+
+ *p++ = (uint8_t)params->preferred_addr.cid.datalen;
+ if (params->preferred_addr.cid.datalen) {
+ p = ngtcp2_cpymem(p, params->preferred_addr.cid.data,
+ params->preferred_addr.cid.datalen);
+ }
+ p = ngtcp2_cpymem(p, params->preferred_addr.stateless_reset_token,
+ sizeof(params->preferred_addr.stateless_reset_token));
+ }
+
+ if (params->retry_scid_present) {
+ p = write_cid_param(p, NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID,
+ &params->retry_scid);
+ }
+
+ if (params->initial_scid_present) {
+ p = write_cid_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID,
+ &params->initial_scid);
+ }
+
+ if (params->initial_max_stream_data_bidi_local) {
+ p = write_varint_param(
+ p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
+ params->initial_max_stream_data_bidi_local);
+ }
+
+ if (params->initial_max_stream_data_bidi_remote) {
+ p = write_varint_param(
+ p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,
+ params->initial_max_stream_data_bidi_remote);
+ }
+
+ if (params->initial_max_stream_data_uni) {
+ p = write_varint_param(p,
+ NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI,
+ params->initial_max_stream_data_uni);
+ }
+
+ if (params->initial_max_data) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA,
+ params->initial_max_data);
+ }
+
+ if (params->initial_max_streams_bidi) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI,
+ params->initial_max_streams_bidi);
+ }
+
+ if (params->initial_max_streams_uni) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI,
+ params->initial_max_streams_uni);
+ }
+
+ if (params->max_udp_payload_size !=
+ NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE,
+ params->max_udp_payload_size);
+ }
+
+ if (params->ack_delay_exponent != NGTCP2_DEFAULT_ACK_DELAY_EXPONENT) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT,
+ params->ack_delay_exponent);
+ }
+
+ if (params->disable_active_migration) {
+ p = write_zero_param(p, NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION);
+ }
+
+ if (params->max_ack_delay != NGTCP2_DEFAULT_MAX_ACK_DELAY) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY,
+ params->max_ack_delay / NGTCP2_MILLISECONDS);
+ }
+
+ if (params->max_idle_timeout) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT,
+ params->max_idle_timeout / NGTCP2_MILLISECONDS);
+ }
+
+ if (params->active_connection_id_limit &&
+ params->active_connection_id_limit !=
+ NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT,
+ params->active_connection_id_limit);
+ }
+
+ if (params->max_datagram_frame_size) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE,
+ params->max_datagram_frame_size);
+ }
+
+ if (params->grease_quic_bit) {
+ p = write_zero_param(p, NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT);
+ }
+
+ if (params->version_info_present) {
+ p = ngtcp2_put_uvarint(p, NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION);
+ p = ngtcp2_put_uvarint(p, version_infolen);
+ p = ngtcp2_put_uint32be(p, params->version_info.chosen_version);
+ if (params->version_info.available_versionslen) {
+ p = ngtcp2_cpymem(p, params->version_info.available_versions,
+ params->version_info.available_versionslen);
+ }
+ }
+
+ assert((size_t)(p - dest) == len);
+
+ return (ngtcp2_ssize)len;
+}
+
+/*
+ * decode_varint decodes a single varint from the buffer pointed by
+ * |*pp| of length |end - *pp|. If it decodes an integer
+ * successfully, it stores the integer in |*pdest|, increment |*pp| by
+ * the number of bytes read from |*pp|, and returns 0. Otherwise it
+ * returns -1.
+ */
+static int decode_varint(uint64_t *pdest, const uint8_t **pp,
+ const uint8_t *end) {
+ const uint8_t *p = *pp;
+ size_t len;
+
+ if (p == end) {
+ return -1;
+ }
+
+ len = ngtcp2_get_uvarintlen(p);
+ if ((uint64_t)(end - p) < len) {
+ return -1;
+ }
+
+ *pp = ngtcp2_get_uvarint(pdest, p);
+
+ return 0;
+}
+
+/*
+ * decode_varint_param decodes length prefixed value from the buffer
+ * pointed by |*pp| of length |end - *pp|. The length and value are
+ * encoded in varint form. If it decodes a value successfully, it
+ * stores the value in |*pdest|, increment |*pp| by the number of
+ * bytes read from |*pp|, and returns 0. Otherwise it returns -1.
+ */
+static int decode_varint_param(uint64_t *pdest, const uint8_t **pp,
+ const uint8_t *end) {
+ const uint8_t *p = *pp;
+ uint64_t valuelen;
+
+ if (decode_varint(&valuelen, &p, end) != 0) {
+ return -1;
+ }
+
+ if (p == end) {
+ return -1;
+ }
+
+ if ((uint64_t)(end - p) < valuelen) {
+ return -1;
+ }
+
+ if (ngtcp2_get_uvarintlen(p) != valuelen) {
+ return -1;
+ }
+
+ *pp = ngtcp2_get_uvarint(pdest, p);
+
+ return 0;
+}
+
+/*
+ * decode_zero_param decodes zero length value from the buffer pointed
+ * by |*pp| of length |end - *pp|. The length is encoded in varint
+ * form. If it decodes zero length value successfully, it increments
+ * |*pp| by 1, and returns 0. Otherwise it returns -1.
+ */
+static int decode_zero_param(const uint8_t **pp, const uint8_t *end) {
+ if (*pp == end || **pp != 0) {
+ return -1;
+ }
+
+ ++*pp;
+
+ return 0;
+}
+
+/*
+ * decode_cid_param decodes length prefixed ngtcp2_cid from the buffer
+ * pointed by |*pp| of length |end - *pp|. The length is encoded in
+ * varint form. If it decodes a value successfully, it stores the
+ * value in |*pdest|, increment |*pp| by the number of read from
+ * |*pp|, and returns the number of bytes read. Otherwise it returns
+ * the one of the negative error code:
+ *
+ * NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM
+ * Could not decode Connection ID.
+ */
+static int decode_cid_param(ngtcp2_cid *pdest, const uint8_t **pp,
+ const uint8_t *end) {
+ const uint8_t *p = *pp;
+ uint64_t valuelen;
+
+ if (decode_varint(&valuelen, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ if ((valuelen != 0 && valuelen < NGTCP2_MIN_CIDLEN) ||
+ valuelen > NGTCP2_MAX_CIDLEN || (size_t)(end - p) < valuelen) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ ngtcp2_cid_init(pdest, p, (size_t)valuelen);
+
+ p += valuelen;
+
+ *pp = p;
+
+ return 0;
+}
+
+int ngtcp2_transport_params_decode_versioned(int transport_params_version,
+ ngtcp2_transport_params *dest,
+ const uint8_t *data,
+ size_t datalen) {
+ const uint8_t *p, *end, *lend;
+ size_t len;
+ uint64_t param_type;
+ uint64_t valuelen;
+ int rv;
+ ngtcp2_sockaddr_in *sa_in;
+ ngtcp2_sockaddr_in6 *sa_in6;
+ uint32_t version;
+ ngtcp2_transport_params *params, paramsbuf;
+
+ if (transport_params_version == NGTCP2_TRANSPORT_PARAMS_VERSION) {
+ params = dest;
+ } else {
+ params = &paramsbuf;
+ }
+
+ /* Set default values */
+ memset(params, 0, sizeof(*params));
+ params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
+ params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
+ params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
+ params->active_connection_id_limit =
+ NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
+
+ p = data;
+ end = data + datalen;
+
+ for (; (size_t)(end - p) >= 2;) {
+ if (decode_varint(&param_type, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ switch (param_type) {
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:
+ if (decode_varint_param(&params->initial_max_stream_data_bidi_local, &p,
+ end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE:
+ if (decode_varint_param(&params->initial_max_stream_data_bidi_remote, &p,
+ end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI:
+ if (decode_varint_param(&params->initial_max_stream_data_uni, &p, end) !=
+ 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA:
+ if (decode_varint_param(&params->initial_max_data, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI:
+ if (decode_varint_param(&params->initial_max_streams_bidi, &p, end) !=
+ 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (params->initial_max_streams_bidi > NGTCP2_MAX_STREAMS) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI:
+ if (decode_varint_param(&params->initial_max_streams_uni, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (params->initial_max_streams_uni > NGTCP2_MAX_STREAMS) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT:
+ if (decode_varint_param(&params->max_idle_timeout, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ params->max_idle_timeout *= NGTCP2_MILLISECONDS;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE:
+ if (decode_varint_param(&params->max_udp_payload_size, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN:
+ if (decode_varint(&valuelen, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if ((size_t)valuelen != sizeof(params->stateless_reset_token)) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if ((size_t)(end - p) < sizeof(params->stateless_reset_token)) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ p = ngtcp2_get_bytes(params->stateless_reset_token, p,
+ sizeof(params->stateless_reset_token));
+ params->stateless_reset_token_present = 1;
+
+ break;
+ case NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT:
+ if (decode_varint_param(&params->ack_delay_exponent, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (params->ack_delay_exponent > 20) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS:
+ if (decode_varint(&valuelen, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if ((size_t)(end - p) < valuelen) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ len = 4 /* ipv4Address */ + 2 /* ipv4Port */ + 16 /* ipv6Address */ +
+ 2 /* ipv6Port */
+ + 1 /* cid length */ + NGTCP2_STATELESS_RESET_TOKENLEN;
+ if (valuelen < len) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ sa_in = &params->preferred_addr.ipv4;
+
+ p = ngtcp2_get_bytes(&sa_in->sin_addr, p, sizeof(sa_in->sin_addr));
+ p = ngtcp2_get_uint16be(&sa_in->sin_port, p);
+
+ if (sa_in->sin_port || memcmp(empty_address, &sa_in->sin_addr,
+ sizeof(sa_in->sin_addr)) != 0) {
+ sa_in->sin_family = NGTCP2_AF_INET;
+ params->preferred_addr.ipv4_present = 1;
+ }
+
+ sa_in6 = &params->preferred_addr.ipv6;
+
+ p = ngtcp2_get_bytes(&sa_in6->sin6_addr, p, sizeof(sa_in6->sin6_addr));
+ p = ngtcp2_get_uint16be(&sa_in6->sin6_port, p);
+
+ if (sa_in6->sin6_port || memcmp(empty_address, &sa_in6->sin6_addr,
+ sizeof(sa_in6->sin6_addr)) != 0) {
+ sa_in6->sin6_family = NGTCP2_AF_INET6;
+ params->preferred_addr.ipv6_present = 1;
+ }
+
+ /* cid */
+ params->preferred_addr.cid.datalen = *p++;
+ len += params->preferred_addr.cid.datalen;
+ if (valuelen != len ||
+ params->preferred_addr.cid.datalen > NGTCP2_MAX_CIDLEN ||
+ params->preferred_addr.cid.datalen < NGTCP2_MIN_CIDLEN) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (params->preferred_addr.cid.datalen) {
+ p = ngtcp2_get_bytes(params->preferred_addr.cid.data, p,
+ params->preferred_addr.cid.datalen);
+ }
+
+ /* stateless reset token */
+ p = ngtcp2_get_bytes(
+ params->preferred_addr.stateless_reset_token, p,
+ sizeof(params->preferred_addr.stateless_reset_token));
+ params->preferred_addr_present = 1;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION:
+ if (decode_zero_param(&p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ params->disable_active_migration = 1;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID:
+ rv = decode_cid_param(&params->original_dcid, &p, end);
+ if (rv != 0) {
+ return rv;
+ }
+ params->original_dcid_present = 1;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID:
+ rv = decode_cid_param(&params->retry_scid, &p, end);
+ if (rv != 0) {
+ return rv;
+ }
+ params->retry_scid_present = 1;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID:
+ rv = decode_cid_param(&params->initial_scid, &p, end);
+ if (rv != 0) {
+ return rv;
+ }
+ params->initial_scid_present = 1;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY:
+ if (decode_varint_param(&params->max_ack_delay, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (params->max_ack_delay >= 16384) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ params->max_ack_delay *= NGTCP2_MILLISECONDS;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT:
+ if (decode_varint_param(&params->active_connection_id_limit, &p, end) !=
+ 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE:
+ if (decode_varint_param(&params->max_datagram_frame_size, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ break;
+ case NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT:
+ if (decode_zero_param(&p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ params->grease_quic_bit = 1;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION:
+ if (decode_varint(&valuelen, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if ((size_t)(end - p) < valuelen) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (valuelen < sizeof(uint32_t) || (valuelen & 0x3)) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ p = ngtcp2_get_uint32(&params->version_info.chosen_version, p);
+ if (params->version_info.chosen_version == 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if (valuelen > sizeof(uint32_t)) {
+ params->version_info.available_versions = (uint8_t *)p;
+ params->version_info.available_versionslen =
+ (size_t)valuelen - sizeof(uint32_t);
+
+ for (lend = p + (valuelen - sizeof(uint32_t)); p != lend;) {
+ p = ngtcp2_get_uint32(&version, p);
+ if (version == 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ }
+ }
+ params->version_info_present = 1;
+ break;
+ default:
+ /* Ignore unknown parameter */
+ if (decode_varint(&valuelen, &p, end) != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ if ((size_t)(end - p) < valuelen) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+ p += valuelen;
+ break;
+ }
+ }
+
+ if (end - p != 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ if (transport_params_version != NGTCP2_TRANSPORT_PARAMS_VERSION) {
+ ngtcp2_transport_params_convert_to_old(transport_params_version, dest,
+ params);
+ }
+
+ return 0;
+}
+
+static int transport_params_copy_new(ngtcp2_transport_params **pdest,
+ const ngtcp2_transport_params *src,
+ const ngtcp2_mem *mem) {
+ size_t len = sizeof(**pdest);
+ ngtcp2_transport_params *dest;
+ uint8_t *p;
+
+ if (src->version_info_present) {
+ len += src->version_info.available_versionslen;
+ }
+
+ dest = ngtcp2_mem_malloc(mem, len);
+ if (dest == NULL) {
+ return NGTCP2_ERR_NOMEM;
+ }
+
+ *dest = *src;
+
+ if (src->version_info_present && src->version_info.available_versionslen) {
+ p = (uint8_t *)dest + sizeof(*dest);
+ memcpy(p, src->version_info.available_versions,
+ src->version_info.available_versionslen);
+ dest->version_info.available_versions = p;
+ }
+
+ *pdest = dest;
+
+ return 0;
+}
+
+int ngtcp2_transport_params_decode_new(ngtcp2_transport_params **pparams,
+ const uint8_t *data, size_t datalen,
+ const ngtcp2_mem *mem) {
+ int rv;
+ ngtcp2_transport_params params;
+
+ rv = ngtcp2_transport_params_decode(&params, data, datalen);
+ if (rv < 0) {
+ return rv;
+ }
+
+ if (mem == NULL) {
+ mem = ngtcp2_mem_default();
+ }
+
+ return transport_params_copy_new(pparams, &params, mem);
+}
+
+void ngtcp2_transport_params_del(ngtcp2_transport_params *params,
+ const ngtcp2_mem *mem) {
+ if (params == NULL) {
+ return;
+ }
+
+ if (mem == NULL) {
+ mem = ngtcp2_mem_default();
+ }
+
+ ngtcp2_mem_free(mem, params);
+}
+
+int ngtcp2_transport_params_copy_new(ngtcp2_transport_params **pdest,
+ const ngtcp2_transport_params *src,
+ const ngtcp2_mem *mem) {
+ if (src == NULL) {
+ *pdest = NULL;
+ return 0;
+ }
+
+ return transport_params_copy_new(pdest, src, mem);
+}
+
+static void transport_params_copy(ngtcp2_transport_params *dest,
+ const ngtcp2_transport_params *src,
+ int transport_params_version) {
+ assert(transport_params_version != NGTCP2_TRANSPORT_PARAMS_VERSION);
+
+ switch (transport_params_version) {
+ case NGTCP2_TRANSPORT_PARAMS_V1:
+ memcpy(dest, src,
+ offsetof(ngtcp2_transport_params, version_info_present) +
+ sizeof(src->version_info_present));
+
+ break;
+ }
+}
+
+const ngtcp2_transport_params *
+ngtcp2_transport_params_convert_to_latest(ngtcp2_transport_params *dest,
+ int transport_params_version,
+ const ngtcp2_transport_params *src) {
+ if (transport_params_version == NGTCP2_TRANSPORT_PARAMS_VERSION) {
+ return src;
+ }
+
+ ngtcp2_transport_params_default(dest);
+
+ transport_params_copy(dest, src, transport_params_version);
+
+ return dest;
+}
+
+void ngtcp2_transport_params_convert_to_old(
+ int transport_params_version, ngtcp2_transport_params *dest,
+ const ngtcp2_transport_params *src) {
+ assert(transport_params_version != NGTCP2_TRANSPORT_PARAMS_VERSION);
+
+ transport_params_copy(dest, src, transport_params_version);
+}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.h
index 3457a8f..9b0acb8 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conversion.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_transport_params.h
@@ -22,8 +22,8 @@
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifndef NGTCP2_CONVERSION_H
-#define NGTCP2_CONVERSION_H
+#ifndef NGTCP2_TRANSPORT_PARAMS_H
+#define NGTCP2_TRANSPORT_PARAMS_H
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -31,6 +31,53 @@
#include <ngtcp2/ngtcp2.h>
+/* ngtcp2_transport_param_id is the registry of QUIC transport
+ parameter ID. */
+typedef uint64_t ngtcp2_transport_param_id;
+
+#define NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID 0x00
+#define NGTCP2_TRANSPORT_PARAM_MAX_IDLE_TIMEOUT 0x01
+#define NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN 0x02
+#define NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE 0x03
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_DATA 0x04
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE 0x06
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_UNI 0x07
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_BIDI 0x08
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI 0x09
+#define NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT 0x0a
+#define NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY 0x0b
+#define NGTCP2_TRANSPORT_PARAM_DISABLE_ACTIVE_MIGRATION 0x0c
+#define NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS 0x0d
+#define NGTCP2_TRANSPORT_PARAM_ACTIVE_CONNECTION_ID_LIMIT 0x0e
+#define NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID 0x0f
+#define NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID 0x10
+/* https://datatracker.ietf.org/doc/html/rfc9221 */
+#define NGTCP2_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE 0x20
+#define NGTCP2_TRANSPORT_PARAM_GREASE_QUIC_BIT 0x2ab2
+/* https://datatracker.ietf.org/doc/html/rfc9368 */
+#define NGTCP2_TRANSPORT_PARAM_VERSION_INFORMATION 0x11
+
+/* NGTCP2_MAX_STREAMS is the maximum number of streams. */
+#define NGTCP2_MAX_STREAMS (1LL << 60)
+
+/*
+ * ngtcp2_transport_params_copy_new makes a copy of |src|, and assigns
+ * it to |*pdest|. If |src| is NULL, NULL is assigned to |*pdest|.
+ *
+ * Caller is responsible to call ngtcp2_transport_params_del to free
+ * the memory assigned to |*pdest|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGTCP2_ERR_NOMEM
+ * Out of memory.
+ */
+int ngtcp2_transport_params_copy_new(ngtcp2_transport_params **pdest,
+ const ngtcp2_transport_params *src,
+ const ngtcp2_mem *mem);
+
/*
* ngtcp2_transport_params_convert_to_latest converts |src| of version
* |transport_params_version| to the latest version
@@ -68,4 +115,4 @@ void ngtcp2_transport_params_convert_to_old(int transport_params_version,
ngtcp2_transport_params *dest,
const ngtcp2_transport_params *src);
-#endif /* NGTCP2_CONVERSION_H */
+#endif /* NGTCP2_TRANSPORT_PARAMS_H */
diff --git a/src/contrib/libngtcp2/ngtcp2/ngtcp2.h b/src/contrib/libngtcp2/ngtcp2/ngtcp2.h
index 72c8142..0b49853 100644
--- a/src/contrib/libngtcp2/ngtcp2/ngtcp2.h
+++ b/src/contrib/libngtcp2/ngtcp2/ngtcp2.h
@@ -1689,7 +1689,8 @@ typedef enum ngtcp2_token_type {
} ngtcp2_token_type;
#define NGTCP2_SETTINGS_V1 1
-#define NGTCP2_SETTINGS_VERSION NGTCP2_SETTINGS_V1
+#define NGTCP2_SETTINGS_V2 2
+#define NGTCP2_SETTINGS_VERSION NGTCP2_SETTINGS_V2
/**
* @struct
@@ -1723,8 +1724,7 @@ typedef struct ngtcp2_settings {
ngtcp2_printf log_printf;
/**
* :member:`max_tx_udp_payload_size` is the maximum size of UDP
- * datagram payload that the local endpoint transmits. It is used
- * by congestion controller to compute congestion window.
+ * datagram payload that the local endpoint transmits.
*/
size_t max_tx_udp_payload_size;
/**
@@ -1877,6 +1877,24 @@ typedef struct ngtcp2_settings {
* number space. It must be in range [0, INT32_MAX], inclusive.
*/
uint32_t initial_pkt_num;
+ /* The following fields have been added since NGTCP2_SETTINGS_V2. */
+ /**
+ * :member:`pmtud_probes` is the array of UDP datagram payload size
+ * to probe during Path MTU Discovery. The discovery is done in the
+ * order appeared in this array. The size must be strictly larger
+ * than 1200, otherwise the behavior is undefined. The maximum
+ * value in this array should be set to
+ * :member:`max_tx_udp_payload_size`. If this field is not set, the
+ * predefined PMTUD probes are made. This field has been available
+ * since v1.4.0.
+ */
+ const uint16_t *pmtud_probes;
+ /**
+ * :member:`pmtud_probeslen` is the number of elements that are
+ * contained in the array pointed by :member:`pmtud_probes`. This
+ * field has been available since v1.4.0.
+ */
+ size_t pmtud_probeslen;
} ngtcp2_settings;
/**
@@ -4388,7 +4406,8 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_write_stream_versioned(
* handshake as well.
*
* |destlen| should be at least
- * :member:`ngtcp2_settings.max_tx_udp_payload_size`.
+ * :member:`ngtcp2_settings.max_tx_udp_payload_size`. It must be at
+ * least :macro:`NGTCP2_MAX_UDP_PAYLOAD_SIZE`.
*
* Specifying -1 to |stream_id| means no new stream data to send.
*
@@ -4418,8 +4437,10 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_write_stream_versioned(
* In that case, |*pdatalen| would be -1 if |pdatalen| is not
* ``NULL``.
*
- * If |flags| & :macro:`NGTCP2_WRITE_STREAM_FLAG_FIN` is nonzero, and
- * 0 length STREAM frame is successfully serialized, |*pdatalen| would
+ * Empty data is treated specially, and it is only accepted if no
+ * data, including the empty data, is submitted to a stream or
+ * :macro:`NGTCP2_WRITE_STREAM_FLAG_FIN` is set in |flags|. If 0
+ * length STREAM frame is successfully serialized, |*pdatalen| would
* be 0.
*
* The number of data encoded in STREAM frame is stored in |*pdatalen|
@@ -4573,7 +4594,8 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_write_datagram_versioned(
* as well.
*
* |destlen| should be at least
- * :member:`ngtcp2_settings.max_tx_udp_payload_size`.
+ * :member:`ngtcp2_settings.max_tx_udp_payload_size`. It must be at
+ * least :macro:`NGTCP2_MAX_UDP_PAYLOAD_SIZE`.
*
* For |path| and |pi| parameters, refer to
* `ngtcp2_conn_writev_stream`.
@@ -5193,7 +5215,19 @@ typedef enum ngtcp2_ccerr_type {
* transport error, and it indicates that connection is closed
* because of idle timeout.
*/
- NGTCP2_CCERR_TYPE_IDLE_CLOSE
+ NGTCP2_CCERR_TYPE_IDLE_CLOSE,
+ /**
+ * :enum:`NGTCP2_CCERR_TYPE_DROP_CONN` is a special case of QUIC
+ * transport error, and it indicates that connection should be
+ * dropped without sending a CONNECTION_CLOSE frame.
+ */
+ NGTCP2_CCERR_TYPE_DROP_CONN,
+ /**
+ * :enum:`NGTCP2_CCERR_TYPE_RETRY` is a special case of QUIC
+ * transport error, and it indicates that RETRY packet should be
+ * sent to a client.
+ */
+ NGTCP2_CCERR_TYPE_RETRY
} ngtcp2_ccerr_type;
/**
@@ -5284,6 +5318,18 @@ NGTCP2_EXTERN void ngtcp2_ccerr_set_transport_error(ngtcp2_ccerr *ccerr,
* :member:`ccerr->error_code <ngtcp2_ccerr.error_code>` to
* :macro:`NGTCP2_NO_ERROR`.
*
+ * If |liberr| is :macro:`NGTCP2_ERR_DROP_CONN`, :member:`ccerr->type
+ * <ngtcp2_ccerr.type>` is set to
+ * :enum:`ngtcp2_ccerr_type.NGTCP2_CCERR_TYPE_DROP_CONN`, and
+ * :member:`ccerr->error_code <ngtcp2_ccerr.error_code>` to
+ * :macro:`NGTCP2_NO_ERROR`.
+ *
+ * If |liberr| is :macro:`NGTCP2_ERR_RETRY`, :member:`ccerr->type
+ * <ngtcp2_ccerr.type>` is set to
+ * :enum:`ngtcp2_ccerr_type.NGTCP2_CCERR_TYPE_RETRY`, and
+ * :member:`ccerr->error_type <ngtcp2_ccerr.error_code>` to
+ * :macro:`NGTCP2_NO_ERROR`.
+ *
* Otherwise, :member:`ccerr->type <ngtcp2_ccerr.type>` is set to
* :enum:`ngtcp2_ccerr_type.NGTCP2_CCERR_TYPE_TRANSPORT`, and
* :member:`ccerr->error_code <ngtcp2_ccerr.error_code>` is set to an
diff --git a/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h b/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h
index 06427d7..9f909bf 100644
--- a/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h
+++ b/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h
@@ -540,7 +540,7 @@ NGTCP2_EXTERN int ngtcp2_crypto_generate_stateless_reset_token(
* `ngtcp2_crypto_generate_retry_token` or
* `ngtcp2_crypto_generate_regular_token`.
*/
-#define NGTCP2_CRYPTO_TOKEN_RAND_DATALEN 32
+#define NGTCP2_CRYPTO_TOKEN_RAND_DATALEN 16
/**
* @macro
diff --git a/src/contrib/libngtcp2/ngtcp2/version.h b/src/contrib/libngtcp2/ngtcp2/version.h
index 801c6cb..9eb076d 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.3.0"
+#define NGTCP2_VERSION "1.5.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 0x010300
+#define NGTCP2_VERSION_NUM 0x010500
#endif /* VERSION_H */
diff --git a/src/knot/conf/base.c b/src/knot/conf/base.c
index 9dc4cef..51caf10 100644
--- a/src/knot/conf/base.c
+++ b/src/knot/conf/base.c
@@ -27,6 +27,7 @@
#include "libknot/yparser/ypformat.h"
#include "libknot/yparser/yptrafo.h"
#include "contrib/files.h"
+#include "contrib/json.h"
#include "contrib/sockaddr.h"
#include "contrib/string.h"
@@ -1073,3 +1074,230 @@ export_error:
return ret;
}
+
+/*
+ * Execute the provided block of code twice: first to handle a JSON schema for
+ * a single item, and then to define an array of these items.
+ */
+#define SINGLE_OR_ARRAY(code_block) \
+do { \
+ if (item->flags & YP_FMULTI) { \
+ jsonw_list(w, "oneOf"); \
+ jsonw_object(w, NULL); \
+ { code_block } \
+ jsonw_end(w); \
+ jsonw_object(w, NULL); \
+ jsonw_str(w, "type", "array"); \
+ jsonw_object(w, "items"); \
+ } \
+ { code_block } \
+ if (item->flags & YP_FMULTI) { \
+ jsonw_end(w); \
+ jsonw_end(w); \
+ jsonw_end(w); \
+ } \
+} while (0)
+
+static int export_group_items(jsonw_t *w, const yp_item_t *item, bool array);
+
+static void export_type(jsonw_t *w, const yp_item_t *item)
+{
+ switch (item->type) {
+ case YP_TINT:
+ SINGLE_OR_ARRAY(
+ switch (item->var.i.unit) {
+ case YP_SSIZE:
+ jsonw_str(w, "$ref", "#/$defs/int_size");
+ break;
+ case YP_STIME:
+ jsonw_str(w, "$ref", "#/$defs/int_time");
+ break;
+ default:
+ jsonw_str(w, "$ref", "#/$defs/int");
+ break;
+ }
+ );
+ break;
+ case YP_TBOOL:
+ SINGLE_OR_ARRAY(
+ jsonw_str(w, "$ref", "#/$defs/switch");
+ );
+ break;
+ case YP_TOPT:
+ SINGLE_OR_ARRAY(
+ jsonw_str(w, "type", "string");
+ jsonw_list(w, "enum");
+ for (const knot_lookup_t *o = item->var.o.opts;
+ o->name != NULL; ++o) {
+ jsonw_str(w, NULL, o->name);
+ }
+ jsonw_end(w);
+ );
+ break;
+ case YP_TSTR:
+ SINGLE_OR_ARRAY(
+ jsonw_str(w, "type", "string");
+ );
+ break;
+ case YP_TDNAME:
+ SINGLE_OR_ARRAY(
+ jsonw_str(w, "$ref", "#/$defs/dname");
+ );
+ break;
+ case YP_TB64:
+ SINGLE_OR_ARRAY(
+ jsonw_str(w, "$ref", "#/$defs/base64");
+ );
+ break;
+ case YP_TGRP:
+ export_group_items(w, item->sub_items, item->flags & YP_FMULTI);
+ break;
+ case YP_THEX:
+ case YP_TADDR:
+ case YP_TNET:
+ case YP_TDATA:
+ case YP_TREF:
+ SINGLE_OR_ARRAY(
+ jsonw_str(w, "type", "string");
+ );
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+static int export_group_items(jsonw_t *w, const yp_item_t *item, bool array)
+{
+ assert(w != NULL && item != NULL);
+
+ if (array) {
+ jsonw_list(w, "type");
+ jsonw_str(w, NULL, "array");
+ jsonw_str(w, NULL, "null");
+ jsonw_end(w);
+ jsonw_object(w, "items");
+ }
+
+ jsonw_list(w, "type");
+ jsonw_str(w, NULL, "object");
+ jsonw_str(w, NULL, "null");
+ jsonw_end(w);
+ jsonw_bool(w, "additionalProperties", false);
+ jsonw_object(w, "properties");
+ for (; item->name != NULL; ++item) {
+ jsonw_object(w, item->name + 1);
+ export_type(w, item);
+ jsonw_end(w);
+ }
+ jsonw_end(w);
+
+ if (array) {
+ jsonw_end(w);
+ }
+
+ return KNOT_EOK;
+}
+
+int conf_export_schema(
+ conf_t *conf,
+ const char *file_name)
+{
+ if (conf == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ FILE *fp = (file_name != NULL) ? fopen(file_name, "w") : stdout;
+ if (fp == NULL) {
+ return knot_map_errno();
+ }
+
+ jsonw_t *w = jsonw_new(fp, " ");
+ jsonw_object(w, NULL);
+
+ // JSON-Schema header
+ jsonw_str(w, "$schema", "https://json-schema.org/draft/2020-12/schema");
+ jsonw_str(w, "$id", "https://knot-dns.cz/config.schema.json");
+ jsonw_str(w, "title", "Knot DNS configuration schema");
+ jsonw_str(w, "description", "Version Knot DNS " PACKAGE_VERSION);
+
+ // Define own types
+ jsonw_object(w, "$defs");
+ // Switch type
+ jsonw_object(w, "switch");
+ jsonw_list(w, "oneOf");
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "boolean");
+ jsonw_end(w);
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "string");
+ jsonw_list(w, "enum");
+ jsonw_str(w, NULL, "on");
+ jsonw_str(w, NULL, "off");
+ jsonw_str(w, NULL, "true");
+ jsonw_str(w, NULL, "false");
+ jsonw_end(w);
+ jsonw_end(w);
+ jsonw_end(w);
+ jsonw_end(w);
+ // Base64 type
+ jsonw_object(w, "base64");
+ jsonw_str(w, "type", "string");
+ jsonw_str(w, "pattern", "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]===)?$");
+ jsonw_end(w);
+ // DNAME type
+ jsonw_object(w, "dname");
+ jsonw_str(w, "type", "string");
+ jsonw_str(w, "pattern", "^(([a-zA-Z0-9_*/-]|(\\\\[^0-9])|(\\\\(([0-1][0-9][0-9])|(2[0-4][0-9])|(25[0-5]))))\\.?)+$");
+ jsonw_end(w);
+ // Integer type
+ jsonw_object(w, "int");
+ jsonw_list(w, "oneOf");
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "integer");
+ jsonw_end(w);
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "string");
+ jsonw_str(w, "pattern", "^[+-]?[0-9]+$");
+ jsonw_end(w);
+ jsonw_end(w);
+ jsonw_end(w);
+ // Size integer type
+ jsonw_object(w, "int_size");
+ jsonw_list(w, "oneOf");
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "integer");
+ jsonw_end(w);
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "string");
+ jsonw_str(w, "pattern", "^[+-]?[0-9]+[BKMG]?$");
+ jsonw_end(w);
+ jsonw_end(w);
+ jsonw_end(w);
+ // Time integer type
+ jsonw_object(w, "int_time");
+ jsonw_list(w, "oneOf");
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "integer");
+ jsonw_end(w);
+ jsonw_object(w, NULL);
+ jsonw_str(w, "type", "string");
+ jsonw_str(w, "pattern", "^[+-]?[0-9]+[smhd]?$");
+ jsonw_end(w);
+ jsonw_end(w);
+ jsonw_end(w);
+ // END
+ jsonw_end(w);
+
+ // Export configuration schema
+ int ret = export_group_items(w, conf->schema, false);
+
+ jsonw_end(w);
+ jsonw_free(&w);
+
+ if (file_name != NULL) {
+ fclose(fp);
+ }
+
+ return ret;
+}
diff --git a/src/knot/conf/base.h b/src/knot/conf/base.h
index 2fc48de..5c77cac 100644
--- a/src/knot/conf/base.h
+++ b/src/knot/conf/base.h
@@ -331,3 +331,16 @@ int conf_export(
const char *file_name,
yp_style_t style
);
+
+/*!
+ * Exports configuration schema in JSON.
+ *
+ * \param[in] conf Configuration.
+ * \param[in] file_name Output filename (stdout is used if NULL).
+ *
+ * \return Error code, KNOT_EOK if success.
+ */
+int conf_export_schema(
+ conf_t *conf,
+ const char *file_name
+);
diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c
index 54eeae6..55ee971 100644
--- a/src/knot/conf/conf.c
+++ b/src/knot/conf/conf.c
@@ -191,6 +191,10 @@ conf_val_t conf_zone_get_txn(
conf_db_get(conf, txn, C_ZONE, key1_name, dname, dname_size, &val);
switch (val.code) {
case KNOT_EOK:
+ if (val.blob_len == 1 && (val.item->flags & CONF_REF_EMPTY)) {
+ static const conf_val_t empty = { .code = KNOT_ENOENT };
+ return empty;
+ }
return val;
default:
CONF_LOG_ZONE(LOG_ERR, dname, "failed to read '%s/%s' (%s)",
diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h
index 99af9bd..562722d 100644
--- a/src/knot/conf/conf.h
+++ b/src/knot/conf/conf.h
@@ -21,6 +21,21 @@
#include "knot/conf/base.h"
#include "knot/conf/schema.h"
+/*! Configuration schema additional flags. */
+#define CONF_IO_FACTIVE YP_FUSR1 /*!< Active confio transaction indicator. */
+#define CONF_IO_FZONE YP_FUSR2 /*!< Zone section indicator. */
+#define CONF_IO_FREF YP_FUSR3 /*!< Possibly referenced id from a zone. */
+#define CONF_IO_FDIFF_ZONES YP_FUSR4 /*!< All zones config has changed. */
+#define CONF_IO_FCHECK_ZONES YP_FUSR5 /*!< All zones config needs to check. */
+#define CONF_IO_FRLD_SRV YP_FUSR6 /*!< Reload server. */
+#define CONF_IO_FRLD_LOG YP_FUSR7 /*!< Reload logging. */
+#define CONF_IO_FRLD_MOD YP_FUSR8 /*!< Reload global modules. */
+#define CONF_IO_FRLD_ZONE YP_FUSR9 /*!< Reload a specific zone. */
+#define CONF_IO_FRLD_ZONES YP_FUSR10 /*!< Reload all zones. */
+#define CONF_REF_EMPTY YP_FUSR11 /*!< Allow empty reference value for zone item. */
+#define CONF_IO_FRLD_ALL (CONF_IO_FRLD_SRV | CONF_IO_FRLD_LOG | \
+ CONF_IO_FRLD_MOD | CONF_IO_FRLD_ZONES)
+
/*! Configuration remote getter output. */
typedef struct {
/*! Target socket address. */
diff --git a/src/knot/conf/confio.h b/src/knot/conf/confio.h
index be08e97..1f3a481 100644
--- a/src/knot/conf/confio.h
+++ b/src/knot/conf/confio.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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
@@ -18,20 +18,6 @@
#include "knot/conf/conf.h"
-/*! Configuration schema additional flags for dynamic changes. */
-#define CONF_IO_FACTIVE YP_FUSR1 /*!< Active confio transaction indicator. */
-#define CONF_IO_FZONE YP_FUSR2 /*!< Zone section indicator. */
-#define CONF_IO_FREF YP_FUSR3 /*!< Possibly referenced id from a zone. */
-#define CONF_IO_FDIFF_ZONES YP_FUSR4 /*!< All zones config has changed. */
-#define CONF_IO_FCHECK_ZONES YP_FUSR5 /*!< All zones config needs to check. */
-#define CONF_IO_FRLD_SRV YP_FUSR6 /*!< Reload server. */
-#define CONF_IO_FRLD_LOG YP_FUSR7 /*!< Reload logging. */
-#define CONF_IO_FRLD_MOD YP_FUSR8 /*!< Reload global modules. */
-#define CONF_IO_FRLD_ZONE YP_FUSR9 /*!< Reload a specific zone. */
-#define CONF_IO_FRLD_ZONES YP_FUSR10 /*!< Reload all zones. */
-#define CONF_IO_FRLD_ALL (CONF_IO_FRLD_SRV | CONF_IO_FRLD_LOG | \
- CONF_IO_FRLD_MOD | CONF_IO_FRLD_ZONES)
-
/*! Zone configuration change type. */
typedef enum {
CONF_IO_TNONE = 0, /*!< Unspecified. */
diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c
index 59c6796..6e426b3 100644
--- a/src/knot/conf/schema.c
+++ b/src/knot/conf/schema.c
@@ -282,6 +282,7 @@ static const yp_item_t desc_xdp[] = {
static const yp_item_t desc_control[] = {
{ C_LISTEN, YP_TSTR, YP_VSTR = { "knot.sock" } },
+ { C_BACKLOG, YP_TINT, YP_VINT = { 0, UINT16_MAX, 5 } },
{ C_TIMEOUT, YP_TINT, YP_VINT = { 0, INT32_MAX / 1000, 5, YP_STIME } },
{ C_COMMENT, YP_TSTR, YP_VNONE },
{ NULL }
@@ -418,6 +419,7 @@ static const yp_item_t desc_policy[] = {
CONF_IO_FRLD_ZONES },
{ C_ZONE_MAX_TTL, YP_TINT, YP_VINT = { 0, INT32_MAX, YP_NIL, YP_STIME },
CONF_IO_FRLD_ZONES },
+ { C_KEYTAG_MODULO, YP_TSTR, YP_VSTR = { "0/1" }, YP_FNONE, { check_modulo } }, \
{ C_KSK_LIFETIME, YP_TINT, YP_VINT = { 0, UINT32_MAX, 0, YP_STIME },
CONF_IO_FRLD_ZONES },
{ C_ZSK_LIFETIME, YP_TINT, YP_VINT = { 0, UINT32_MAX, DAYS(30), YP_STIME },
@@ -460,9 +462,11 @@ static const yp_item_t desc_policy[] = {
#define ZONE_ITEMS(FLAGS) \
{ C_STORAGE, YP_TSTR, YP_VSTR = { STORAGE_DIR }, FLAGS }, \
{ C_FILE, YP_TSTR, YP_VNONE, FLAGS }, \
- { C_MASTER, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI, { check_ref } }, \
+ { C_MASTER, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | CONF_REF_EMPTY, \
+ { check_ref } }, \
{ C_DDNS_MASTER, YP_TREF, YP_VREF = { C_RMT }, YP_FNONE, { check_ref_empty } }, \
- { C_NOTIFY, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI, { check_ref } }, \
+ { C_NOTIFY, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | CONF_REF_EMPTY, \
+ { check_ref } }, \
{ C_ACL, YP_TREF, YP_VREF = { C_ACL }, YP_FMULTI, { check_ref } }, \
{ C_MASTER_PIN_TOL, YP_TINT, YP_VINT = { 0, UINT32_MAX, 0, YP_STIME } }, \
{ C_PROVIDE_IXFR, YP_TBOOL, YP_VBOOL = { true } }, \
@@ -480,7 +484,7 @@ static const yp_item_t desc_policy[] = {
{ C_DNSSEC_SIGNING, YP_TBOOL, YP_VNONE, FLAGS }, \
{ C_DNSSEC_VALIDATION, YP_TBOOL, YP_VNONE, FLAGS }, \
{ C_DNSSEC_POLICY, YP_TREF, YP_VREF = { C_POLICY }, FLAGS, { check_ref_dflt } }, \
- { C_DS_PUSH, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | FLAGS, \
+ { C_DS_PUSH, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | CONF_REF_EMPTY | FLAGS, \
{ check_ref } }, \
{ C_REVERSE_GEN, YP_TDNAME,YP_VNONE, FLAGS | CONF_IO_FRLD_ZONES }, \
{ C_SERIAL_POLICY, YP_TOPT, YP_VOPT = { serial_policies, SERIAL_POLICY_INCREMENT } }, \
diff --git a/src/knot/conf/schema.h b/src/knot/conf/schema.h
index 1850380..96d29c1 100644
--- a/src/knot/conf/schema.h
+++ b/src/knot/conf/schema.h
@@ -30,6 +30,7 @@
#define C_ASYNC_START "\x0B""async-start"
#define C_AUTO_ACL "\x0D""automatic-acl"
#define C_BACKEND "\x07""backend"
+#define C_BACKLOG "\x07""backlog"
#define C_BG_WORKERS "\x12""background-workers"
#define C_BLOCK_NOTIFY_XFR "\x1B""block-notify-after-transfer"
#define C_CATALOG_DB "\x0A""catalog-db"
@@ -83,6 +84,7 @@
#define C_DELETE_DELAY "\x0C""delete-delay"
#define C_KEY "\x03""key"
#define C_KEYSTORE "\x08""keystore"
+#define C_KEYTAG_MODULO "\x0D""keytag-modulo"
#define C_KEY_FILE "\x08""key-file"
#define C_KEY_LABEL "\x09""key-label"
#define C_KSK_LIFETIME "\x0C""ksk-lifetime"
diff --git a/src/knot/conf/tools.c b/src/knot/conf/tools.c
index 965c49c..e232fba 100644
--- a/src/knot/conf/tools.c
+++ b/src/knot/conf/tools.c
@@ -238,6 +238,13 @@ int check_ref(
bool found1 = false, found2 = false;
+ // Check if allowed empty value for specific zone items.
+ if (args->data_len == 1 && (args->item->flags & CONF_REF_EMPTY) &&
+ args->item->parent->name[0] == C_ZONE[0] &&
+ memcmp(&args->item->parent->name[1], &C_ZONE[1], C_ZONE[0]) == 0) {
+ return KNOT_EOK;
+ }
+
// Try to find the id in the first section.
found1 = conf_rawid_exists_txn(args->extra->conf, args->extra->txn,
ref->name, args->data, args->data_len);
@@ -963,15 +970,44 @@ int check_template(
#define CHECK_CATZ_TPL(option, option_string) \
{ \
- conf_val_t val = conf_rawid_get_txn(args->extra->conf, args->extra->txn, \
- C_TPL, option, catalog_tpl.data, \
- catalog_tpl.len); \
+ val = conf_rawid_get_txn(args->extra->conf, args->extra->txn, \
+ C_TPL, option, tpl->data, tpl->len); \
if (val.code == KNOT_EOK) { \
- args->err_str = "'" option_string "' in a catalog template"; \
+ args->err_str = "'" option_string "' not compatible with the role"; \
return KNOT_EINVAL; \
} \
}
+static int sub_check_catalog_tpl(
+ knotd_conf_check_args_t *args,
+ conf_val_t *tpl)
+{
+ conf_val_t val = conf_rawid_get_txn(args->extra->conf, args->extra->txn,
+ C_TPL, C_CATALOG_ROLE, tpl->data, tpl->len);
+ switch (conf_opt(&val)) {
+ case CATALOG_ROLE_MEMBER:
+ val = conf_rawid_get_txn(args->extra->conf, args->extra->txn,
+ C_TPL, C_CATALOG_ZONE, tpl->data, tpl->len);
+ if (val.code != KNOT_EOK) {
+ args->err_str = "no catalog zone defined";
+ return KNOT_EINVAL;
+ }
+ CHECK_CATZ_TPL(C_CATALOG_TPL, "catalog-template");
+ return KNOT_EOK;
+ case CATALOG_ROLE_INTERPRET:
+ args->err_str = "catalog role interpret in a catalog template";
+ return KNOT_EINVAL;
+ case CATALOG_ROLE_GENERATE:
+ args->err_str = "catalog role generate in a catalog template";
+ return KNOT_EINVAL;
+ default:
+ CHECK_CATZ_TPL(C_CATALOG_TPL, "catalog-template");
+ CHECK_CATZ_TPL(C_CATALOG_ZONE, "catalog-zone");
+ CHECK_CATZ_TPL(C_CATALOG_GROUP, "catalog-group");
+ return KNOT_EOK;
+ }
+}
+
int check_zone(
knotd_conf_check_args_t *args)
{
@@ -1057,10 +1093,9 @@ int check_zone(
if (role == CATALOG_ROLE_INTERPRET) {
conf_val(&catalog_tpl);
while (catalog_tpl.code == KNOT_EOK) {
- CHECK_CATZ_TPL(C_CATALOG_TPL, "catalog-template");
- CHECK_CATZ_TPL(C_CATALOG_ROLE, "catalog-role");
- CHECK_CATZ_TPL(C_CATALOG_ZONE, "catalog-zone");
- CHECK_CATZ_TPL(C_CATALOG_GROUP, "catalog-group");
+ if (sub_check_catalog_tpl(args, &catalog_tpl) != KNOT_EOK) {
+ return KNOT_EINVAL;
+ }
conf_val_next(&catalog_tpl);
}
}
diff --git a/src/knot/ctl/commands.c b/src/knot/ctl/commands.c
index 693bc59..c34709d 100644
--- a/src/knot/ctl/commands.c
+++ b/src/knot/ctl/commands.c
@@ -70,6 +70,20 @@ static struct {
sizeof(((send_ctx_t *)0)->rdata)];
} ctl_globals;
+static bool allow_blocking_while_ctl_txn(zone_event_type_t event)
+{
+ // this can be allowed for those events that do NOT create a zone_update_t
+ switch (event) {
+ case ZONE_EVENT_UFREEZE:
+ case ZONE_EVENT_UTHAW:
+ case ZONE_EVENT_NOTIFY:
+ case ZONE_EVENT_FLUSH:
+ return true;
+ default:
+ return false;
+ }
+}
+
/*!
* Evaluates a filter pair and checks for conflicting filters.
*
@@ -110,6 +124,10 @@ static int schedule_trigger(zone_t *zone, ctl_args_t *args, zone_event_type_t ev
int ret = KNOT_EOK;
if (ctl_has_flag(args->data[KNOT_CTL_IDX_FLAGS], CTL_FLAG_BLOCKING)) {
+ if (!allow_blocking_while_ctl_txn(event) &&
+ zone->control_update != NULL) {
+ return KNOT_TXN_EEXISTS;
+ }
ret = zone_events_schedule_blocking(zone, event, user);
} else if (user) {
zone_events_schedule_user(zone, event);
@@ -562,6 +580,10 @@ static int init_backup(ctl_args_t *args, bool restore_mode)
// Evaluate filters (and possibly fail) before writing to the filesystem.
knot_backup_params_t filters = 0;
knot_backup_params_t dflts = restore_mode ? BACKUP_PARAM_DFLT_R : BACKUP_PARAM_DFLT_B;
+
+ // Filter '+keysonly' silently changes all defaults to '+no...'.
+ dflts = MATCH_AND_FILTER(args, BACKUP_PARAM_KEYSONLY) ? BACKUP_PARAM_EMPTY : dflts;
+
for (const backup_filter_list_t *item = backup_filters; item->name != NULL; item++) {
if (!eval_backup_filters(args, &filters, item, dflts)) {
return KNOT_EXPARAM;
@@ -629,6 +651,12 @@ static int zone_backup_cmd(zone_t *zone, ctl_args_t *args)
return KNOT_EPROGRESS;
}
+ if (ctx->restore_mode && zone->control_update != NULL) {
+ log_zone_warning(zone->name, "restoring backup not possible due to open control transaction");
+ ctx->failed = true;
+ return KNOT_TXN_EEXISTS;
+ }
+
ctx->zone_count++;
int ret;
@@ -824,6 +852,11 @@ static int zone_txn_begin(zone_t *zone, _unused_ ctl_args_t *args)
return KNOT_TXN_EEXISTS;
}
+ if (zone->backup_ctx != NULL && zone->backup_ctx->restore_mode) {
+ log_zone_warning(zone->name, "zone restore pending, try opening control transaction later");
+ return KNOT_EAGAIN;
+ }
+
zone->control_update = malloc(sizeof(zone_update_t));
if (zone->control_update == NULL) {
return KNOT_ENOMEM;
diff --git a/src/knot/dnssec/context.c b/src/knot/dnssec/context.c
index 3413dba..c10e5c6 100644
--- a/src/knot/dnssec/context.c
+++ b/src/knot/dnssec/context.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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
@@ -24,6 +24,7 @@
#include "knot/dnssec/kasp/keystore.h"
#include "knot/dnssec/key_records.h"
#include "knot/server/dthreads.h"
+#include "knot/zone/serial.h"
knot_dynarray_define(parent, knot_kasp_parent_t, DYNARRAY_VISIBILITY_NORMAL)
@@ -168,6 +169,13 @@ static void policy_load(knot_kasp_policy_t *policy, conf_t *conf, conf_val_t *id
policy->unsafe |= conf_opt(&val);
conf_val_next(&val);
}
+
+ val = conf_id_get(conf, C_POLICY, C_KEYTAG_MODULO, id);
+ int ret = serial_modulo_parse(conf_str(&val), &policy->keytag_remain,
+ &policy->keytag_modulo);
+ if (ret != KNOT_EOK) {
+ assert(0); // cannot happen - ensured by conf check
+ }
}
int kdnssec_ctx_init(conf_t *conf, kdnssec_ctx_t *ctx, const knot_dname_t *zone_name,
diff --git a/src/knot/dnssec/ds_query.c b/src/knot/dnssec/ds_query.c
index 375bb50..2ac91cc 100644
--- a/src/knot/dnssec/ds_query.c
+++ b/src/knot/dnssec/ds_query.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
@@ -27,9 +27,9 @@
#include "knot/server/server.h"
#define DS_CHECK_LOG(priority, zone, remote, flags, fmt, ...) \
- ns_log(priority, zone, LOG_OPERATION_DS_CHECK, LOG_DIRECTION_OUT, remote, \
+ ns_log(priority, zone, LOG_OPERATION_DS_CHECK, LOG_DIRECTION_OUT, &(remote)->addr, \
((flags) & KNOT_REQUESTOR_QUIC) ? KNOTD_QUERY_PROTO_QUIC : KNOTD_QUERY_PROTO_TCP, \
- ((flags) & KNOT_REQUESTOR_REUSED), fmt, ## __VA_ARGS__)
+ ((flags) & KNOT_REQUESTOR_REUSED), (remote)->key.name, fmt, ## __VA_ARGS__)
static bool match_key_ds(knot_kasp_key_t *key, knot_rdata_t *ds)
{
@@ -72,7 +72,7 @@ struct ds_query_data {
conf_t *conf;
const knot_dname_t *zone_name;
- const struct sockaddr *remote;
+ const conf_remote_t *remote;
knot_kasp_key_t *key;
knot_kasp_key_t *not_key;
@@ -116,8 +116,8 @@ static int ds_query_consume(knot_layer_t *layer, knot_pkt_t *pkt)
uint16_t rcode = knot_pkt_ext_rcode(pkt);
if (rcode != KNOT_RCODE_NOERROR) {
DS_CHECK_LOG((rcode == KNOT_RCODE_NXDOMAIN ? LOG_NOTICE : LOG_WARNING),
- data->zone_name, data->remote, layer->flags,
- "failed (%s)", knot_pkt_ext_rcode_name(pkt));
+ data->zone_name, data->remote, layer->flags,
+ "failed (%s)", knot_pkt_ext_rcode_name(pkt));
return KNOT_STATE_FAIL;
}
@@ -179,7 +179,7 @@ static int try_ds(conf_t *conf, const knot_dname_t *zone_name, const conf_remote
struct ds_query_data data = {
.zone_name = zone_name,
- .remote = (struct sockaddr *)&parent->addr,
+ .remote = parent,
.key = key,
.not_key = not_key,
.edns = query_edns_data_init(conf, parent, QUERY_EDNS_OPT_DO),
@@ -214,7 +214,7 @@ static int try_ds(conf_t *conf, const knot_dname_t *zone_name, const conf_remote
if (ret != KNOT_EOK && !data.result_logged) {
DS_CHECK_LOG(LOG_WARNING, zone_name, data.remote, requestor.layer.flags,
- "failed (%s)", knot_strerror(ret));
+ "failed (%s)", knot_strerror(ret));
}
*ds_ttl = data.ttl;
diff --git a/src/knot/dnssec/kasp/policy.h b/src/knot/dnssec/kasp/policy.h
index b70ac6c..d895d48 100644
--- a/src/knot/dnssec/kasp/policy.h
+++ b/src/knot/dnssec/kasp/policy.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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
@@ -132,5 +132,7 @@ typedef struct {
bool incremental;
bool key_label;
unsigned unsafe;
+ uint32_t keytag_remain;
+ uint32_t keytag_modulo;
} knot_kasp_policy_t;
// TODO make the time parameters knot_timediff_t ??
diff --git a/src/knot/dnssec/zone-events.c b/src/knot/dnssec/zone-events.c
index f2f6d93..faf093d 100644
--- a/src/knot/dnssec/zone-events.c
+++ b/src/knot/dnssec/zone-events.c
@@ -191,6 +191,9 @@ int knot_dnssec_zone_sign(zone_update_t *update,
ctx.rrsig_drop_existing = flags & ZONE_SIGN_DROP_SIGNATURES;
+ // create placeholder ZONEMD to be signed and later filled in
+ // ...or remove it if zonemd_alg == ZONE_DIGEST_REMOVE
+ // removing non-existent ZONEMD is ok
conf_val_t val = conf_zone_get(conf, C_ZONEMD_GENERATE, zone_name);
unsigned zonemd_alg = conf_opt(&val);
if (zonemd_alg != ZONE_DIGEST_NONE) {
@@ -285,7 +288,9 @@ int knot_dnssec_zone_sign(zone_update_t *update,
}
}
- if (zonemd_alg != ZONE_DIGEST_NONE) {
+ // fill in ZONEMD if desired
+ // if (zonemd_alg == ZONE_DIGEST_REMOVE), ZONEMD was already removed above, so skip this
+ if (zonemd_alg != ZONE_DIGEST_NONE && zonemd_alg != ZONE_DIGEST_REMOVE) {
result = zone_update_add_digest(update, zonemd_alg, false);
if (result == KNOT_EOK) {
result = knot_zone_sign_apex_rr(update, KNOT_RRTYPE_ZONEMD, &keyset, &ctx);
@@ -335,6 +340,9 @@ int knot_dnssec_sign_update(zone_update_t *update, conf_t *conf)
update_policy_from_zone(ctx.policy, update->new_cont);
+ // create placeholder ZONEMD to be signed and later filled in
+ // ...or remove it & its RRSIGs if zonemd_alg == ZONE_DIGEST_REMOVE
+ // removing non-existent ZONEMD is ok
conf_val_t val = conf_zone_get(conf, C_ZONEMD_GENERATE, zone_name);
unsigned zonemd_alg = conf_opt(&val);
if (zonemd_alg != ZONE_DIGEST_NONE) {
@@ -412,7 +420,9 @@ int knot_dnssec_sign_update(zone_update_t *update, conf_t *conf)
goto done;
}
- if (zonemd_alg != ZONE_DIGEST_NONE) {
+ // fill in ZONEMD if desired
+ // if (zonemd_alg == ZONE_DIGEST_REMOVE), ZONEMD was already removed above, so skip this
+ if (zonemd_alg != ZONE_DIGEST_NONE && zonemd_alg != ZONE_DIGEST_REMOVE) {
result = zone_update_add_digest(update, zonemd_alg, false);
if (result == KNOT_EOK) {
result = knot_zone_sign_apex_rr(update, KNOT_RRTYPE_ZONEMD, &keyset, &ctx);
diff --git a/src/knot/dnssec/zone-keys.c b/src/knot/dnssec/zone-keys.c
index af8226c..05faac8 100644
--- a/src/knot/dnssec/zone-keys.c
+++ b/src/knot/dnssec/zone-keys.c
@@ -104,7 +104,7 @@ static bool keytag_in_use(kdnssec_ctx_t *ctx, uint16_t keytag)
return false;
}
-#define GENERATE_KEYTAG_ATTEMPTS (20)
+#define GENERATE_KEYTAG_ATTEMPTS (40)
static int generate_keytag_unconflict(kdnssec_ctx_t *ctx,
kdnssec_generate_flags_t flags,
@@ -131,7 +131,9 @@ static int generate_keytag_unconflict(kdnssec_ctx_t *ctx,
if (ret != KNOT_EOK) {
return ret;
}
- if (!keytag_in_use(ctx, dnssec_key_get_keytag(*key))) {
+ uint16_t keytag = dnssec_key_get_keytag(*key);
+ if (!keytag_in_use(ctx, keytag) &&
+ keytag % ctx->policy->keytag_modulo == ctx->policy->keytag_remain) {
return KNOT_EOK;
}
diff --git a/src/knot/events/handlers/dnskey_sync.c b/src/knot/events/handlers/dnskey_sync.c
index 8e6d823..c6d80ff 100644
--- a/src/knot/events/handlers/dnskey_sync.c
+++ b/src/knot/events/handlers/dnskey_sync.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
@@ -25,9 +25,9 @@
#include "libknot/errcode.h"
#define DNSKEY_SYNC_LOG(priority, zone, remote, flags, fmt, ...) \
- ns_log(priority, zone, LOG_OPERATION_DNSKEY_SYNC, LOG_DIRECTION_OUT, remote, \
+ ns_log(priority, zone, LOG_OPERATION_DNSKEY_SYNC, LOG_DIRECTION_OUT, &(remote)->addr, \
((flags) & KNOT_REQUESTOR_QUIC) ? KNOTD_QUERY_PROTO_QUIC : KNOTD_QUERY_PROTO_TCP, \
- ((flags) & KNOT_REQUESTOR_REUSED), fmt, ## __VA_ARGS__)
+ ((flags) & KNOT_REQUESTOR_REUSED), (remote)->key.name, fmt, ## __VA_ARGS__)
static const unsigned remote_rrs[] = { KNOT_RRTYPE_DNSKEY, KNOT_RRTYPE_CDNSKEY, KNOT_RRTYPE_CDS };
#define REMOTE_NTYPES (sizeof(remote_rrs) / sizeof(remote_rrs[0]))
@@ -36,7 +36,7 @@ struct dnskey_sync_data {
zone_t *zone;
knot_rrset_t *rem_rr[REMOTE_NTYPES];
knot_rrset_t *add_rr[REMOTE_NTYPES];
- const struct sockaddr *remote;
+ const conf_remote_t *remote;
query_edns_data_t edns;
bool uptodate;
bool ddns_sent;
@@ -235,7 +235,7 @@ static int send_dnskey_sync(conf_t *conf, zone_t *zone, bool *uptodate,
{
struct dnskey_sync_data data = {
.zone = zone,
- .remote = (struct sockaddr *)&remote->addr,
+ .remote = remote,
.edns = query_edns_data_init(conf, remote, 0)
};
@@ -264,14 +264,14 @@ static int send_dnskey_sync(conf_t *conf, zone_t *zone, bool *uptodate,
}
if (data.ddns_sent && ret == KNOT_ETIMEOUT) {
- DNSKEY_SYNC_LOG(LOG_WARNING, zone->name, &remote->addr, requestor.layer.flags,
+ DNSKEY_SYNC_LOG(LOG_WARNING, zone->name, remote, requestor.layer.flags,
"timed out, may be caused by parallel mutual DNSKEY sync, "
"may settle down after check-interval");
ret = KNOT_EOK;
}
if (ret != KNOT_EOK) {
- DNSKEY_SYNC_LOG(LOG_ERR, zone->name, &remote->addr, requestor.layer.flags,
+ DNSKEY_SYNC_LOG(LOG_ERR, zone->name, remote, requestor.layer.flags,
"failed (%s)", knot_strerror(ret));
}
diff --git a/src/knot/events/handlers/ds_push.c b/src/knot/events/handlers/ds_push.c
index 5a3a9bb..be7621f 100644
--- a/src/knot/events/handlers/ds_push.c
+++ b/src/knot/events/handlers/ds_push.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
@@ -30,16 +30,16 @@ struct ds_push_data {
knot_dname_t *parent_soa;
knot_rrset_t del_old_ds;
knot_rrset_t new_ds;
- const struct sockaddr *remote;
+ const conf_remote_t *remote;
query_edns_data_t edns;
};
#define DS_PUSH_RETRY 600
#define DS_PUSH_LOG(priority, zone, remote, flags, fmt, ...) \
- ns_log(priority, zone, LOG_OPERATION_DS_PUSH, LOG_DIRECTION_OUT, remote, \
+ ns_log(priority, zone, LOG_OPERATION_DS_PUSH, LOG_DIRECTION_OUT, &(remote)->addr, \
((flags) & KNOT_REQUESTOR_QUIC) ? KNOTD_QUERY_PROTO_QUIC : KNOTD_QUERY_PROTO_TCP, \
- ((flags) & KNOT_REQUESTOR_REUSED), fmt, ## __VA_ARGS__)
+ ((flags) & KNOT_REQUESTOR_REUSED), (remote)->key.name, fmt, ## __VA_ARGS__)
static const knot_rdata_t remove_cds = { 5, { 0, 0, 0, 0, 0 } };
@@ -172,7 +172,7 @@ static int send_ds_push(conf_t *conf, zone_t *zone,
.zone = zone->name,
.parent_query = zone->name,
.new_ds = zone_cds,
- .remote = (struct sockaddr *)&parent->addr,
+ .remote = parent,
.edns = query_edns_data_init(conf, parent, 0)
};
@@ -203,13 +203,13 @@ static int send_ds_push(conf_t *conf, zone_t *zone,
ret = knot_requestor_exec(&requestor, req, timeout);
if (ret == KNOT_EOK && knot_pkt_ext_rcode(req->resp) == 0) {
- DS_PUSH_LOG(LOG_INFO, zone->name, &parent->addr, requestor.layer.flags,
+ DS_PUSH_LOG(LOG_INFO, zone->name, parent, requestor.layer.flags,
"success");
} else if (knot_pkt_ext_rcode(req->resp) == 0) {
- DS_PUSH_LOG(LOG_WARNING, zone->name, &parent->addr, requestor.layer.flags,
+ DS_PUSH_LOG(LOG_WARNING, zone->name, parent, requestor.layer.flags,
"failed (%s)", knot_strerror(ret));
} else {
- DS_PUSH_LOG(LOG_WARNING, zone->name, &parent->addr, requestor.layer.flags,
+ DS_PUSH_LOG(LOG_WARNING, zone->name, parent, requestor.layer.flags,
"server responded with error '%s'",
knot_pkt_ext_rcode_name(req->resp));
}
diff --git a/src/knot/events/handlers/notify.c b/src/knot/events/handlers/notify.c
index ccddf88..9dae70a 100644
--- a/src/knot/events/handlers/notify.c
+++ b/src/knot/events/handlers/notify.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
@@ -15,6 +15,7 @@
*/
#include <assert.h>
+#include <urcu.h>
#include "contrib/openbsd/siphash.h"
#include "knot/common/log.h"
@@ -40,7 +41,7 @@ static notifailed_rmt_hash notifailed_hash(conf_val_t *rmt_id)
struct notify_data {
const knot_dname_t *zone;
const knot_rrset_t *soa;
- const struct sockaddr *remote;
+ const conf_remote_t *remote;
query_edns_data_t edns;
};
@@ -82,9 +83,9 @@ static const knot_layer_api_t NOTIFY_API = {
};
#define NOTIFY_OUT_LOG(priority, zone, remote, flags, fmt, ...) \
- ns_log(priority, zone, LOG_OPERATION_NOTIFY, LOG_DIRECTION_OUT, remote, \
+ ns_log(priority, zone, LOG_OPERATION_NOTIFY, LOG_DIRECTION_OUT, &(remote)->addr, \
((flags) & KNOT_REQUESTOR_QUIC) ? KNOTD_QUERY_PROTO_QUIC : KNOTD_QUERY_PROTO_TCP, \
- ((flags) & KNOT_REQUESTOR_REUSED), fmt, ## __VA_ARGS__)
+ ((flags) & KNOT_REQUESTOR_REUSED), (remote)->key.name, fmt, ## __VA_ARGS__)
static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa,
const conf_remote_t *slave, int timeout, bool retry)
@@ -92,7 +93,7 @@ static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa,
struct notify_data data = {
.zone = zone->name,
.soa = soa,
- .remote = (struct sockaddr *)&slave->addr,
+ .remote = slave,
.edns = query_edns_data_init(conf, slave, 0)
};
@@ -118,16 +119,16 @@ static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa,
const char *log_retry = retry ? "retry, " : "";
if (ret == KNOT_EOK && knot_pkt_ext_rcode(req->resp) == 0) {
- NOTIFY_OUT_LOG(LOG_INFO, zone->name, &slave->addr,
+ NOTIFY_OUT_LOG(LOG_INFO, zone->name, slave,
requestor.layer.flags,
"%sserial %u", log_retry, knot_soa_serial(soa->rrs.rdata));
zone->timers.last_notified_serial = (knot_soa_serial(soa->rrs.rdata) | LAST_NOTIFIED_SERIAL_VALID);
} else if (knot_pkt_ext_rcode(req->resp) == 0) {
- NOTIFY_OUT_LOG(LOG_WARNING, zone->name, &slave->addr,
+ NOTIFY_OUT_LOG(LOG_WARNING, zone->name, slave,
requestor.layer.flags,
"%sfailed (%s)", log_retry, knot_strerror(ret));
} else {
- NOTIFY_OUT_LOG(LOG_WARNING, zone->name, &slave->addr,
+ NOTIFY_OUT_LOG(LOG_WARNING, zone->name, slave,
requestor.layer.flags,
"%sserver responded with error '%s'",
log_retry, knot_pkt_ext_rcode_name(req->resp));
@@ -151,7 +152,13 @@ int event_notify(conf_t *conf, zone_t *zone)
// NOTIFY content
int timeout = conf->cache.srv_tcp_remote_io_timeout;
+ rcu_read_lock();
knot_rrset_t soa = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
+ knot_rrset_t *soa_cpy = knot_rrset_copy(&soa, NULL);
+ rcu_read_unlock();
+ if (soa_cpy == NULL) {
+ return KNOT_ENOMEM;
+ }
// in case of re-try, NOTIFY only failed remotes
pthread_mutex_lock(&zone->preferred_lock);
@@ -176,7 +183,7 @@ int event_notify(conf_t *conf, zone_t *zone)
for (int i = 0; i < addr_count; i++) {
conf_remote_t slave = conf_remote(conf, iter.id, i);
- ret = send_notify(conf, zone, &soa, &slave, timeout, retry);
+ ret = send_notify(conf, zone, soa_cpy, &slave, timeout, retry);
if (ret == KNOT_EOK) {
break;
}
@@ -196,7 +203,7 @@ int event_notify(conf_t *conf, zone_t *zone)
if (failed) {
notifailed_rmt_dynarray_sort_dedup(&zone->notifailed);
- uint32_t retry_in = knot_soa_retry(soa.rrs.rdata);
+ uint32_t retry_in = knot_soa_retry(soa_cpy->rrs.rdata);
conf_val_t val = conf_zone_get(conf, C_RETRY_MIN_INTERVAL, zone->name);
retry_in = MAX(retry_in, conf_int(&val));
val = conf_zone_get(conf, C_RETRY_MAX_INTERVAL, zone->name);
@@ -205,6 +212,7 @@ int event_notify(conf_t *conf, zone_t *zone)
zone_events_schedule_at(zone, ZONE_EVENT_NOTIFY, time(NULL) + retry_in);
}
pthread_mutex_unlock(&zone->preferred_lock);
+ knot_rrset_free(soa_cpy, NULL);
return failed ? KNOT_ERROR : KNOT_EOK;
}
diff --git a/src/knot/events/handlers/refresh.c b/src/knot/events/handlers/refresh.c
index 32ee68d..83fb376 100644
--- a/src/knot/events/handlers/refresh.c
+++ b/src/knot/events/handlers/refresh.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
@@ -72,15 +72,15 @@
#define REFRESH_LOG(priority, data, msg...) \
ns_log(priority, (data)->zone->name, LOG_OPERATION_REFRESH, LOG_DIRECTION_NONE, \
- (data)->remote, 0, false, msg)
+ &(data)->remote->addr, 0, false, (data)->remote->key.name, msg)
#define AXFRIN_LOG(priority, data, msg...) \
ns_log(priority, (data)->zone->name, LOG_OPERATION_AXFR, LOG_DIRECTION_IN, \
- (data)->remote, PROTO(data), (data)->layer->flags & KNOT_REQUESTOR_REUSED, msg)
+ &(data)->remote->addr, PROTO(data), (data)->layer->flags & KNOT_REQUESTOR_REUSED, (data)->remote->key.name, msg)
#define IXFRIN_LOG(priority, data, msg...) \
ns_log(priority, (data)->zone->name, LOG_OPERATION_IXFR, LOG_DIRECTION_IN, \
- (data)->remote, PROTO(data), (data)->layer->flags & KNOT_REQUESTOR_REUSED, msg)
+ &(data)->remote->addr, PROTO(data), (data)->layer->flags & KNOT_REQUESTOR_REUSED, (data)->remote->key.name, msg)
enum state {
REFRESH_STATE_INVALID = 0,
@@ -104,7 +104,7 @@ struct refresh_data {
zone_t *zone; //!< Zone to eventually updated.
conf_t *conf; //!< Server configuration.
- const struct sockaddr *remote; //!< Remote endpoint.
+ const conf_remote_t *remote; //!< Remote endpoint.
const knot_rrset_t *soa; //!< Local SOA (NULL for AXFR).
const size_t max_zone_size; //!< Maximal zone size.
query_edns_data_t edns; //!< EDNS data to be used in queries.
@@ -1196,10 +1196,10 @@ static int transfer_consume(knot_layer_t *layer, knot_pkt_t *pkt)
data->xfr_type == XFR_TYPE_IXFR ||
data->xfr_type == XFR_TYPE_UPTODATE ?
LOG_OPERATION_IXFR : LOG_OPERATION_AXFR,
- LOG_DIRECTION_IN, data->remote,
+ LOG_DIRECTION_IN, &data->remote->addr,
(layer->flags & KNOT_REQUESTOR_QUIC ?
KNOTD_QUERY_PROTO_QUIC : KNOTD_QUERY_PROTO_TCP),
- &data->stats);
+ data->remote->key.name, &data->stats);
/*
* TODO: Move finialization into finish
@@ -1340,7 +1340,7 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master,
struct refresh_data data = {
.zone = zone,
.conf = conf,
- .remote = (struct sockaddr *)&master->addr,
+ .remote = master,
.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),
diff --git a/src/knot/events/handlers/update.c b/src/knot/events/handlers/update.c
index b868273..b4092a3 100644
--- a/src/knot/events/handlers/update.c
+++ b/src/knot/events/handlers/update.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
@@ -33,8 +33,8 @@
#define UPDATE_LOG(priority, qdata, fmt...) \
ns_log(priority, knot_pkt_qname(qdata->query), LOG_OPERATION_UPDATE, \
- LOG_DIRECTION_IN, (struct sockaddr *)knotd_qdata_remote_addr(qdata), \
- qdata->params->proto, false, fmt)
+ LOG_DIRECTION_IN, (qdata)->params->remote, \
+ (qdata)->params->proto, false, (qdata)->sign.tsig_key.name, fmt)
static void init_qdata_from_request(knotd_qdata_t *qdata,
zone_t *zone,
diff --git a/src/knot/modules/authsignal/authsignal.rst b/src/knot/modules/authsignal/authsignal.rst
index 01043a1..d3a52ad 100644
--- a/src/knot/modules/authsignal/authsignal.rst
+++ b/src/knot/modules/authsignal/authsignal.rst
@@ -18,6 +18,7 @@ Automatic forward records
.........................
::
+
mod-onlinesign:
- id: authsignal
nsec-bitmap: [CDS, CDNSKEY]
diff --git a/src/knot/modules/dnstap/dnstap.c b/src/knot/modules/dnstap/dnstap.c
index c8c82ea..612e488 100644
--- a/src/knot/modules/dnstap/dnstap.c
+++ b/src/knot/modules/dnstap/dnstap.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
@@ -185,6 +185,33 @@ 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)
{
@@ -213,17 +240,42 @@ finish:
}
/*! \brief Create a log sink according to the path string. */
-static struct fstrm_writer* dnstap_writer(const char *path)
+static struct fstrm_writer* dnstap_writer(knotd_mod_t *mod, const char *path)
{
- const char *prefix = "unix:";
- const size_t prefix_len = strlen(prefix);
+ 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);
/* UNIX socket prefix. */
- if (strlen(path) > prefix_len && strncmp(path, prefix, prefix_len) == 0) {
- return dnstap_unix_writer(path + prefix_len);
+ 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);
}
-
- return dnstap_file_writer(path);
}
int dnstap_load(knotd_mod_t *mod)
@@ -273,7 +325,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(sink);
+ struct fstrm_writer *writer = dnstap_writer(mod, sink);
if (writer == NULL) {
goto fail;
}
@@ -307,13 +359,13 @@ int dnstap_load(knotd_mod_t *mod)
return KNOT_EOK;
fail:
- knotd_mod_log(mod, LOG_ERR, "failed to init sink '%s'", sink);
+ knotd_mod_log(mod, LOG_ERR, "failed to initialize sink '%s'", sink);
free(ctx->identity);
free(ctx->version);
free(ctx);
- return KNOT_ENOMEM;
+ return KNOT_EINVAL;
}
void dnstap_unload(knotd_mod_t *mod)
diff --git a/src/knot/modules/dnstap/dnstap.rst b/src/knot/modules/dnstap/dnstap.rst
index 358977d..05eac09 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 or a UNIX socket::
+which can be either a file, a UNIX socket, or a TCP address::
mod-dnstap:
- id: capture_all
@@ -60,9 +60,10 @@ A module identifier.
sink
....
-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.
+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.
*Required*
diff --git a/src/knot/nameserver/axfr.c b/src/knot/nameserver/axfr.c
index 677e241..dcd62e9 100644
--- a/src/knot/nameserver/axfr.c
+++ b/src/knot/nameserver/axfr.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
@@ -25,12 +25,13 @@
#include "libknot/libknot.h"
#define ZONE_NAME(qdata) knot_pkt_qname((qdata)->query)
-#define REMOTE(qdata) (struct sockaddr *)knotd_qdata_remote_addr(qdata)
+#define REMOTE(qdata) (qdata)->params->remote
#define PROTO(qdata) (qdata)->params->proto
+#define KEY(qdata) (qdata)->sign.tsig_key.name
#define AXFROUT_LOG(priority, qdata, fmt...) \
ns_log(priority, ZONE_NAME(qdata), LOG_OPERATION_AXFR, \
- LOG_DIRECTION_OUT, REMOTE(qdata), PROTO(qdata), false, fmt)
+ LOG_DIRECTION_OUT, REMOTE(qdata), PROTO(qdata), false, KEY(qdata), fmt)
/* AXFR context. @note aliasing the generic xfr_proc */
struct axfr_proc {
@@ -120,7 +121,7 @@ static void axfr_answer_finished(knotd_qdata_t *qdata, knot_pkt_t *pkt, int stat
xfr_stats_add(&xfr->stats, pkt->size);
xfr_stats_end(&xfr->stats);
xfr_log_finished(ZONE_NAME(qdata), LOG_OPERATION_AXFR, LOG_DIRECTION_OUT,
- REMOTE(qdata), PROTO(qdata), &xfr->stats);
+ REMOTE(qdata), PROTO(qdata), KEY(qdata), &xfr->stats);
break;
default:
break;
diff --git a/src/knot/nameserver/ixfr.c b/src/knot/nameserver/ixfr.c
index ea15273..b57759c 100644
--- a/src/knot/nameserver/ixfr.c
+++ b/src/knot/nameserver/ixfr.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
@@ -28,12 +28,13 @@
#include "libknot/libknot.h"
#define ZONE_NAME(qdata) knot_pkt_qname((qdata)->query)
-#define REMOTE(qdata) (struct sockaddr *)knotd_qdata_remote_addr(qdata)
+#define REMOTE(qdata) (qdata)->params->remote
#define PROTO(qdata) (qdata)->params->proto
+#define KEY(qdata) (qdata)->sign.tsig_key.name
#define IXFROUT_LOG(priority, qdata, fmt...) \
ns_log(priority, ZONE_NAME(qdata), LOG_OPERATION_IXFR, \
- LOG_DIRECTION_OUT, REMOTE(qdata), PROTO(qdata), false, fmt)
+ LOG_DIRECTION_OUT, REMOTE(qdata), PROTO(qdata), false, KEY(qdata), fmt)
/*! \brief Helper macro for putting RRs into packet. */
#define IXFR_SAFE_PUT(pkt, rr) \
@@ -173,7 +174,7 @@ static void ixfr_answer_finished(knotd_qdata_t *qdata, knot_pkt_t *pkt, int stat
xfr_stats_add(&xfr->stats, pkt->size);
xfr_stats_end(&xfr->stats);
xfr_log_finished(ZONE_NAME(qdata), LOG_OPERATION_IXFR, LOG_DIRECTION_OUT,
- REMOTE(qdata), PROTO(qdata), &xfr->stats);
+ REMOTE(qdata), PROTO(qdata), KEY(qdata), &xfr->stats);
break;
default:
break;
diff --git a/src/knot/nameserver/log.h b/src/knot/nameserver/log.h
index 752de55..5a5d5f0 100644
--- a/src/knot/nameserver/log.h
+++ b/src/knot/nameserver/log.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
@@ -88,16 +88,16 @@ static inline const char *log_conn_info(knotd_query_proto_t proto, bool pool)
/*!
* \brief Generate log message for server communication.
- *
- * Example output:
- *
- * [example.com] NOTIFY, outgoing, remote 2001:db8::1@53, serial 123
*/
-#define ns_log(priority, zone, op, dir, remote, proto, pool, fmt, ...) \
+#define ns_log(priority, zone, op, dir, remote, proto, pool, key, fmt, ...) \
do { \
+ knot_dname_txt_storage_t key_str; \
char address[SOCKADDR_STRLEN] = ""; \
- sockaddr_tostr(address, sizeof(address), (const struct sockaddr_storage *)remote); \
- log_fmt_zone(priority, LOG_SOURCE_ZONE, zone, NULL, "%s%s, remote %s%s, " fmt, \
+ sockaddr_tostr(address, sizeof(address), remote); \
+ (void)knot_dname_to_str(key_str, key, sizeof(key_str)); \
+ log_fmt_zone(priority, LOG_SOURCE_ZONE, zone, NULL, "%s%s, remote %s%s, %s%s%s" fmt, \
log_operation_name(op), log_direction_name(dir), address, \
- log_conn_info(proto, pool), ## __VA_ARGS__); \
+ log_conn_info(proto, pool), (key != NULL ? "key " : ""), \
+ (key != NULL ? key_str : ""), (key != NULL ? ", " : ""), \
+ ## __VA_ARGS__); \
} while (0)
diff --git a/src/knot/nameserver/notify.c b/src/knot/nameserver/notify.c
index f5c5ee5..eaa305a 100644
--- a/src/knot/nameserver/notify.c
+++ b/src/knot/nameserver/notify.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
@@ -26,8 +26,8 @@
#define NOTIFY_IN_LOG(priority, qdata, fmt...) \
ns_log(priority, knot_pkt_qname(qdata->query), LOG_OPERATION_NOTIFY, \
- LOG_DIRECTION_IN, knotd_qdata_remote_addr(qdata), qdata->params->proto, \
- false, fmt)
+ LOG_DIRECTION_IN, (qdata)->params->remote, (qdata)->params->proto, \
+ false, (qdata)->sign.tsig_key.name, fmt)
static int notify_check_query(knotd_qdata_t *qdata)
{
diff --git a/src/knot/nameserver/xfr.h b/src/knot/nameserver/xfr.h
index 94a5621..e6d06b6 100644
--- a/src/knot/nameserver/xfr.h
+++ b/src/knot/nameserver/xfr.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
@@ -36,10 +36,11 @@ void xfr_stats_end(struct xfr_stats *stats);
static inline
void xfr_log_finished(const knot_dname_t *zone, log_operation_t op,
- log_direction_t dir, const struct sockaddr *remote,
- knotd_query_proto_t proto, const struct xfr_stats *stats)
+ log_direction_t dir, const struct sockaddr_storage *remote,
+ knotd_query_proto_t proto, const knot_dname_t *key_name,
+ const struct xfr_stats *stats)
{
- ns_log(LOG_INFO, zone, op, dir, remote, proto, false,
+ ns_log(LOG_INFO, zone, op, dir, remote, proto, false, key_name,
"%sfinished, %0.2f seconds, %u messages, %u bytes",
(proto == KNOTD_QUERY_PROTO_QUIC && dir == LOG_DIRECTION_OUT ? "buffering " : ""),
time_diff_ms(&stats->begin, &stats->end) / 1000.0,
diff --git a/src/knot/server/xdp-handler.c b/src/knot/server/xdp-handler.c
index 11eeeb6..ae8512d 100644
--- a/src/knot/server/xdp-handler.c
+++ b/src/knot/server/xdp-handler.c
@@ -83,6 +83,20 @@ void xdp_handle_reconfigure(xdp_handle_ctx_t *ctx)
void xdp_handle_free(xdp_handle_ctx_t *ctx)
{
+ // send RST on all existing conns
+ knot_tcp_relay_t sweep_relays[XDP_BATCHLEN] = { 0 };
+ int ret = KNOT_EOK;
+ while (ret == KNOT_EOK && ctx->tcp_table != NULL && ctx->tcp_table->usage > 0) {
+ knot_xdp_send_prepare(ctx->sock);
+ ret = knot_tcp_sweep(ctx->tcp_table, UINT32_MAX, 1, UINT32_MAX, UINT32_MAX, SIZE_MAX,
+ SIZE_MAX, sweep_relays, XDP_BATCHLEN, &ctx->tcp_closed);
+ if (ret == KNOT_EOK) {
+ ret = knot_tcp_send(ctx->sock, sweep_relays, XDP_BATCHLEN, XDP_BATCHLEN);
+ }
+ knot_tcp_cleanup(ctx->tcp_table, sweep_relays, XDP_BATCHLEN);
+ (void)knot_xdp_send_finish(ctx->sock);
+ }
+
knot_tcp_table_free(ctx->tcp_table);
knot_tcp_table_free(ctx->syn_table);
#ifdef ENABLE_QUIC
diff --git a/src/knot/updates/zone-update.c b/src/knot/updates/zone-update.c
index 64ce179..73c9558 100644
--- a/src/knot/updates/zone-update.c
+++ b/src/knot/updates/zone-update.c
@@ -979,7 +979,7 @@ int zone_update_commit(conf_t *conf, zone_update_t *update)
return ret;
}
- if (dnssec && zone_is_slave(conf, update->zone)) {
+ if (dnssec) {
ret = zone_set_lastsigned_serial(update->zone,
zone_contents_serial(update->new_cont));
if (ret != KNOT_EOK) {
diff --git a/src/knot/zone/backup.h b/src/knot/zone/backup.h
index d3ae07d..9f2660d 100644
--- a/src/knot/zone/backup.h
+++ b/src/knot/zone/backup.h
@@ -49,6 +49,9 @@ typedef enum {
#define BACKUP_PARAM_DFLT_R (BACKUP_PARAM_ZONEFILE | BACKUP_PARAM_TIMERS | \
BACKUP_PARAM_KASPDB | BACKUP_PARAM_CATALOG)
+/*! \bref Empty defaults. */
+#define BACKUP_PARAM_EMPTY 0
+
/*! \bref Backup components done in event. */
#define BACKUP_PARAM_EVENT (BACKUP_PARAM_ZONEFILE | BACKUP_PARAM_JOURNAL | \
BACKUP_PARAM_TIMERS | BACKUP_PARAM_KASPDB | \
diff --git a/src/knot/zone/zone.c b/src/knot/zone/zone.c
index d0fbde4..6bdfb1d 100644
--- a/src/knot/zone/zone.c
+++ b/src/knot/zone/zone.c
@@ -704,7 +704,7 @@ int zone_master_try(conf_t *conf, zone_t *zone, zone_master_cb callback,
true, true, preferred_idx == last_idx, pin_tolerance
};
ret = try_remote(conf, zone, callback, callback_data, err_str,
- preferred_id, &preferred, &fallback, "notifying ");
+ preferred_id, &preferred, &fallback, "notifier ");
if (ret == KNOT_EOK || !fallback.remote) {
return ret; // Success or local error.
}
diff --git a/src/libdnssec/version.h b/src/libdnssec/version.h
index 0368f18..ad691c7 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 0x05
+#define DNSSEC_VERSION_PATCH 0x06
#define DNSSEC_VERSION_HEX ((DNSSEC_VERSION_MAJOR << 16) | \
(DNSSEC_VERSION_MINOR << 8) | \
diff --git a/src/libknot/control/control.c b/src/libknot/control/control.c
index 8656057..671896f 100644
--- a/src/libknot/control/control.c
+++ b/src/libknot/control/control.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
@@ -37,7 +37,7 @@
#endif
/*! Listen backlog size. */
-#define LISTEN_BACKLOG 5
+#define DEFAULT_LISTEN_BACKLOG 5
/*! Default socket operations timeout in milliseconds. */
#define DEFAULT_TIMEOUT (30 * 1000)
@@ -196,6 +196,12 @@ void knot_ctl_set_timeout(knot_ctl_t *ctx, int timeout_ms)
_public_
int knot_ctl_bind(knot_ctl_t *ctx, const char *path)
{
+ return knot_ctl_bind2(ctx, path, DEFAULT_LISTEN_BACKLOG);
+}
+
+_public_
+int knot_ctl_bind2(knot_ctl_t *ctx, const char *path, unsigned backlog)
+{
if (ctx == NULL || path == NULL) {
return KNOT_EINVAL;
}
@@ -215,7 +221,7 @@ int knot_ctl_bind(knot_ctl_t *ctx, const char *path)
}
// Start listening.
- if (listen(ctx->listen_sock, LISTEN_BACKLOG) != 0) {
+ if (listen(ctx->listen_sock, backlog) != 0) {
close_sock(&ctx->listen_sock);
return knot_map_errno();
}
diff --git a/src/libknot/control/control.h b/src/libknot/control/control.h
index 1d3dcd1..8ab1e10 100644
--- a/src/libknot/control/control.h
+++ b/src/libknot/control/control.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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,6 +94,11 @@ void knot_ctl_set_timeout(knot_ctl_t *ctx, int timeout_ms);
int knot_ctl_bind(knot_ctl_t *ctx, const char *path);
/*!
+ * Same as knot_ctl_bind() with socket backlog specification.
+ */
+int knot_ctl_bind2(knot_ctl_t *ctx, const char *path, unsigned backlog);
+
+/*!
* Unbinds a control socket.
*
* \note Server operation.
diff --git a/src/libknot/quic/quic.c b/src/libknot/quic/quic.c
index 5e447e7..f9d1d1d 100644
--- a/src/libknot/quic/quic.c
+++ b/src/libknot/quic/quic.c
@@ -44,6 +44,7 @@
#include "libknot/wire.h"
#define SERVER_DEFAULT_SCIDLEN 18
+#define QUIC_REGULAR_TOKEN_TIMEOUT (24 * 3600 * 1000000000LLU)
#define QUIC_DEFAULT_VERSION "-VERS-ALL:+VERS-TLS1.3"
#define QUIC_DEFAULT_GROUPS "-GROUP-ALL:+GROUP-X25519:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-SECP521R1"
@@ -971,14 +972,25 @@ int knot_quic_handle(knot_quic_table_t *table, knot_quic_reply_t *reply,
}
if (header.tokenlen > 0) {
- ret = ngtcp2_crypto_verify_retry_token(
- &odcid, header.token, header.tokenlen,
- (const uint8_t *)table->hash_secret,
- sizeof(table->hash_secret), header.version,
- (const struct sockaddr *)reply->ip_rem,
- addr_len((struct sockaddr_in6 *)reply->ip_rem),
- &dcid, idle_timeout, now // NOTE setting retry token validity to idle_timeout for simplicity
- );
+ if (header.token[0] == NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY) {
+ ret = ngtcp2_crypto_verify_retry_token(
+ &odcid, header.token, header.tokenlen,
+ (const uint8_t *)table->hash_secret,
+ sizeof(table->hash_secret), header.version,
+ (const struct sockaddr *)reply->ip_rem,
+ addr_len((struct sockaddr_in6 *)reply->ip_rem),
+ &dcid, idle_timeout, now // NOTE setting retry token validity to idle_timeout for simplicity
+ );
+ } else {
+ ret = ngtcp2_crypto_verify_regular_token(
+ header.token, header.tokenlen,
+ (const uint8_t *)table->hash_secret,
+ sizeof(table->hash_secret),
+ (const struct sockaddr *)reply->ip_rem,
+ addr_len((struct sockaddr_in6 *)reply->ip_rem),
+ QUIC_REGULAR_TOKEN_TIMEOUT, now
+ );
+ }
if (ret != 0) {
ret = KNOT_EOK;
goto finish;
diff --git a/src/libknot/version.h b/src/libknot/version.h
index 2f86ed7..66b1793 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 0x05
+#define KNOT_VERSION_PATCH 0x06
#define KNOT_VERSION_HEX ((KNOT_VERSION_MAJOR << 16) | \
(KNOT_VERSION_MINOR << 8) | \
diff --git a/src/libknot/xdp/tcp.c b/src/libknot/xdp/tcp.c
index 7d647d7..94d445c 100644
--- a/src/libknot/xdp/tcp.c
+++ b/src/libknot/xdp/tcp.c
@@ -588,7 +588,7 @@ int knot_tcp_send(knot_xdp_socket_t *socket, knot_tcp_relay_t relays[],
break;
case XDP_TCP_RESET:
NEXT_MSG
- msg->flags |= KNOT_XDP_MSG_RST;
+ msg->flags |= (KNOT_XDP_MSG_RST | KNOT_XDP_MSG_ACK);
break;
case XDP_TCP_NOOP:
default:
diff --git a/src/libknot/yparser/ypbody.c b/src/libknot/yparser/ypbody.c
index ad9cf1f..3343604 100644
--- a/src/libknot/yparser/ypbody.c
+++ b/src/libknot/yparser/ypbody.c
@@ -1,5 +1,5 @@
-/* Copyright (C) 2021 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
@@ -45,8 +45,8 @@ static const unsigned char _yparser_key_offsets[] = {
0, 0, 14, 16, 27, 29, 32, 43,
44, 54, 65, 67, 68, 78, 90, 94,
96, 99, 104, 107, 110, 122, 132, 142,
- 145, 148, 151, 156, 159, 162, 176, 190,
- 204
+ 145, 155, 160, 163, 166, 169, 172, 186,
+ 200, 214
};
static const char _yparser_trans_keys[] = {
@@ -65,43 +65,44 @@ static const char _yparser_trans_keys[] = {
34, 32, 126, 34, 92, 127, 0, 31,
10, 13, 32, 34, 32, 126, 10, 13,
32, 34, 35, 44, 91, 92, 93, 127,
- 0, 31, 32, 34, 35, 44, 92, 127,
- 0, 31, 91, 93, 32, 44, 91, 92,
+ 0, 31, 32, 34, 35, 44, 91, 92,
+ 93, 127, 0, 31, 32, 44, 91, 92,
93, 127, 0, 31, 34, 35, 32, 44,
- 93, 10, 13, 32, 34, 32, 126, 34,
- 92, 127, 0, 31, 32, 44, 93, 34,
- 32, 126, 10, 13, 32, 35, 42, 45,
+ 93, 32, 34, 35, 44, 92, 127, 0,
+ 31, 91, 93, 34, 92, 127, 0, 31,
+ 32, 44, 93, 10, 13, 32, 34, 32,
+ 126, 34, 32, 126, 10, 13, 32, 35,
+ 42, 45, 92, 95, 46, 57, 65, 90,
+ 97, 122, 10, 13, 32, 35, 42, 45,
92, 95, 46, 57, 65, 90, 97, 122,
10, 13, 32, 35, 42, 45, 92, 95,
46, 57, 65, 90, 97, 122, 10, 13,
32, 35, 42, 45, 92, 95, 46, 57,
- 65, 90, 97, 122, 10, 13, 32, 35,
- 42, 45, 92, 95, 46, 57, 65, 90,
- 97, 122, 0
+ 65, 90, 97, 122, 0
};
static const char _yparser_single_lengths[] = {
0, 8, 2, 5, 2, 3, 5, 1,
4, 5, 2, 1, 6, 6, 4, 2,
- 1, 3, 3, 1, 10, 6, 6, 3,
- 3, 1, 3, 3, 1, 8, 8, 8,
- 8
+ 1, 3, 3, 1, 10, 8, 6, 3,
+ 6, 3, 3, 3, 1, 1, 8, 8,
+ 8, 8
};
static const char _yparser_range_lengths[] = {
0, 3, 0, 3, 0, 0, 3, 0,
3, 3, 0, 0, 2, 3, 0, 0,
- 1, 1, 0, 1, 1, 2, 2, 0,
- 0, 1, 1, 0, 1, 3, 3, 3,
- 3
+ 1, 1, 0, 1, 1, 1, 2, 0,
+ 2, 1, 0, 0, 1, 1, 3, 3,
+ 3, 3
};
static const unsigned char _yparser_index_offsets[] = {
0, 0, 12, 15, 24, 27, 31, 40,
42, 50, 59, 62, 64, 73, 83, 88,
- 91, 94, 99, 103, 106, 118, 127, 136,
- 140, 144, 147, 152, 156, 159, 171, 183,
- 195
+ 91, 94, 99, 103, 106, 118, 128, 137,
+ 141, 150, 155, 159, 163, 166, 169, 181,
+ 193, 205
};
static const char _yparser_indicies[] = {
@@ -120,30 +121,32 @@ static const char _yparser_indicies[] = {
0, 0, 37, 30, 31, 32, 0, 40,
37, 0, 12, 13, 14, 27, 35, 0,
41, 28, 0, 0, 0, 26, 41, 43,
- 0, 0, 44, 0, 0, 0, 42, 46,
- 47, 0, 48, 49, 0, 0, 0, 45,
- 50, 41, 51, 0, 12, 13, 34, 0,
- 52, 45, 0, 54, 55, 0, 0, 53,
- 46, 47, 49, 0, 56, 53, 0, 1,
- 2, 3, 4, 57, 6, 57, 57, 57,
- 57, 57, 0, 59, 60, 61, 62, 63,
- 64, 63, 63, 63, 63, 63, 58, 65,
- 66, 67, 68, 69, 70, 69, 69, 69,
- 69, 69, 0, 71, 72, 73, 74, 75,
- 76, 75, 75, 75, 75, 75, 58, 0
+ 0, 0, 0, 44, 45, 0, 0, 42,
+ 47, 48, 0, 49, 50, 0, 0, 0,
+ 46, 51, 52, 45, 0, 52, 43, 0,
+ 0, 44, 0, 0, 0, 42, 54, 55,
+ 0, 0, 53, 47, 48, 50, 0, 12,
+ 13, 34, 0, 56, 53, 0, 57, 46,
+ 0, 1, 2, 3, 4, 58, 6, 58,
+ 58, 58, 58, 58, 0, 60, 61, 62,
+ 63, 64, 65, 64, 64, 64, 64, 64,
+ 59, 66, 67, 68, 69, 70, 71, 70,
+ 70, 70, 70, 70, 0, 72, 73, 74,
+ 75, 76, 77, 76, 76, 76, 76, 76,
+ 59, 0
};
static const char _yparser_trans_targs[] = {
- 0, 30, 31, 1, 2, 3, 7, 4,
- 3, 5, 4, 5, 32, 29, 20, 4,
+ 0, 31, 32, 1, 2, 3, 7, 4,
+ 3, 5, 4, 5, 33, 30, 20, 4,
6, 5, 8, 9, 10, 9, 11, 10,
- 11, 12, 13, 17, 16, 13, 32, 29,
+ 11, 12, 13, 17, 16, 13, 33, 30,
14, 16, 14, 15, 13, 17, 18, 19,
- 17, 21, 22, 26, 25, 22, 23, 21,
- 25, 24, 23, 24, 22, 26, 27, 28,
- 26, 6, 0, 30, 31, 1, 2, 6,
- 7, 30, 31, 1, 2, 6, 7, 30,
- 31, 1, 2, 6, 7
+ 17, 21, 22, 25, 29, 27, 22, 23,
+ 24, 29, 27, 23, 24, 25, 26, 28,
+ 25, 22, 6, 0, 31, 32, 1, 2,
+ 6, 7, 31, 32, 1, 2, 6, 7,
+ 31, 32, 1, 2, 6, 7
};
static const char _yparser_trans_actions[] = {
@@ -152,26 +155,26 @@ static const char _yparser_trans_actions[] = {
13, 15, 21, 46, 19, 13, 19, 0,
0, 0, 37, 7, 37, 9, 43, 11,
11, 9, 0, 0, 40, 9, 0, 9,
- 40, 0, 37, 7, 37, 9, 11, 11,
- 9, 11, 0, 0, 40, 9, 0, 9,
- 40, 46, 31, 55, 28, 88, 28, 83,
- 93, 34, 5, 75, 5, 71, 79, 25,
- 3, 63, 3, 59, 67
+ 40, 0, 37, 7, 37, 0, 9, 11,
+ 11, 9, 11, 0, 0, 9, 0, 9,
+ 40, 40, 46, 31, 55, 28, 88, 28,
+ 83, 93, 34, 5, 75, 5, 71, 79,
+ 25, 3, 63, 3, 59, 67
};
static const char _yparser_eof_actions[] = {
0, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 0, 28, 5,
- 3
+ 23, 23, 23, 23, 23, 23, 0, 28,
+ 5, 3
};
-int _yp_start_state = 29;
+int _yp_start_state = 30;
int _yp_parse(
yp_parser_t *parser)
diff --git a/src/libzscanner/version.h b/src/libzscanner/version.h
index 25520c7..12d0d9e 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 0x05
+#define ZSCANNER_VERSION_PATCH 0x06
#define ZSCANNER_VERSION_HEX ((ZSCANNER_VERSION_MAJOR << 16) | \
(ZSCANNER_VERSION_MINOR << 8) | \
diff --git a/src/utils/common/params.c b/src/utils/common/params.c
index 4db4b9e..d16af4c 100644
--- a/src/utils/common/params.c
+++ b/src/utils/common/params.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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
@@ -47,7 +47,12 @@ char *name_from_idn(const char *idn_name) {
return NULL;
}
- return name;
+ if (strcasecmp(idn_name, name) == 0) {
+ free(name);
+ return strdup(idn_name);
+ } else {
+ return name;
+ }
#endif
return strdup(idn_name);
}
@@ -212,7 +217,7 @@ char *get_fqd_name(const char *name)
size_t name_len = strlen(name);
// If the name is FQDN, make a copy.
- if (name[name_len - 1] == '.') {
+ if (name_len > 0 && name[name_len - 1] == '.') {
fqd_name = strdup(name);
// Else make a copy and append a trailing dot.
} else {
diff --git a/src/utils/common/quic.c b/src/utils/common/quic.c
index 55e5408..704f3b1 100644
--- a/src/utils/common/quic.c
+++ b/src/utils/common/quic.c
@@ -564,6 +564,10 @@ int quic_ctx_connect(quic_ctx_t *ctx, int sockfd, struct addrinfo *dst_addr)
ret = poll(&pfd, 1, timeout);
if (ret == 0) {
ret = ngtcp2_conn_handle_expiry(ctx->conn, quic_timestamp());
+ if (ret != 0) {
+ WARN("QUIC, failed to send");
+ return KNOT_ECONNABORTED;
+ }
} else if (ret < 0) {
return knot_map_errno();
}
@@ -658,6 +662,10 @@ int quic_send_dns_query(quic_ctx_t *ctx, int sockfd, struct addrinfo *srv,
return knot_map_errno();
} else if (ret == 0) {
ret = ngtcp2_conn_handle_expiry(ctx->conn, quic_timestamp());
+ if (ret != 0) {
+ WARN("QUIC, failed to send");
+ return KNOT_ECONNABORTED;
+ }
continue;
}
ret = quic_recv(ctx, sockfd);
@@ -701,6 +709,10 @@ int quic_recv_dns_response(quic_ctx_t *ctx, uint8_t *buf, const size_t buf_len,
return knot_map_errno();
} else if (ret == 0) {
ret = ngtcp2_conn_handle_expiry(ctx->conn, quic_timestamp());
+ if (ret != 0) {
+ WARN("QUIC, failed to send");
+ return KNOT_ECONNABORTED;
+ }
WARN("QUIC, peer took too long to respond");
goto send;
}
diff --git a/src/utils/kdig/kdig_params.c b/src/utils/kdig/kdig_params.c
index 310e890..c8fd83f 100644
--- a/src/utils/kdig/kdig_params.c
+++ b/src/utils/kdig/kdig_params.c
@@ -1982,7 +1982,7 @@ static int parse_name(const char *value, list_t *queries, const query_t *conf)
char *ascii_name = (char *)value;
char *fqd_name = NULL;
- if (value != NULL) {
+ if (value != NULL && value[0] != '\0') {
if (conf->idn) {
ascii_name = name_from_idn(value);
if (ascii_name == NULL) {
diff --git a/src/utils/knotc/commands.c b/src/utils/knotc/commands.c
index e5cb455..c2c25a2 100644
--- a/src/utils/knotc/commands.c
+++ b/src/utils/knotc/commands.c
@@ -688,6 +688,7 @@ static int cmd_zone_ctl(cmd_args_t *args)
}
#define FILTER_IMPORT_NOPURGE "+nopurge"
+#define FILTER_EXPORT_SCHEMA "+schema"
typedef struct {
const char *name;
@@ -1173,22 +1174,45 @@ static int cmd_conf_import(cmd_args_t *args)
static int cmd_conf_export(cmd_args_t *args)
{
- int ret = check_args(args, 0, 1);
+ int ret = check_args(args, 0, 2);
if (ret != KNOT_EOK) {
return ret;
}
// Stdout is the default output file.
const char *file_name = NULL;
- if (args->argc > 0) {
- file_name = args->argv[0];
- log_debug("exporting confdb into file '%s'", file_name);
+ bool export_schema = false;
+ for (int i = 0; i < args->argc; i++) {
+ if (args->argv[i][0] == '+') {
+ if (strcmp(args->argv[i], FILTER_EXPORT_SCHEMA) == 0) {
+ export_schema = true;
+ } else {
+ log_error("unknown filter: %s", args->argv[i]);
+ return KNOT_EINVAL;
+ }
+ } else if (file_name == NULL) {
+ file_name = args->argv[i];
+ } else {
+ log_error("command does not take 2 arguments");
+ return KNOT_EINVAL;
+ }
}
- ret = conf_export(conf(), file_name, YP_SNONE);
+ if (file_name != NULL) {
+ if (export_schema) {
+ log_debug("exporting JSON schema into file '%s'", file_name);
+ } else {
+ log_debug("exporting confdb into file '%s'", file_name);
+ }
+ }
+ if (export_schema) {
+ ret = conf_export_schema(conf(), file_name);
+ } else {
+ ret = conf_export(conf(), file_name, YP_SNONE);
+ }
if (ret == KNOT_EOK) {
- if (args->argc > 0) {
+ if (file_name != NULL) {
log_info("OK");
}
} else {
@@ -1345,7 +1369,7 @@ static const cmd_help_t cmd_help_table[] = {
{ CMD_CONF_INIT, "", "Initialize the confdb. (*)" },
{ CMD_CONF_CHECK, "", "Check the server configuration. (*)" },
{ CMD_CONF_IMPORT, " <filename> [+nopurge]", "Import a config file into the confdb. (*)" },
- { CMD_CONF_EXPORT, "[<filename>]", "Export the confdb into a config file or stdout. (*)" },
+ { CMD_CONF_EXPORT, "[<filename>] [+schema]", "Export the confdb (or JSON schema) into a file or stdout. (*)" },
{ CMD_CONF_LIST, "[<item>...]", "List the confdb sections or section items." },
{ CMD_CONF_READ, "[<item>...]", "Get the item from the active confdb." },
{ CMD_CONF_BEGIN, "", "Begin a writing confdb transaction." },
diff --git a/src/utils/knotd/main.c b/src/utils/knotd/main.c
index 2355d9e..d4ebd53 100644
--- a/src/utils/knotd/main.c
+++ b/src/utils/knotd/main.c
@@ -273,7 +273,8 @@ static void event_loop(server_t *server, const char *socket, bool daemonize,
log_info("control, binding to '%s'", listen);
/* Bind the control socket. */
- int ret = knot_ctl_bind(ctl, listen);
+ uint16_t backlog = conf_get_int(conf(), C_CTL, C_BACKLOG);
+ int ret = knot_ctl_bind2(ctl, listen, backlog);
if (ret != KNOT_EOK) {
knot_ctl_free(ctl);
log_fatal("control, failed to bind socket '%s' (%s)",
diff --git a/src/utils/kxdpgun/main.c b/src/utils/kxdpgun/main.c
index c9db312..8f4d402 100644
--- a/src/utils/kxdpgun/main.c
+++ b/src/utils/kxdpgun/main.c
@@ -30,6 +30,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@@ -205,12 +206,12 @@ static void print_stats(kxdpgun_stats_t *st, bool tcp, bool quic, bool recv, uin
{
pthread_mutex_lock(&st->mutex);
-#define ps(counter) ((counter) * 1000 / (st->duration / 1000))
+#define ps(counter) ((typeof(counter))((counter) * 1000 / ((float)st->duration / 1000)))
#define pct(counter) ((counter) * 100.0 / st->qry_sent)
const char *name = tcp ? "SYNs: " : quic ? "initials:" : "queries: ";
- printf("total %s %"PRIu64" (%"PRIu64" pps) (%f%%)\n", name,
- st->qry_sent, ps(st->qry_sent), 100.0 * st->qry_sent / (st->duration / 1000000.0 * qps));
+ printf("total %s %"PRIu64" (%"PRIu64" pps) (%f%%)\n", name, st->qry_sent,
+ ps(st->qry_sent), 100.0 * st->qry_sent / (st->duration / 1000000.0 * qps));
if (st->qry_sent > 0 && recv) {
if (tcp || quic) {
name = tcp ? "established:" : "handshakes: ";
@@ -534,8 +535,8 @@ void *xdp_gun_thread(void *_ctx)
}
if (ctx->thread_id == 0) {
- INFO2("using interface %s, XDP threads %u, %s%s%s, %s mode",
- ctx->dev, ctx->n_threads,
+ INFO2("using interface %s, XDP threads %u, IPv%c/%s%s%s, %s mode",
+ ctx->dev, ctx->n_threads, (ctx->ipv6 ? '6' : '4'),
(ctx->tcp ? "TCP" : ctx->quic ? "QUIC" : "UDP"),
(ctx->sending_mode[0] != '\0' ? " mode " : ""),
(ctx->sending_mode[0] != '\0' ? ctx->sending_mode : ""),
@@ -989,6 +990,41 @@ static int mac_sscan(const char *src, uint8_t *dst)
return KNOT_EOK;
}
+static bool resolve_name(char *target_str, xdp_gun_ctx_t *ctx)
+{
+ struct addrinfo *res = NULL, hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = 0, // any socket type
+ .ai_protocol = 0, // any protocol
+ };
+
+ int err = 0;
+ if ((err = getaddrinfo(target_str, NULL, &hints, &res)) != 0) {
+ ERR2("failed to resolve '%s' (%s)", target_str, gai_strerror(err));
+ goto cleanup;
+ }
+
+ for (struct addrinfo *i = res; i != NULL; i = i->ai_next) {
+ switch (i->ai_family) {
+ case AF_INET:
+ case AF_INET6:
+ ctx->ipv6 = (i->ai_family == AF_INET6);
+ assert(sizeof(ctx->target_ip_ss) >= i->ai_addrlen);
+ memcpy(&ctx->target_ip_ss, i->ai_addr, i->ai_addrlen);
+ goto cleanup;
+ default:
+ break;
+ };
+ }
+ err = 1;
+
+cleanup:
+ if (res != NULL) {
+ freeaddrinfo(res);
+ }
+ return (err == 0);
+}
+
static bool configure_target(char *target_str, char *local_ip, xdp_gun_ctx_t *ctx)
{
int val;
@@ -998,16 +1034,8 @@ static bool configure_target(char *target_str, char *local_ip, xdp_gun_ctx_t *ct
*at = '\0';
}
- ctx->ipv6 = false;
- if (inet_pton(AF_INET, target_str, &ctx->target_ip4.sin_addr) <= 0) {
- ctx->ipv6 = true;
- ctx->target_ip.sin6_family = AF_INET6;
- if (inet_pton(AF_INET6, target_str, &ctx->target_ip.sin6_addr) <= 0) {
- ERR2("invalid target IP");
- return false;
- }
- } else {
- ctx->target_ip.sin6_family = AF_INET;
+ if (!resolve_name(target_str, ctx)) {
+ return false;
}
struct sockaddr_storage via = { 0 };