Download raw body.
nsd 4.14.1 update
here's an update to NSD. I added cpuset.h to the compat/ dir (we have
so far been removing that dir from the imports) to allow removing some
diffs in Makefile.in that often require hand merging during updates
(it's a prereq of nearly all objects).
any tests/comments?
4.14.1
================
FEATURES:
- Merge #469 from jschlyter: Add container build files
BUG FIXES:
- Fix to note DSYNC RFC9859 reference.
- Fix to note reference for NXNAME in comment.
- Merge #470 from jschlyter: Update path to default container
configuration and entrypoint
- Fix rr-test.tdir so AMTRELAY relay field is "." with type 0
- Fix checkconf.tdir test to anticipate default values for
send-buffer-size and receive-buffer-size when configured with 0
- skip dns-cookies.tdir test with restricted unpriviledged userns
- Fix #474: metrics output with zone statistics to change
disallowed characters in metric names to underscores.
- Fix that non normalized NSEC next owner names are preserved.
- Fix to preserve case in literal dnames in RR types RRSIG,
IPSECKEY, TALINK, DSYNC and AMTRELAY.
- Fix for #474: Fix metrics name for zone statistics for
the queries_total to have disallowed characters changed
to underscores.
- Fix to silence restricted userns check in test script.
- Fix #475 info: axfr for domain from not-verified.
- Fix metrics to clear server variable after close and log error
on allocation failure.
- Fix to escape slashes when they appear in the zone name for a
pattern zonefile that is created. Also for per zone statistics.
- Merge #472: Reduce memory usage with zones with RRsets
consisting of many RRs.
- Fix man page for ip-address, add text about process numbers,
bindtodevice and setfib.
- Fix systemd signalling so that it does not reload for too long.
The reload is not signalled to systemd, so that long operations
can complete, without systemd acting on a timer to stop them.
4.14.0
================
FEATURES:
- Fix #137: Adds tcp-listen-queue: number config option to set
the TCP backlog. And the default for the listen TCP backlog is
set to -1 on BSDs and Linux.
- Merge #444: Refactor RDATA storage to reduce memory footprint
BUG FIXES:
- Fix empty debug statement body in catalog consumer zone process.
- Merge #459: Check for libfstrm version >= 0.4.
- For #459: Add configure check for fstrm_tcp_writer_options_init
in addition to the check for fstrm_iothr_init.
- Merge #460: Add XDP_OBJ fixing link errors for XDP.
- Fix XDP build error with --enable-checking
- Resolve warnings about mixed declaration and code and unused variable
- Fix confusing report for default send and receive buffer-size by
nsd-checkconf
- Fix to log more details when send-buffer-size or receive-buffer-size
is not granted, on verbosity level 2.
- Update in acx_nlnetlabs.m4 to version 49.
- Update in acx_nlnetlabs.m4 to version 50, with cache value for
malloc function check.
- Update acx_nlnetlabs.m4 to version 51, with nonstring unknown
attribute warning fix.
- Merge #466: Do not delete nodes from non-existent zone's NSEC3 hash
trees
Index: Makefile.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/Makefile.in,v
diff -u -p -r1.40 Makefile.in
--- Makefile.in 6 Sep 2025 17:41:37 -0000 1.40
+++ Makefile.in 18 Mar 2026 20:44:03 -0000
@@ -101,10 +101,10 @@ XDP_OBJ=xdp-server.o xdp-util.o
NSD_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) $(XDP_OBJ) difffile.o ipc.o mini_event.o netio.o nsd.o server.o dbaccess.o dbcreate.o zonec.o verify.o
ALL_OBJ=$(NSD_OBJ) nsd-checkconf.o nsd-checkzone.o nsd-control.o nsd-mem.o xfr-inspect.o
NSD_CHECKCONF_OBJ=$(COMMON_OBJ) nsd-checkconf.o
-NSD_CHECKZONE_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o nsd-checkzone.o verify.o
+NSD_CHECKZONE_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) $(XDP_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o nsd-checkzone.o verify.o
NSD_CONTROL_OBJ=$(COMMON_OBJ) nsd-control.o
-CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o verify.o zonec.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_util.o cutest_xfrd_tcp.o cutest_bitset.o cutest_popen3.o cutest_iter.o cutest_event.o cutest.o qtest.o
-NSD_MEM_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o verify.o server.o zonec.o nsd-mem.o
+CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) $(XDP_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o verify.o zonec.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_util.o cutest_xfrd_tcp.o cutest_bitset.o cutest_popen3.o cutest_iter.o cutest_event.o cutest.o qtest.o
+NSD_MEM_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) $(XDP_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o verify.o server.o zonec.o nsd-mem.o
.PHONY: all html
@@ -163,6 +163,14 @@ nsd-checkzone.8: $(srcdir)/nsd-checkzone
nsd-control.8: $(srcdir)/nsd-control.8.in config.h
$(EDIT) $(srcdir)/nsd-control.8.in > $@
+contrib/nsd.openrc: $(srcdir)/contrib/nsd.openrc.in
+ mkdir -p contrib
+ $(EDIT) $(srcdir)/contrib/nsd.openrc.in > $@
+
+contrib/nsd-tmpfiles.conf: $(srcdir)/contrib/nsd-tmpfiles.conf.in
+ mkdir -p contrib
+ $(EDIT) $(srcdir)/contrib/nsd-tmpfiles.conf.in > $@
+
install:
orig-install: all
@@ -493,225 +501,229 @@ depend:
proxy_protocol.o: $(srcdir)/util/proxy_protocol.c config.h $(srcdir)/util/proxy_protocol.h
# Dependencies
-answer.o: $(srcdir)/answer.c config.h $(srcdir)/answer.h $(srcdir)/dns.h $(srcdir)/namedb.h \
+answer.o: $(srcdir)/answer.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/answer.h $(srcdir)/dns.h $(srcdir)/namedb.h \
$(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/packet.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/tsig.h
-axfr.o: $(srcdir)/axfr.c config.h $(srcdir)/axfr.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h \
+axfr.o: $(srcdir)/axfr.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/axfr.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/options.h $(srcdir)/ixfr.h
-bitset.o: $(srcdir)/bitset.c config.h $(srcdir)/bitset.h
-buffer.o: $(srcdir)/buffer.c config.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h \
+bitset.o: $(srcdir)/bitset.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/bitset.h
+buffer.o: $(srcdir)/buffer.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h \
$(srcdir)/util.h $(srcdir)/bitset.h
-configlexer.o: configlexer.c config.h $(srcdir)/options.h \
+configlexer.o: configlexer.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/options.h \
$(srcdir)/region-allocator.h $(srcdir)/rbtree.h configparser.h
-configparser.o: configparser.c config.h $(srcdir)/options.h \
+configparser.o: configparser.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/options.h \
$(srcdir)/region-allocator.h $(srcdir)/rbtree.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/dns.h \
$(srcdir)/tsig.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h \
configparser.h
-dbaccess.o: $(srcdir)/dbaccess.c config.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+dbaccess.o: $(srcdir)/dbaccess.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/options.h \
$(srcdir)/rdata.h $(srcdir)/udb.h $(srcdir)/zonec.h $(srcdir)/nsec3.h $(srcdir)/difffile.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/ixfr.h $(srcdir)/query.h \
$(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/ixfrcreate.h
-dbcreate.o: $(srcdir)/dbcreate.c config.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
+dbcreate.o: $(srcdir)/dbcreate.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/udb.h \
$(srcdir)/options.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/packet.h $(srcdir)/tsig.h
-difffile.o: $(srcdir)/difffile.c config.h $(srcdir)/difffile.h $(srcdir)/rbtree.h \
+difffile.o: $(srcdir)/difffile.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/difffile.h $(srcdir)/rbtree.h \
$(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h \
$(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/udb.h $(srcdir)/xfrd-disk.h $(srcdir)/packet.h $(srcdir)/rdata.h $(srcdir)/nsec3.h $(srcdir)/nsd.h \
$(srcdir)/edns.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/tsig.h $(srcdir)/ixfr.h $(srcdir)/zonec.h $(srcdir)/xfrd-catalog-zones.h $(srcdir)/xfrd.h
-dname.o: $(srcdir)/dname.c config.h $(srcdir)/dns.h $(srcdir)/dname.h $(srcdir)/buffer.h \
+dname.o: $(srcdir)/dname.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h
-dns.o: $(srcdir)/dns.c config.h $(srcdir)/dns.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+dns.o: $(srcdir)/dns.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $(srcdir)/rdata.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h
-edns.o: $(srcdir)/edns.c config.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
+edns.o: $(srcdir)/edns.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/nsd.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h $(srcdir)/tsig.h
-ipc.o: $(srcdir)/ipc.c config.h $(srcdir)/ipc.h $(srcdir)/netio.h $(srcdir)/region-allocator.h \
+ipc.o: $(srcdir)/ipc.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/ipc.h $(srcdir)/netio.h $(srcdir)/region-allocator.h \
$(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/xfrd-notify.h $(srcdir)/difffile.h \
$(srcdir)/udb.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/packet.h
-iterated_hash.o: $(srcdir)/iterated_hash.c config.h $(srcdir)/iterated_hash.h \
+iterated_hash.o: $(srcdir)/iterated_hash.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/iterated_hash.h \
$(srcdir)/util.h $(srcdir)/bitset.h
-ixfr.o: $(srcdir)/ixfr.c config.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+ixfr.o: $(srcdir)/ixfr.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/rdata.h $(srcdir)/axfr.h $(srcdir)/options.h $(srcdir)/zonec.h \
$(srcdir)/simdzone/include/zone.h $(srcdir)/simdzone/include/zone/attributes.h \
simdzone/include/zone/export.h
-ixfrcreate.o: $(srcdir)/ixfrcreate.c config.h $(srcdir)/ixfrcreate.h $(srcdir)/dns.h \
+ixfrcreate.o: $(srcdir)/ixfrcreate.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/ixfrcreate.h $(srcdir)/dns.h \
$(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h \
- $(srcdir)/rbtree.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/options.h
-lookup3.o: $(srcdir)/lookup3.c config.h $(srcdir)/lookup3.h
-metrics.o: $(srcdir)/metrics.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
+ $(srcdir)/rbtree.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/options.h $(srcdir)/rdata.h
+lookup3.o: $(srcdir)/lookup3.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/lookup3.h
+metrics.o: $(srcdir)/metrics.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/remote.h $(srcdir)/metrics.h
-mini_event.o: $(srcdir)/mini_event.c config.h
-namedb.o: $(srcdir)/namedb.c config.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
+mini_event.o: $(srcdir)/mini_event.c config.h $(srcdir)/compat/cpuset.h
+namedb.o: $(srcdir)/namedb.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsec3.h
-netio.o: $(srcdir)/netio.c config.h $(srcdir)/netio.h $(srcdir)/region-allocator.h \
+netio.o: $(srcdir)/netio.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/netio.h $(srcdir)/region-allocator.h \
$(srcdir)/util.h $(srcdir)/bitset.h
-nsd.o: $(srcdir)/nsd.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
+nsd.o: $(srcdir)/nsd.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
+ $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/options.h $(srcdir)/rbtree.h $(srcdir)/tsig.h $(srcdir)/dname.h \
$(srcdir)/remote.h $(srcdir)/xfrd-disk.h $(srcdir)/ipc.h $(srcdir)/netio.h $(srcdir)/metrics.h $(srcdir)/dnstap/dnstap_collector.h \
- $(srcdir)/util/proxy_protocol.h config.h $(srcdir)/xdp-server.h $(srcdir)/xdp-util.h
-nsd-checkconf.o: $(srcdir)/nsd-checkconf.c config.h $(srcdir)/tsig.h $(srcdir)/buffer.h \
+ $(srcdir)/util/proxy_protocol.h config.h $(srcdir)/compat/cpuset.h $(srcdir)/xdp-server.h $(srcdir)/xdp-util.h
+nsd-checkconf.o: $(srcdir)/nsd-checkconf.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/tsig.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dname.h $(srcdir)/dns.h $(srcdir)/options.h $(srcdir)/rbtree.h \
$(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h
-nsd-checkzone.o: $(srcdir)/nsd-checkzone.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h \
+nsd-checkzone.o: $(srcdir)/nsd-checkzone.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h $(srcdir)/dns.h \
$(srcdir)/edns.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/options.h $(srcdir)/rbtree.h \
$(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/packet.h $(srcdir)/tsig.h \
$(srcdir)/ixfrcreate.h $(srcdir)/difffile.h $(srcdir)/udb.h
-nsd-control.o: $(srcdir)/nsd-control.c config.h $(srcdir)/util.h $(srcdir)/bitset.h \
+nsd-control.o: $(srcdir)/nsd-control.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/tsig.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/dname.h $(srcdir)/dns.h $(srcdir)/options.h $(srcdir)/rbtree.h \
$(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/radtree.h
-nsd-mem.o: $(srcdir)/nsd-mem.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
+nsd-mem.o: $(srcdir)/nsd-mem.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/tsig.h $(srcdir)/dname.h $(srcdir)/options.h $(srcdir)/rbtree.h \
$(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/packet.h
-nsec3.o: $(srcdir)/nsec3.c config.h $(srcdir)/nsec3.h $(srcdir)/iterated_hash.h \
+nsec3.o: $(srcdir)/nsec3.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsec3.h $(srcdir)/iterated_hash.h \
$(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h \
$(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/answer.h $(srcdir)/packet.h $(srcdir)/query.h $(srcdir)/tsig.h \
$(srcdir)/options.h
-options.o: $(srcdir)/options.c config.h $(srcdir)/options.h \
+options.o: $(srcdir)/options.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/options.h \
$(srcdir)/region-allocator.h $(srcdir)/rbtree.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h \
$(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/ixfr.h $(srcdir)/difffile.h \
$(srcdir)/udb.h $(srcdir)/rrl.h $(srcdir)/xfrd.h configparser.h
-packet.o: $(srcdir)/packet.c config.h $(srcdir)/packet.h $(srcdir)/dns.h $(srcdir)/namedb.h \
+packet.o: $(srcdir)/packet.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/packet.h $(srcdir)/dns.h $(srcdir)/namedb.h \
$(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/tsig.h $(srcdir)/rdata.h
-popen3.o: $(srcdir)/popen3.c config.h $(srcdir)/popen3.h
-query.o: $(srcdir)/query.c config.h $(srcdir)/answer.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+popen3.o: $(srcdir)/popen3.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/popen3.h
+query.o: $(srcdir)/query.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/answer.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h \
- $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/tsig.h $(srcdir)/axfr.h $(srcdir)/options.h $(srcdir)/nsec3.h
-radtree.o: $(srcdir)/radtree.c config.h $(srcdir)/radtree.h $(srcdir)/util.h $(srcdir)/bitset.h \
+ $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/tsig.h $(srcdir)/axfr.h $(srcdir)/options.h $(srcdir)/nsec3.h $(srcdir)/rdata.h
+radtree.o: $(srcdir)/radtree.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/radtree.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/region-allocator.h
-rbtree.o: $(srcdir)/rbtree.c config.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h
-rdata.o: $(srcdir)/rdata.c config.h $(srcdir)/rdata.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h \
- $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/zonec.h
-region-allocator.o: $(srcdir)/region-allocator.c config.h \
+rbtree.o: $(srcdir)/rbtree.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h
+rdata.o: $(srcdir)/rdata.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/rdata.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+ $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/zonec.h \
+ $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h
+region-allocator.o: $(srcdir)/region-allocator.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h
-remote.o: $(srcdir)/remote.c config.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/xfrd.h \
+remote.o: $(srcdir)/remote.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/xfrd.h \
$(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/dns.h $(srcdir)/radtree.h \
$(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/xfrd-catalog-zones.h $(srcdir)/xfrd-notify.h $(srcdir)/xfrd-tcp.h $(srcdir)/nsd.h \
- $(srcdir)/edns.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/ipc.h $(srcdir)/netio.h $(srcdir)/remote.h $(srcdir)/metrics.h
-rrl.o: $(srcdir)/rrl.c config.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+ $(srcdir)/edns.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/ipc.h $(srcdir)/netio.h $(srcdir)/remote.h $(srcdir)/rdata.h $(srcdir)/metrics.h
+rrl.o: $(srcdir)/rrl.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/lookup3.h $(srcdir)/options.h
-server.o: $(srcdir)/server.c config.h $(srcdir)/axfr.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h \
+server.o: $(srcdir)/server.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/axfr.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/netio.h $(srcdir)/xfrd.h $(srcdir)/options.h $(srcdir)/xfrd-tcp.h \
$(srcdir)/xfrd-disk.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/nsec3.h $(srcdir)/ipc.h $(srcdir)/remote.h $(srcdir)/lookup3.h $(srcdir)/rrl.h \
$(srcdir)/ixfr.h $(srcdir)/dnstap/dnstap_collector.h $(srcdir)/verify.h $(srcdir)/util/proxy_protocol.h config.h \
- $(srcdir)/metrics.h $(srcdir)/xdp-server.h
+ $(srcdir)/compat/cpuset.h $(srcdir)/metrics.h $(srcdir)/xdp-server.h
siphash.o: $(srcdir)/siphash.c
-tsig.o: $(srcdir)/tsig.c config.h $(srcdir)/tsig.h $(srcdir)/buffer.h \
+tsig.o: $(srcdir)/tsig.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/tsig.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dname.h $(srcdir)/dns.h $(srcdir)/tsig-openssl.h $(srcdir)/packet.h \
$(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h
-tsig-openssl.o: $(srcdir)/tsig-openssl.c config.h $(srcdir)/tsig-openssl.h \
+tsig-openssl.o: $(srcdir)/tsig-openssl.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/tsig-openssl.h \
$(srcdir)/region-allocator.h $(srcdir)/tsig.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dname.h $(srcdir)/dns.h
-udb.o: $(srcdir)/udb.c config.h $(srcdir)/udb.h $(srcdir)/lookup3.h $(srcdir)/util.h $(srcdir)/bitset.h
-util.o: $(srcdir)/util.c config.h $(srcdir)/util.h $(srcdir)/bitset.h \
+udb.o: $(srcdir)/udb.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/udb.h $(srcdir)/lookup3.h $(srcdir)/util.h $(srcdir)/bitset.h
+util.o: $(srcdir)/util.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/region-allocator.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/rdata.h $(srcdir)/zonec.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/options.h
-verify.o: $(srcdir)/verify.c config.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h \
+verify.o: $(srcdir)/verify.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h \
$(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h \
$(srcdir)/options.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/verify.h $(srcdir)/popen3.h
xdp-server.o: $(srcdir)/xdp-server.c config.h $(srcdir)/xdp-server.h $(srcdir)/xdp-util.h $(srcdir)/dns.h $(srcdir)/nsd.h $(srcdir)/query.h $(srcdir)/region-allocator.h $(srcdir)/util.h
xdp-util.o: $(srcdir)/xdp-util.c config.h $(srcdir)/xdp-util.h
-xfrd.o: $(srcdir)/xfrd.c config.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h \
+xfrd.o: $(srcdir)/xfrd.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h \
$(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h \
$(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd-disk.h $(srcdir)/xfrd-notify.h \
$(srcdir)/xfrd-catalog-zones.h $(srcdir)/netio.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/rdata.h $(srcdir)/difffile.h \
$(srcdir)/udb.h $(srcdir)/ipc.h $(srcdir)/remote.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/dnstap/dnstap_collector.h $(srcdir)/metrics.h
-xfrd-catalog-zones.o: $(srcdir)/xfrd-catalog-zones.c config.h \
+xfrd-catalog-zones.o: $(srcdir)/xfrd-catalog-zones.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/difffile.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h \
- $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/udb.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h \
+ $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/udb.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/rdata.h \
$(srcdir)/xfrd-catalog-zones.h $(srcdir)/xfrd.h $(srcdir)/tsig.h $(srcdir)/xfrd-notify.h
-xfrd-disk.o: $(srcdir)/xfrd-disk.c config.h $(srcdir)/xfrd-disk.h $(srcdir)/xfrd.h \
+xfrd-disk.o: $(srcdir)/xfrd-disk.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/xfrd-disk.h $(srcdir)/xfrd.h \
$(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/nsd.h $(srcdir)/edns.h
-xfrd-notify.o: $(srcdir)/xfrd-notify.c config.h $(srcdir)/xfrd-notify.h \
+xfrd-notify.o: $(srcdir)/xfrd-notify.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/xfrd-notify.h \
$(srcdir)/tsig.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dname.h $(srcdir)/dns.h \
$(srcdir)/rbtree.h $(srcdir)/xfrd.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/xfrd-tcp.h $(srcdir)/packet.h
-xfrd-tcp.o: $(srcdir)/xfrd-tcp.c config.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h \
+xfrd-tcp.o: $(srcdir)/xfrd-tcp.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h \
$(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/packet.h $(srcdir)/xfrd-disk.h
-xfr-inspect.o: $(srcdir)/xfr-inspect.c config.h $(srcdir)/util.h $(srcdir)/bitset.h \
+xfr-inspect.o: $(srcdir)/xfr-inspect.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/packet.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h \
$(srcdir)/rbtree.h $(srcdir)/rdata.h $(srcdir)/difffile.h $(srcdir)/options.h $(srcdir)/udb.h
-zonec.o: $(srcdir)/zonec.c config.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h \
+zonec.o: $(srcdir)/zonec.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \
$(srcdir)/rdata.h $(srcdir)/options.h $(srcdir)/nsec3.h $(srcdir)/simdzone/include/zone.h \
$(srcdir)/simdzone/include/zone/attributes.h simdzone/include/zone/export.h
-b64_ntop.o: $(srcdir)/compat/b64_ntop.c config.h
-b64_pton.o: $(srcdir)/compat/b64_pton.c config.h
+b64_ntop.o: $(srcdir)/compat/b64_ntop.c config.h $(srcdir)/compat/cpuset.h
+b64_pton.o: $(srcdir)/compat/b64_pton.c config.h $(srcdir)/compat/cpuset.h
basename.o: $(srcdir)/compat/basename.c
-explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
-fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
-inet_aton.o: $(srcdir)/compat/inet_aton.c config.h
-inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h
-inet_pton.o: $(srcdir)/compat/inet_pton.c config.h
+cpuset.o: $(srcdir)/compat/cpuset.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/compat/cpuset.h
+explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h $(srcdir)/compat/cpuset.h
+fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h \
+ $(srcdir)/compat/cpuset.h
+inet_aton.o: $(srcdir)/compat/inet_aton.c config.h $(srcdir)/compat/cpuset.h
+inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h $(srcdir)/compat/cpuset.h
+inet_pton.o: $(srcdir)/compat/inet_pton.c config.h $(srcdir)/compat/cpuset.h
malloc.o: $(srcdir)/compat/malloc.c
-memcmp.o: $(srcdir)/compat/memcmp.c config.h
-memmove.o: $(srcdir)/compat/memmove.c config.h
-pselect.o: $(srcdir)/compat/pselect.c config.h
-reallocarray.o: $(srcdir)/compat/reallocarray.c config.h
-setproctitle.o: $(srcdir)/compat/setproctitle.c config.h
-snprintf.o: $(srcdir)/compat/snprintf.c config.h
-strlcat.o: $(srcdir)/compat/strlcat.c config.h
-strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
+memcmp.o: $(srcdir)/compat/memcmp.c config.h $(srcdir)/compat/cpuset.h
+memmove.o: $(srcdir)/compat/memmove.c config.h $(srcdir)/compat/cpuset.h
+pselect.o: $(srcdir)/compat/pselect.c config.h $(srcdir)/compat/cpuset.h
+reallocarray.o: $(srcdir)/compat/reallocarray.c config.h $(srcdir)/compat/cpuset.h
+setproctitle.o: $(srcdir)/compat/setproctitle.c config.h $(srcdir)/compat/cpuset.h
+snprintf.o: $(srcdir)/compat/snprintf.c config.h $(srcdir)/compat/cpuset.h
+strlcat.o: $(srcdir)/compat/strlcat.c config.h $(srcdir)/compat/cpuset.h
+strlcpy.o: $(srcdir)/compat/strlcpy.c config.h $(srcdir)/compat/cpuset.h
strptime.o: $(srcdir)/compat/strptime.c
cutest_bitset.o: $(srcdir)/tpkg/cutest/cutest_bitset.c $(srcdir)/bitset.h \
$(srcdir)/tpkg/cutest/cutest.h
-cutest.o: $(srcdir)/tpkg/cutest/cutest.c config.h \
+cutest.o: $(srcdir)/tpkg/cutest/cutest.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h
-cutest_dname.o: $(srcdir)/tpkg/cutest/cutest_dname.c config.h \
+cutest_dname.o: $(srcdir)/tpkg/cutest/cutest_dname.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h
-cutest_dns.o: $(srcdir)/tpkg/cutest/cutest_dns.c config.h \
+cutest_dns.o: $(srcdir)/tpkg/cutest/cutest_dns.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/dns.h
-cutest_event.o: $(srcdir)/tpkg/cutest/cutest_event.c config.h $(srcdir)/nsd.h \
+cutest_event.o: $(srcdir)/tpkg/cutest/cutest_event.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h \
$(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/tpkg/cutest/cutest.h
cutest_iterated_hash.o: $(srcdir)/tpkg/cutest/cutest_iterated_hash.c config.h \
- $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h \
+ $(srcdir)/compat/cpuset.h $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h \
$(srcdir)/iterated_hash.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h
-cutest_iter.o: $(srcdir)/tpkg/cutest/cutest_iter.c config.h $(srcdir)/nsd.h \
+cutest_iter.o: $(srcdir)/tpkg/cutest/cutest_iter.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/nsd.h \
$(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/options.h \
$(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h $(srcdir)/tpkg/cutest/cutest.h
-cutest_namedb.o: $(srcdir)/tpkg/cutest/cutest_namedb.c config.h \
+cutest_namedb.o: $(srcdir)/tpkg/cutest/cutest_namedb.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/options.h $(srcdir)/region-allocator.h \
$(srcdir)/rbtree.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h \
$(srcdir)/nsec3.h $(srcdir)/udb.h $(srcdir)/difffile.h $(srcdir)/namedb.h $(srcdir)/options.h $(srcdir)/udb.h $(srcdir)/zonec.h $(srcdir)/nsd.h $(srcdir)/edns.h \
$(srcdir)/simdzone/include/zone.h $(srcdir)/simdzone/include/zone/attributes.h \
- simdzone/include/zone/export.h
-cutest_options.o: $(srcdir)/tpkg/cutest/cutest_options.c config.h \
+ simdzone/include/zone/export.h $(srcdir)/rdata.h
+cutest_options.o: $(srcdir)/tpkg/cutest/cutest_options.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/options.h $(srcdir)/region-allocator.h \
$(srcdir)/rbtree.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/nsd.h $(srcdir)/edns.h
-cutest_popen3.o: $(srcdir)/tpkg/cutest/cutest_popen3.c config.h \
+cutest_popen3.o: $(srcdir)/tpkg/cutest/cutest_popen3.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/popen3.h $(srcdir)/tpkg/cutest/cutest.h
-cutest_radtree.o: $(srcdir)/tpkg/cutest/cutest_radtree.c config.h \
+cutest_radtree.o: $(srcdir)/tpkg/cutest/cutest_radtree.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/radtree.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h
-cutest_rbtree.o: $(srcdir)/tpkg/cutest/cutest_rbtree.c config.h \
+cutest_rbtree.o: $(srcdir)/tpkg/cutest/cutest_rbtree.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h
-cutest_region.o: $(srcdir)/tpkg/cutest/cutest_region.c config.h \
+cutest_region.o: $(srcdir)/tpkg/cutest/cutest_region.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/rbtree.h \
$(srcdir)/region-allocator.h
-cutest_rrl.o: $(srcdir)/tpkg/cutest/cutest_rrl.c config.h \
+cutest_rrl.o: $(srcdir)/tpkg/cutest/cutest_rrl.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h \
$(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h \
$(srcdir)/packet.h $(srcdir)/tsig.h
-cutest_run.o: $(srcdir)/tpkg/cutest/cutest_run.c config.h \
+cutest_run.o: $(srcdir)/tpkg/cutest/cutest_run.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/tpkg/cutest/qtest.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h \
- $(srcdir)/util.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h $(srcdir)/bitset.h
-cutest_udb.o: $(srcdir)/tpkg/cutest/cutest_udb.c config.h \
+ $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h
+cutest_udb.o: $(srcdir)/tpkg/cutest/cutest_udb.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/udb.h
-cutest_util.o: $(srcdir)/tpkg/cutest/cutest_util.c config.h \
+cutest_util.o: $(srcdir)/tpkg/cutest/cutest_util.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h
-cutest_xfrd_tcp.o: $(srcdir)/tpkg/cutest/cutest_xfrd_tcp.c config.h \
+cutest_xfrd_tcp.o: $(srcdir)/tpkg/cutest/cutest_xfrd_tcp.c config.h $(srcdir)/compat/cpuset.h \
$(srcdir)/tpkg/cutest/cutest.h $(srcdir)/xfrd-tcp.h $(srcdir)/xfrd.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h \
$(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h \
$(srcdir)/tsig.h
popen3_echo.o: $(srcdir)/tpkg/cutest/popen3_echo.c
-qtest.o: $(srcdir)/tpkg/cutest/qtest.c config.h $(srcdir)/tpkg/cutest/qtest.h \
+qtest.o: $(srcdir)/tpkg/cutest/qtest.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/tpkg/cutest/qtest.h \
$(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/bitset.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \
$(srcdir)/buffer.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/namedb.h \
$(srcdir)/util.h $(srcdir)/nsec3.h $(srcdir)/options.h $(srcdir)/packet.h $(srcdir)/dname.h $(srcdir)/rdata.h
Index: README.md
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/README.md,v
diff -u -p -r1.3 README.md
--- README.md 3 Sep 2025 18:46:48 -0000 1.3
+++ README.md 18 Mar 2026 20:44:03 -0000
@@ -4,7 +4,7 @@
[](https://scan.coverity.com/projects/nlnetlabs-nsd)
[](https://repology.org/project/nsd/versions)
[](https://bestpractices.coreinfrastructure.org/projects/1462)
-[](https://fosstodon.org/@nlnetlabs)
+[](https://social.nlnetlabs.nl/@nlnetlabs)
The NLnet Labs Name Server Daemon (NSD) is an authoritative DNS name server.
It has been developed for operations in environments where speed,
Index: aclocal.m4
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/aclocal.m4,v
diff -u -p -r1.6 aclocal.m4
--- aclocal.m4 6 Sep 2025 17:41:37 -0000 1.6
+++ aclocal.m4 18 Mar 2026 20:44:03 -0000
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
-# Copyright (C) 1996-2025 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -13,7 +13,7 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
-# serial 13 (pkgconf)
+# serial 12 (pkg-config-0.29.2)
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@@ -29,7 +29,9 @@ dnl MERCHANTABILITY or FITNESS FOR A PAR
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
-dnl along with this program; if not, see <https://www.gnu.org/licenses/>.
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
@@ -58,8 +60,8 @@ m4_if(m4_version_compare(PKG_MACROS_VERS
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
-dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND])
-dnl ---------------------------------------------------------
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
@@ -67,12 +69,6 @@ dnl first found in the path. Checks that
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
-dnl
-dnl If pkg-config is not found or older than specified, it will result
-dnl in an empty PKG_CONFIG variable. To avoid widespread issues with
-dnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting.
-dnl You can specify [PKG_CONFIG=false] as an action instead, which would
-dnl result in pkg-config tests failing, but no bogus error messages.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
@@ -93,9 +89,6 @@ if test -n "$PKG_CONFIG"; then
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
-fi
-if test -z "$PKG_CONFIG"; then
- m4_default([$2], [AC_MSG_ERROR([pkg-config not found])])
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
Index: acx_nlnetlabs.m4
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/acx_nlnetlabs.m4,v
diff -u -p -r1.10 acx_nlnetlabs.m4
--- acx_nlnetlabs.m4 12 Apr 2024 15:53:34 -0000 1.10
+++ acx_nlnetlabs.m4 18 Mar 2026 20:44:03 -0000
@@ -2,7 +2,12 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
-# Version 48
+# Version 51
+# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints
+# a warning for 'unknown attribute' when nonstring is used.
+# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
+# check by ACX_FUNC_MALLOC.
+# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
# and check for getaddrinfo with only header.
# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
@@ -71,6 +76,7 @@
# ACX_DEPFLAG - find cc dependency flags.
# ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX.
# ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax.
+# ACX_CHECK_NONSTRING_ATTRIBUTE - find cc nonstring attribute syntax.
# ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax.
# ACX_CHECK_FLTO - see if cc supports -flto and use it if so.
# ACX_LIBTOOL_C_ONLY - create libtool for C only, improved.
@@ -92,6 +98,7 @@
# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably.
# ACX_FUNC_MALLOC - check malloc, define replacement .
# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format.
+# AHX_CONFIG_NONSTRING_ATTRIBUTE - config.h text for nonstring.
# AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused.
# AHX_CONFIG_FSEEKO - define fseeko, ftello fallback.
# AHX_CONFIG_RAND_MAX - define RAND_MAX if needed.
@@ -490,7 +497,7 @@ AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
])
dnl Check how to mark function arguments as unused.
-dnl result in HAVE_ATTR_UNUSED.
+dnl result in HAVE_ATTR_UNUSED.
dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
@@ -525,6 +532,49 @@ if test $ac_cv_c_unused_attribute = yes;
fi
])dnl
+dnl Check how to mark function arguments as nonstring.
+dnl result in HAVE_ATTR_NONSTRING.
+dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
+AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
+[AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([ACX_CHECK_ERROR_FLAGS])
+BAKCFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $ERRFLAG"
+AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
+AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
+[ac_cv_c_nonstring_attribute=no
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+struct test {
+ char __attribute__((nonstring)) s[1];
+};
+]], [[
+ struct test t = { "1" };
+ (void) t;
+]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
+CFLAGS="$BAKCFLAGS"
+])
+
+dnl Setup ATTR_NONSTRING config.h parts.
+dnl make sure you call ACX_CHECK_NONSTRING_ATTRIBUTE also.
+AC_DEFUN([AHX_CONFIG_NONSTRING_ATTRIBUTE],
+[
+#if defined(DOXYGEN)
+# define ATTR_NONSTRING(x) x
+#elif defined(__cplusplus)
+# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
+#elif defined(HAVE_ATTR_NONSTRING)
+# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
+#else /* !HAVE_ATTR_NONSTRING */
+# define ATTR_NONSTRING(x) x
+#endif /* !HAVE_ATTR_NONSTRING */
+])
+
+AC_MSG_RESULT($ac_cv_c_nonstring_attribute)
+if test $ac_cv_c_nonstring_attribute = yes; then
+ AC_DEFINE(HAVE_ATTR_NONSTRING, 1, [Whether the C compiler accepts the "nonstring" attribute])
+fi
+])dnl
+
dnl Pre-fun for ACX_LIBTOOL_C_ONLY
AC_DEFUN([ACX_LIBTOOL_C_PRE], [
# skip these tests, we do not need them.
@@ -1190,8 +1240,9 @@ dnl detect malloc and provide malloc com
dnl $1: unique name for compat code
AC_DEFUN([ACX_FUNC_MALLOC],
[
- AC_MSG_CHECKING([for GNU libc compatible malloc])
- AC_RUN_IFELSE([AC_LANG_PROGRAM(
+ AC_CACHE_CHECK([for GNU libc compatible malloc],[ac_cv_func_malloc_0_nonnull],
+ [
+ AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
#include <stdlib.h>
#else
@@ -1199,14 +1250,16 @@ char *malloc ();
#endif
]], [ if(malloc(0) != 0) return 1;])
],
- [AC_MSG_RESULT([no])
- AC_LIBOBJ(malloc)
- AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ,
- [AC_MSG_RESULT([yes])
- AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
- [AC_MSG_RESULT([no (crosscompile)])
- AC_LIBOBJ(malloc)
- AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] )
+ [ac_cv_func_malloc_0_nonnull=no],
+ [ac_cv_func_malloc_0_nonnull=yes],
+ [ac_cv_func_malloc_0_nonnull="no (crosscompile)"])
+ ])
+ AS_IF([test "$ac_cv_func_malloc_0_nonnull" = yes],
+ [AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
+ [
+ AC_LIBOBJ(malloc)
+ AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])
+ ])
])
dnl Define fallback for fseeko and ftello if needed.
Index: axfr.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/axfr.c,v
diff -u -p -r1.24 axfr.c
--- axfr.c 3 Sep 2025 18:46:48 -0000 1.24
+++ axfr.c 18 Mar 2026 20:44:03 -0000
@@ -82,8 +82,8 @@ query_axfr(struct nsd *nsd, struct query
assert(query->axfr_zone->soa_rrset->rr_count == 1);
added = packet_encode_rr(query,
query->axfr_zone->apex,
- &query->axfr_zone->soa_rrset->rrs[0],
- query->axfr_zone->soa_rrset->rrs[0].ttl);
+ query->axfr_zone->soa_rrset->rrs[0],
+ query->axfr_zone->soa_rrset->rrs[0]->ttl);
if (!added) {
/* XXX: This should never happen... generate error code? */
abort();
@@ -123,8 +123,8 @@ query_axfr(struct nsd *nsd, struct query
added = packet_encode_rr(
query,
query->axfr_current_domain,
- &query->axfr_current_rrset->rrs[query->axfr_current_rr],
- query->axfr_current_rrset->rrs[query->axfr_current_rr].ttl);
+ query->axfr_current_rrset->rrs[query->axfr_current_rr],
+ query->axfr_current_rrset->rrs[query->axfr_current_rr]->ttl);
if(total_added == 0) {
query->maxlen = oldmaxlen;
if(query_overflow(query)) {
@@ -154,8 +154,8 @@ query_axfr(struct nsd *nsd, struct query
assert(query->axfr_zone->soa_rrset->rr_count == 1);
added = packet_encode_rr(query,
query->axfr_zone->apex,
- &query->axfr_zone->soa_rrset->rrs[0],
- query->axfr_zone->soa_rrset->rrs[0].ttl);
+ query->axfr_zone->soa_rrset->rrs[0],
+ query->axfr_zone->soa_rrset->rrs[0]->ttl);
if (added) {
++total_added;
query->tsig_sign_it = 1; /* sign last packet */
@@ -256,10 +256,10 @@ static int axfr_ixfr_can_admit_query(str
return 0;
}
#ifdef HAVE_SSL
- DEBUG(DEBUG_XFRD,1, (LOG_INFO, "%s admitted acl %s %s %s",
+ DEBUG(DEBUG_XFRD,1, (LOG_INFO, "%s admitted acl %s %s%s",
(q->qtype==TYPE_AXFR?"axfr":"ixfr"),
acl->ip_address_spec, acl->key_name?acl->key_name:"NOKEY",
- (q->tls||q->tls_auth)?(q->tls?"tls":"tls-auth"):""));
+ (q->tls||q->tls_auth)?(q->tls?" tls":" tls-auth"):""));
#else
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "%s admitted acl %s %s",
(q->qtype==TYPE_AXFR?"axfr":"ixfr"),
@@ -269,11 +269,12 @@ static int axfr_ixfr_can_admit_query(str
char a[128];
addr2str(&q->client_addr, a, sizeof(a));
#ifdef HAVE_SSL
- VERBOSITY(1, (LOG_INFO, "%s for %s from %s %s %s",
+ VERBOSITY(1, (LOG_INFO, "%s for %s from %s%s%s%s",
(q->qtype==TYPE_AXFR?"axfr":"ixfr"),
dname_to_string(q->qname, NULL), a,
- (q->tls||q->tls_auth)?(q->tls?"tls":"tls-auth"):"",
- q->cert_cn?q->cert_cn:"not-verified"));
+ (q->tls||q->tls_auth)?(q->tls?" tls":" tls-auth"):"",
+ (q->tls||q->tls_auth)?" ":"",
+ (q->tls||q->tls_auth)?(q->cert_cn?q->cert_cn:"not-verified"):""));
#else
VERBOSITY(1, (LOG_INFO, "%s for %s from %s",
(q->qtype==TYPE_AXFR?"axfr":"ixfr"),
Index: config.guess
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/config.guess,v
diff -u -p -r1.5 config.guess
--- config.guess 6 Sep 2025 17:41:37 -0000 1.5
+++ config.guess 18 Mar 2026 20:44:03 -0000
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2023 Free Software Foundation, Inc.
+# Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2023-08-22'
+timestamp='2022-01-09'
# This file 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,7 @@ me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
-Output the configuration name of the system '$me' is run on.
+Output the configuration name of the system \`$me' is run on.
Options:
-h, --help print this help, then exit
@@ -60,13 +60,13 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try '$me --help' for more information."
+Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -102,8 +102,8 @@ GUESS=
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
-# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
-# use 'HOST_CC' if defined, but it is deprecated.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
@@ -155,9 +155,6 @@ Linux|GNU|GNU/*)
set_cc_for_build
cat <<-EOF > "$dummy.c"
- #if defined(__ANDROID__)
- LIBC=android
- #else
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -172,7 +169,6 @@ Linux|GNU|GNU/*)
LIBC=musl
#endif
#endif
- #endif
EOF
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
eval "$cc_set_libc"
@@ -463,7 +459,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME
UNAME_RELEASE=`uname -v`
;;
esac
- # Japanese Language versions have a version number like '4.1.3-JL'.
+ # Japanese Language versions have a version number like `4.1.3-JL'.
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
GUESS=sparc-sun-sunos$SUN_REL
;;
@@ -908,7 +904,7 @@ EOF
fi
;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=`uname -p`
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
@@ -970,37 +966,11 @@ EOF
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
;;
- x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
- GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
- ;;
- *:[Mm]anagarm:*:*)
- GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
- ;;
*:Minix:*:*)
GUESS=$UNAME_MACHINE-unknown-minix
;;
aarch64:Linux:*:*)
- set_cc_for_build
- CPU=$UNAME_MACHINE
- LIBCABI=$LIBC
- if test "$CC_FOR_BUILD" != no_compiler_found; then
- ABI=64
- sed 's/^ //' << EOF > "$dummy.c"
- #ifdef __ARM_EABI__
- #ifdef __ARM_PCS_VFP
- ABI=eabihf
- #else
- ABI=eabi
- #endif
- #endif
-EOF
- cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
- eval "$cc_set_abi"
- case $ABI in
- eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
- esac
- fi
- GUESS=$CPU-unknown-linux-$LIBCABI
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
@@ -1066,16 +1036,7 @@ EOF
k1om:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
- kvx:Linux:*:*)
- GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
- ;;
- kvx:cos:*:*)
- GUESS=$UNAME_MACHINE-unknown-cos
- ;;
- kvx:mbr:*:*)
- GUESS=$UNAME_MACHINE-unknown-mbr
- ;;
- loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+ loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
m32r*:Linux:*:*)
@@ -1190,27 +1151,16 @@ EOF
;;
x86_64:Linux:*:*)
set_cc_for_build
- CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
- ABI=64
- sed 's/^ //' << EOF > "$dummy.c"
- #ifdef __i386__
- ABI=x86
- #else
- #ifdef __ILP32__
- ABI=x32
- #endif
- #endif
-EOF
- cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
- eval "$cc_set_abi"
- case $ABI in
- x86) CPU=i686 ;;
- x32) LIBCABI=${LIBC}x32 ;;
- esac
+ if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_X32 >/dev/null
+ then
+ LIBCABI=${LIBC}x32
+ fi
fi
- GUESS=$CPU-pc-linux-$LIBCABI
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
;;
xtensa*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
@@ -1230,7 +1180,7 @@ EOF
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
;;
i*86:OS/2:*:*)
- # If we were able to find 'uname', then EMX Unix compatibility
+ # If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
GUESS=$UNAME_MACHINE-pc-os2-emx
;;
@@ -1371,7 +1321,7 @@ EOF
GUESS=ns32k-sni-sysv
fi
;;
- PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
GUESS=i586-unisys-sysv4
;;
@@ -1417,11 +1367,8 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
GUESS=i586-pc-haiku
;;
- ppc:Haiku:*:*) # Haiku running on Apple PowerPC
- GUESS=powerpc-apple-haiku
- ;;
- *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
- GUESS=$UNAME_MACHINE-unknown-haiku
+ x86_64:Haiku:*:*)
+ GUESS=x86_64-unknown-haiku
;;
SX-4:SUPER-UX:*:*)
GUESS=sx4-nec-superux$UNAME_RELEASE
Index: config.h.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/config.h.in,v
diff -u -p -r1.46 config.h.in
--- config.h.in 6 Sep 2025 17:41:37 -0000 1.46
+++ config.h.in 18 Mar 2026 20:44:03 -0000
@@ -46,22 +46,22 @@
/* Define to the default facility for syslog. */
#undef FACILITY
-/* Define to 1 if you have the 'accept4' function. */
+/* Define to 1 if you have the `accept4' function. */
#undef HAVE_ACCEPT4
-/* Define to 1 if you have the 'alarm' function. */
+/* Define to 1 if you have the `alarm' function. */
#undef HAVE_ALARM
-/* Define to 1 if you have the 'arc4random' function. */
+/* Define to 1 if you have the `arc4random' function. */
#undef HAVE_ARC4RANDOM
-/* Define to 1 if you have the 'arc4random_uniform' function. */
+/* Define to 1 if you have the `arc4random_uniform' function. */
#undef HAVE_ARC4RANDOM_UNIFORM
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
-/* Define to 1 if you have the 'ASN1_STRING_get0_data' function. */
+/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
#undef HAVE_ASN1_STRING_GET0_DATA
/* Whether the C compiler accepts the "format" attribute */
@@ -76,145 +76,148 @@
/* Whether the C compiler accepts the "weak" attribute */
#undef HAVE_ATTR_WEAK
-/* Define to 1 if you have the 'b64_ntop' function. */
+/* Define to 1 if you have the `b64_ntop' function. */
#undef HAVE_B64_NTOP
-/* Define to 1 if you have the 'b64_pton' function. */
+/* Define to 1 if you have the `b64_pton' function. */
#undef HAVE_B64_PTON
-/* Define to 1 if you have the 'basename' function. */
+/* Define to 1 if you have the `basename' function. */
#undef HAVE_BASENAME
-/* Define to 1 if your system has a working 'chown' function. */
+/* Define to 1 if your system has a working `chown' function. */
#undef HAVE_CHOWN
-/* Define to 1 if you have the 'chroot' function. */
+/* Define to 1 if you have the `chroot' function. */
#undef HAVE_CHROOT
-/* Define to 1 if you have the 'clock_gettime' function. */
+/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
-/* Define to 1 if the system has the type 'cpuid_t'. */
+/* Define to 1 if the system has the type `cpuid_t'. */
#undef HAVE_CPUID_T
-/* Define to 1 if the system has the type 'cpuset_t'. */
+/* Define to 1 if the system has the type `cpuset_t'. */
#undef HAVE_CPUSET_T
-/* Define to 1 if the system has the type 'cpu_set_t'. */
+/* Define to 1 if the system has the type `cpu_set_t'. */
#undef HAVE_CPU_SET_T
-/* Define to 1 if you have the 'CRYPTO_memcmp' function. */
+/* Define to 1 if you have the `CRYPTO_memcmp' function. */
#undef HAVE_CRYPTO_MEMCMP
/* if time.h provides ctime_r prototype */
#undef HAVE_CTIME_R_PROTO
-/* Define to 1 if you have the declaration of 'reallocarray', and to 0 if you
+/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
don't. */
#undef HAVE_DECL_REALLOCARRAY
-/* Define to 1 if you have the declaration of 'SSL_CTX_set_ecdh_auto', and to
+/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to
0 if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
-/* Define to 1 if you have the declaration of 'SSL_CTX_set_tmp_ecdh', and to 0
+/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0
if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH
-/* Define to 1 if you have the 'dup2' function. */
+/* Define to 1 if you have the `dup2' function. */
#undef HAVE_DUP2
-/* Define to 1 if you have the 'EC_KEY_new_by_curve_name' function. */
+/* Define to 1 if you have the `EC_KEY_new_by_curve_name' function. */
#undef HAVE_EC_KEY_NEW_BY_CURVE_NAME
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
-/* Define to 1 if you have the 'endpwent' function. */
+/* Define to 1 if you have the `endpwent' function. */
#undef HAVE_ENDPWENT
-/* Define to 1 if you have the 'ERR_load_crypto_strings' function. */
+/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
#undef HAVE_ERR_LOAD_CRYPTO_STRINGS
-/* Define to 1 if you have the 'ERR_load_SSL_strings' function. */
+/* Define to 1 if you have the `ERR_load_SSL_strings' function. */
#undef HAVE_ERR_LOAD_SSL_STRINGS
-/* Define to 1 if you have the 'event_base_free' function. */
+/* Define to 1 if you have the `event_base_free' function. */
#undef HAVE_EVENT_BASE_FREE
-/* Define to 1 if you have the 'event_base_get_method' function. */
+/* Define to 1 if you have the `event_base_get_method' function. */
#undef HAVE_EVENT_BASE_GET_METHOD
-/* Define to 1 if you have the 'event_base_new' function. */
+/* Define to 1 if you have the `event_base_new' function. */
#undef HAVE_EVENT_BASE_NEW
-/* Define to 1 if you have the 'event_base_once' function. */
+/* Define to 1 if you have the `event_base_once' function. */
#undef HAVE_EVENT_BASE_ONCE
/* Define to 1 if you have the <event.h> header file. */
#undef HAVE_EVENT_H
-/* Define to 1 if you have the 'evhttp_free' function. */
+/* Define to 1 if you have the `evhttp_free' function. */
#undef HAVE_EVHTTP_FREE
-/* Define to 1 if you have the 'EVP_cleanup' function. */
+/* Define to 1 if you have the `EVP_cleanup' function. */
#undef HAVE_EVP_CLEANUP
-/* Define to 1 if you have the 'EVP_MAC_CTX_get_mac_size' function. */
+/* Define to 1 if you have the `EVP_MAC_CTX_get_mac_size' function. */
#undef HAVE_EVP_MAC_CTX_GET_MAC_SIZE
-/* Define to 1 if you have the 'EVP_MAC_CTX_new' function. */
+/* Define to 1 if you have the `EVP_MAC_CTX_new' function. */
#undef HAVE_EVP_MAC_CTX_NEW
-/* Define to 1 if you have the 'EVP_MAC_CTX_set_params' function. */
+/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
-/* Define to 1 if you have the 'EVP_PKEY_get0_type_name' function. */
+/* Define to 1 if you have the `EVP_PKEY_get0_type_name' function. */
#undef HAVE_EVP_PKEY_GET0_TYPE_NAME
-/* Define to 1 if you have the 'ev_default_loop' function. */
+/* Define to 1 if you have the `ev_default_loop' function. */
#undef HAVE_EV_DEFAULT_LOOP
-/* Define to 1 if you have the 'ev_loop' function. */
+/* Define to 1 if you have the `ev_loop' function. */
#undef HAVE_EV_LOOP
-/* Define to 1 if you have the 'explicit_bzero' function. */
+/* Define to 1 if you have the `explicit_bzero' function. */
#undef HAVE_EXPLICIT_BZERO
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
-/* Define to 1 if you have the 'fork' function. */
+/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
-/* Define to 1 if you have the 'freeaddrinfo' function. */
+/* Define to 1 if you have the `freeaddrinfo' function. */
#undef HAVE_FREEADDRINFO
-/* Define to 1 if fseeko (and ftello) are declared in stdio.h. */
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
-/* Define to 1 if you have the 'gai_strerror' function. */
+/* Define to 1 if you have the `fstrm_tcp_writer_options_init' function. */
+#undef HAVE_FSTRM_TCP_WRITER_OPTIONS_INIT
+
+/* Define to 1 if you have the `gai_strerror' function. */
#undef HAVE_GAI_STRERROR
-/* Define to 1 if you have the 'getaddrinfo' function. */
+/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
-/* Define to 1 if you have the 'gethostname' function. */
+/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
-/* Define to 1 if you have the 'getifaddrs' function. */
+/* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS
-/* Define to 1 if you have the 'getnameinfo' function. */
+/* Define to 1 if you have the `getnameinfo' function. */
#undef HAVE_GETNAMEINFO
-/* Define to 1 if you have the 'getpwnam' function. */
+/* Define to 1 if you have the `getpwnam' function. */
#undef HAVE_GETPWNAM
-/* Define to 1 if you have the 'getrandom' function. */
+/* Define to 1 if you have the `getrandom' function. */
#undef HAVE_GETRANDOM
-/* Define to 1 if you have the 'glob' function. */
+/* Define to 1 if you have the `glob' function. */
#undef HAVE_GLOB
/* Define to 1 if you have the <glob.h> header file. */
@@ -223,65 +226,65 @@
/* Define to 1 if you have the <grp.h> header file. */
#undef HAVE_GRP_H
-/* Define to 1 if you have the 'HMAC_CTX_new' function. */
+/* Define to 1 if you have the `HMAC_CTX_new' function. */
#undef HAVE_HMAC_CTX_NEW
-/* Define to 1 if you have the 'HMAC_CTX_reset' function. */
+/* Define to 1 if you have the `HMAC_CTX_reset' function. */
#undef HAVE_HMAC_CTX_RESET
/* Define to 1 if you have the <ifaddrs.h> header file. */
#undef HAVE_IFADDRS_H
-/* Define to 1 if you have the 'inet_aton' function. */
+/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
-/* Define to 1 if you have the 'inet_ntop' function. */
+/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
-/* Define to 1 if you have the 'inet_pton' function. */
+/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
-/* Define to 1 if you have the 'initgroups' function. */
+/* Define to 1 if you have the `initgroups' function. */
#undef HAVE_INITGROUPS
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* Define to 1 if you have the 'crypto' library (-lcrypto). */
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
-/* Define to 1 if you have the 'localtime_r' function. */
+/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
/* Define to 1 if you have the <login_cap.h> header file. */
#undef HAVE_LOGIN_CAP_H
-/* Define to 1 if your system has a GNU libc compatible 'malloc' function, and
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
-/* Define to 1 if you have the 'memcpy' function. */
+/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
-/* Define to 1 if you have the 'memmove' function. */
+/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
-/* Define to 1 if you have the 'memset' function. */
+/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <minix/config.h> header file. */
#undef HAVE_MINIX_CONFIG_H
-/* Define to 1 if you have the 'mmap' function. */
+/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* If sys/socket.h has a struct mmsghdr. */
#undef HAVE_MMSGHDR
-/* Define to 1 if you have the 'munmap' function. */
+/* Define to 1 if you have the `munmap' function. */
#undef HAVE_MUNMAP
/* Define to 1 if you have the <netdb.h> header file. */
@@ -299,10 +302,10 @@
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
-/* Define to 1 if you have the 'OPENSSL_init_crypto' function. */
+/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
#undef HAVE_OPENSSL_INIT_CRYPTO
-/* Define to 1 if you have the 'OPENSSL_init_ssl' function. */
+/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
#undef HAVE_OPENSSL_INIT_SSL
/* Define to 1 if you have the <openssl/ocsp.h> header file. */
@@ -317,16 +320,16 @@
/* Define to 1 if you have the <openssl/x509v3.h> header file. */
#undef HAVE_OPENSSL_X509V3_H
-/* Define to 1 if you have the 'ppoll' function. */
+/* Define to 1 if you have the `ppoll' function. */
#undef HAVE_PPOLL
-/* Define to 1 if you have the 'pselect' function. */
+/* Define to 1 if you have the `pselect' function. */
#undef HAVE_PSELECT
/* if sys/select.h provides pselect prototype */
#undef HAVE_PSELECT_PROTO
-/* Define to 1 if you have the 'pwrite' function. */
+/* Define to 1 if you have the `pwrite' function. */
#undef HAVE_PWRITE
/* If we have reallocarray(3) */
@@ -344,49 +347,49 @@
/* Define if sendmmsg is implemented */
#undef HAVE_SENDMMSG
-/* Define to 1 if you have the 'setproctitle' function. */
+/* Define to 1 if you have the `setproctitle' function. */
#undef HAVE_SETPROCTITLE
-/* Define to 1 if you have the 'setregid' function. */
+/* Define to 1 if you have the `setregid' function. */
#undef HAVE_SETREGID
-/* Define to 1 if you have the 'setresgid' function. */
+/* Define to 1 if you have the `setresgid' function. */
#undef HAVE_SETRESGID
-/* Define to 1 if you have the 'setresuid' function. */
+/* Define to 1 if you have the `setresuid' function. */
#undef HAVE_SETRESUID
-/* Define to 1 if you have the 'setreuid' function. */
+/* Define to 1 if you have the `setreuid' function. */
#undef HAVE_SETREUID
-/* Define to 1 if you have the 'setusercontext' function. */
+/* Define to 1 if you have the `setusercontext' function. */
#undef HAVE_SETUSERCONTEXT
-/* Define to 1 if you have the 'SHA1_Init' function. */
+/* Define to 1 if you have the `SHA1_Init' function. */
#undef HAVE_SHA1_INIT
-/* Define to 1 if you have the 'sigaction' function. */
+/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
-/* Define to 1 if you have the 'sigprocmask' function. */
+/* Define to 1 if you have the `sigprocmask' function. */
#undef HAVE_SIGPROCMASK
-/* Define to 1 if you have the 'snprintf' function. */
+/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
-/* Define to 1 if you have the 'socket' function. */
+/* Define to 1 if you have the `socket' function. */
#undef HAVE_SOCKET
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
-/* Define to 1 if you have the 'SSL_CTX_set_security_level' function. */
+/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
-/* Define to 1 if you have the 'SSL_get1_peer_certificate' function. */
+/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */
#undef HAVE_SSL_GET1_PEER_CERTIFICATE
/* Define to 1 if you have the <stdarg.h> header file. */
@@ -404,19 +407,19 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
-/* Define to 1 if you have the 'strcasecmp' function. */
+/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
-/* Define to 1 if you have the 'strchr' function. */
+/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
-/* Define to 1 if you have the 'strdup' function. */
+/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
-/* Define to 1 if you have the 'strerror' function. */
+/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
-/* Define to 1 if you have the 'strftime' function. */
+/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
@@ -425,34 +428,34 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
-/* Define to 1 if you have the 'strlcat' function. */
+/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
-/* Define to 1 if you have the 'strlcpy' function. */
+/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
-/* Define to 1 if you have the 'strncasecmp' function. */
+/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
-/* Define to 1 if you have the 'strptime' function. */
+/* Define to 1 if you have the `strptime' function. */
#undef HAVE_STRPTIME
-/* Define to 1 if you have the 'strtol' function. */
+/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
-/* Define to 1 if 'sun_len' is a member of 'struct sockaddr_un'. */
+/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
-/* Define to 1 if 'st_mtimensec' is a member of 'struct stat'. */
+/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
-/* Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'. */
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
/* If time.h has a struct timespec (for pselect). */
#undef HAVE_STRUCT_TIMESPEC
-/* Define to 1 if you have the 'sysconf' function. */
+/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
/* Define to 1 if you have the <syslog.h> header file. */
@@ -503,7 +506,7 @@
/* Define if TLS 1.3 is supported by OpenSSL */
#undef HAVE_TLS_1_3
-/* Define to 1 if you have the 'tzset' function. */
+/* Define to 1 if you have the `tzset' function. */
#undef HAVE_TZSET
/* Define to 1 if you have the <unistd.h> header file. */
@@ -512,7 +515,7 @@
/* Define this if you have double va_list definitions. */
#undef HAVE_VA_LIST_DOUBLE_DEF
-/* Define to 1 if you have the 'vfork' function. */
+/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
@@ -521,13 +524,13 @@
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
-/* Define to 1 if 'fork' works. */
+/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
-/* Define to 1 if 'vfork' works. */
+/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
-/* Define to 1 if you have the 'writev' function. */
+/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
/* Define to the default nsd identity. */
@@ -616,13 +619,13 @@
/* NSD shared files dir */
#undef SHAREDFILESDIR
-/* The size of 'off_t', as computed by sizeof. */
+/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
-/* The size of 'void*', as computed by sizeof. */
+/* The size of `void*', as computed by sizeof. */
#undef SIZEOF_VOIDP
-/* Define to 1 if all of the C89 standard headers exist (not just the ones
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
@@ -677,7 +680,7 @@
/* Define this to configure to use the radix tree. */
#undef USE_RADIX_TREE
-/* Enable extensions on AIX, Interix, z/OS. */
+/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
@@ -738,15 +741,11 @@
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
-/* Enable extensions specified by C23 Annex F. */
-#ifndef __STDC_WANT_IEC_60559_EXT__
-# undef __STDC_WANT_IEC_60559_EXT__
-#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
-/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
@@ -790,8 +789,8 @@
/* Pathname to where the NSD transfer dir is created. */
#undef XFRDIR
-/* Define to 1 if 'lex' declares 'yytext' as a 'char *' by default, not a
- 'char[]'. */
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
#undef YYTEXT_POINTER
/* Pathname to the NSD zone list file. */
@@ -803,31 +802,25 @@
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
-/* Define to 1 if necessary to make fseeko visible. */
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
-/* Define to 1 on platforms where this makes off_t a 64-bit type. */
+/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Enable for compile on Minix */
#undef _NETBSD_SOURCE
-/* Number of bits in time_t, on hosts where this is settable. */
-#undef _TIME_BITS
-
-/* Define to 1 on platforms where this makes time_t a 64-bit type. */
-#undef __MINGW_USE_VC2005_COMPAT
-
-/* Define to empty if 'const' does not conform to ANSI C. */
+/* Define to empty if `const' does not conform to ANSI C. */
#undef const
-/* Define as 'int' if <sys/types.h> doesn't define. */
+/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* in_addr_t */
#undef in_addr_t
-/* Define to '__inline__' or '__inline' if that's what the C compiler
+/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
@@ -848,7 +841,7 @@
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
-/* Define to 'long int' if <sys/types.h> does not define. */
+/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define as a signed integer type capable of holding a process identifier. */
@@ -857,7 +850,7 @@
/* Define "sig_atomic_t" to "int" if "sig_atomic_t" is missing */
#undef sig_atomic_t
-/* Define as 'unsigned int' if <stddef.h> doesn't define. */
+/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define "socklen_t" to "int" if "socklen_t" is missing */
@@ -872,7 +865,7 @@
/* Define "suseconds_t" to "time_t" if "suseconds_t" is missing */
#undef suseconds_t
-/* Define as 'int' if <sys/types.h> doesn't define. */
+/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define "uint16_t" to "unsigned short" if "uint16_t" is missing */
@@ -890,7 +883,7 @@
/* Define "uintptr_t" to "void*" if "uintptr_t" is missing */
#undef uintptr_t
-/* Define as 'fork' if 'vfork' does not work. */
+/* Define as `fork' if `vfork' does not work. */
#undef vfork
Index: config.sub
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/config.sub,v
diff -u -p -r1.5 config.sub
--- config.sub 6 Sep 2025 17:41:37 -0000 1.5
+++ config.sub 18 Mar 2026 20:44:03 -0000
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2023 Free Software Foundation, Inc.
+# Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2023-09-19'
+timestamp='2022-01-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -76,13 +76,13 @@ Report bugs and patches to <config-patch
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try '$me --help' for more information."
+Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -130,7 +130,7 @@ IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
*-*-*-*-*)
- echo "Invalid configuration '$1': more than four components" >&2
+ echo Invalid configuration \`"$1"\': more than four components >&2
exit 1
;;
*-*-*-*)
@@ -145,8 +145,7 @@ case $1 in
nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
- | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \
- | windows-* )
+ | storm-chaos* | os2-emx* | rtmk-nova*)
basic_machine=$field1
basic_os=$maybe_os
;;
@@ -944,7 +943,7 @@ $basic_machine
EOF
IFS=$saved_IFS
;;
- # We use 'pc' rather than 'unknown'
+ # We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
@@ -1076,7 +1075,7 @@ case $cpu-$vendor in
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
cpu=i586
;;
- pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
cpu=i686
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
@@ -1181,7 +1180,7 @@ case $cpu-$vendor in
case $cpu in
1750a | 580 \
| a29k \
- | aarch64 | aarch64_be | aarch64c | arm64ec \
+ | aarch64 | aarch64_be \
| abacus \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
@@ -1200,23 +1199,45 @@ case $cpu-$vendor in
| d10v | d30v | dlx | dsp16xx \
| e2k | elxsi | epiphany \
| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
- | javascript \
| h8300 | h8500 \
| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i*86 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
- | kvx \
| le32 | le64 \
| lm32 \
- | loongarch32 | loongarch64 \
+ | loongarch32 | loongarch64 | loongarchx32 \
| m32c | m32r | m32rle \
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
| m88110 | m88k | maxq | mb | mcore | mep | metag \
| microblaze | microblazeel \
- | mips* \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64eb | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r3 | mipsisa32r3el \
+ | mipsisa32r5 | mipsisa32r5el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r3 | mipsisa64r3el \
+ | mipsisa64r5 | mipsisa64r5el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
| mmix \
| mn10200 | mn10300 \
| moxie \
@@ -1264,7 +1285,7 @@ case $cpu-$vendor in
;;
*)
- echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
+ echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
exit 1
;;
esac
@@ -1285,12 +1306,11 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if test x"$basic_os" != x
+if test x$basic_os != x
then
# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
# set os.
-obj=
case $basic_os in
gnu/linux*)
kernel=linux
@@ -1321,10 +1341,6 @@ EOF
kernel=linux
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
;;
- managarm*)
- kernel=managarm
- os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
- ;;
*)
kernel=
os=$basic_os
@@ -1490,16 +1506,10 @@ case $os in
os=eabi
;;
*)
- os=
- obj=elf
+ os=elf
;;
esac
;;
- aout* | coff* | elf* | pe*)
- # These are machine code file formats, not OSes
- obj=$os
- os=
- ;;
*)
# No normalization, but not necessarily accepted, that comes below.
;;
@@ -1518,15 +1528,12 @@ else
# system, and we'll never get to this point.
kernel=
-obj=
case $cpu-$vendor in
score-*)
- os=
- obj=elf
+ os=elf
;;
spu-*)
- os=
- obj=elf
+ os=elf
;;
*-acorn)
os=riscix1.2
@@ -1536,35 +1543,28 @@ case $cpu-$vendor in
os=gnu
;;
arm*-semi)
- os=
- obj=aout
+ os=aout
;;
c4x-* | tic4x-*)
- os=
- obj=coff
+ os=coff
;;
c8051-*)
- os=
- obj=elf
+ os=elf
;;
clipper-intergraph)
os=clix
;;
hexagon-*)
- os=
- obj=elf
+ os=elf
;;
tic54x-*)
- os=
- obj=coff
+ os=coff
;;
tic55x-*)
- os=
- obj=coff
+ os=coff
;;
tic6x-*)
- os=
- obj=coff
+ os=coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1586,24 +1586,19 @@ case $cpu-$vendor in
os=sunos3
;;
m68*-cisco)
- os=
- obj=aout
+ os=aout
;;
mep-*)
- os=
- obj=elf
+ os=elf
;;
mips*-cisco)
- os=
- obj=elf
+ os=elf
;;
mips*-*)
- os=
- obj=elf
+ os=elf
;;
or32-*)
- os=
- obj=coff
+ os=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=sysv3
@@ -1612,8 +1607,7 @@ case $cpu-$vendor in
os=sunos4.1.1
;;
pru-*)
- os=
- obj=elf
+ os=elf
;;
*-be)
os=beos
@@ -1694,12 +1688,10 @@ case $cpu-$vendor in
os=uxpv
;;
*-rom68k)
- os=
- obj=coff
+ os=coff
;;
*-*bug)
- os=
- obj=coff
+ os=coff
;;
*-apple)
os=macos
@@ -1717,8 +1709,7 @@ esac
fi
-# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
-
+# Now, validate our (potentially fixed-up) OS.
case $os in
# Sometimes we do "kernel-libc", so those need to count as OSes.
musl* | newlib* | relibc* | uclibc*)
@@ -1729,9 +1720,6 @@ case $os in
# VxWorks passes extra cpu info in the 4th filed.
simlinux | simwindows | spe)
;;
- # See `case $cpu-$os` validation below
- ghcjs)
- ;;
# Now accept the basic system types.
# The portable systems comes first.
# Each alternative MUST end in a * to match a version number.
@@ -1740,7 +1728,7 @@ case $os in
| hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
| sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
| hiux* | abug | nacl* | netware* | windows* \
- | os9* | macos* | osx* | ios* | tvos* | watchos* \
+ | os9* | macos* | osx* | ios* \
| mpw* | magic* | mmixware* | mon960* | lnews* \
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
| aos* | aros* | cloudabi* | sortix* | twizzler* \
@@ -1749,11 +1737,11 @@ case $os in
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
| bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
- | bosx* | nextstep* | cxux* | oabi* \
- | ptx* | ecoff* | winnt* | domain* | vsta* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
| udi* | lites* | ieee* | go32* | aux* | hcos* \
| chorusrdb* | cegcc* | glidix* | serenity* \
- | cygwin* | msys* | moss* | proelf* | rtems* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
| midipix* | mingw32* | mingw64* | mint* \
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
| interix* | uwin* | mks* | rhapsody* | darwin* \
@@ -1766,7 +1754,7 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* | cos* | mbr* )
+ | fiwix* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1774,99 +1762,41 @@ case $os in
;;
none)
;;
- kernel* | msvc* )
- # Restricted further below
- ;;
- '')
- if test x"$obj" = x
- then
- echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
- fi
- ;;
- *)
- echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
- exit 1
- ;;
-esac
-
-case $obj in
- aout* | coff* | elf* | pe*)
- ;;
- '')
- # empty is fine
- ;;
*)
- echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
- exit 1
- ;;
-esac
-
-# Here we handle the constraint that a (synthetic) cpu and os are
-# valid only in combination with each other and nowhere else.
-case $cpu-$os in
- # The "javascript-unknown-ghcjs" triple is used by GHC; we
- # accept it here in order to tolerate that, but reject any
- # variations.
- javascript-ghcjs)
- ;;
- javascript-* | *-ghcjs)
- echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
+ echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
exit 1
;;
esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
-case $kernel-$os-$obj in
- linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
- | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
- ;;
- uclinux-uclibc*- )
- ;;
- managarm-mlibc*- | managarm-kernel*- )
+case $kernel-$os in
+ linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+ | linux-musl* | linux-relibc* | linux-uclibc* )
;;
- windows*-msvc*-)
+ uclinux-uclibc* )
;;
- -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
+ -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
- echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
- exit 1
- ;;
- -kernel*- )
- echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
- exit 1
- ;;
- *-kernel*- )
- echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
+ echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
exit 1
;;
- *-msvc*- )
- echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
- exit 1
- ;;
- kfreebsd*-gnu*- | kopensolaris*-gnu*-)
+ kfreebsd*-gnu* | kopensolaris*-gnu*)
;;
- vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
+ vxworks-simlinux | vxworks-simwindows | vxworks-spe)
;;
- nto-qnx*-)
- ;;
- os2-emx-)
+ nto-qnx*)
;;
- *-eabi*- | *-gnueabi*-)
+ os2-emx)
;;
- none--*)
- # None (no kernel, i.e. freestanding / bare metal),
- # can be paired with an machine code file format
+ *-eabi* | *-gnueabi*)
;;
- -*-)
+ -*)
# Blank kernel with real OS is always fine.
;;
- --*)
- # Blank kernel and OS with real machine code file format is always fine.
- ;;
- *-*-*)
- echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
+ *-*)
+ echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
exit 1
;;
esac
@@ -1949,7 +1879,7 @@ case $vendor in
;;
esac
-echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
exit
# Local variables:
Index: configlexer.lex
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/configlexer.lex,v
diff -u -p -r1.27 configlexer.lex
--- configlexer.lex 6 Sep 2025 17:41:37 -0000 1.27
+++ configlexer.lex 18 Mar 2026 20:44:03 -0000
@@ -213,6 +213,7 @@ tcp-query-count{COLON} { LEXOUT(("v(%s)
tcp-timeout{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_TIMEOUT;}
tcp-mss{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_MSS;}
outgoing-tcp-mss{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_TCP_MSS;}
+tcp-listen-queue{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_LISTEN_QUEUE;}
ipv4-edns-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IPV4_EDNS_SIZE;}
ipv6-edns-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IPV6_EDNS_SIZE;}
pidfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PIDFILE;}
Index: configparser.y
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/configparser.y,v
diff -u -p -r1.41 configparser.y
--- configparser.y 6 Sep 2025 17:41:37 -0000 1.41
+++ configparser.y 18 Mar 2026 20:44:03 -0000
@@ -106,6 +106,7 @@ struct component {
%token VAR_TCP_TIMEOUT
%token VAR_TCP_MSS
%token VAR_OUTGOING_TCP_MSS
+%token VAR_TCP_LISTEN_QUEUE
%token VAR_IPV4_EDNS_SIZE
%token VAR_IPV6_EDNS_SIZE
%token VAR_STATISTICS
@@ -295,9 +296,25 @@ server_option:
| VAR_IP_FREEBIND boolean
{ cfg_parser->opt->ip_freebind = $2; }
| VAR_SEND_BUFFER_SIZE number
- { cfg_parser->opt->send_buffer_size = (int)$2; }
+ {
+ if ($2 > 0) {
+ cfg_parser->opt->send_buffer_size = (int)$2;
+ } else if ($2 == 0) {
+ /* do nothing and use the default value */
+ } else {
+ yyerror("expected a number equal to or greater than zero");
+ }
+ }
| VAR_RECEIVE_BUFFER_SIZE number
- { cfg_parser->opt->receive_buffer_size = (int)$2; }
+ {
+ if ($2 > 0) {
+ cfg_parser->opt->receive_buffer_size = (int)$2;
+ } else if ($2 == 0) {
+ /* do nothing and use the default value */
+ } else {
+ yyerror("expected a number equal to or greater than zero");
+ }
+ }
| VAR_DEBUG_MODE boolean
{ cfg_parser->opt->debug_mode = $2; }
| VAR_USE_SYSTEMD boolean
@@ -374,6 +391,9 @@ server_option:
{ cfg_parser->opt->tcp_mss = (int)$2; }
| VAR_OUTGOING_TCP_MSS number
{ cfg_parser->opt->outgoing_tcp_mss = (int)$2; }
+ | VAR_TCP_LISTEN_QUEUE STRING
+ { /* With atoi is it allowed to be negative, for system chosen result. */
+ cfg_parser->opt->tcp_listen_queue = atoi($2); }
| VAR_IPV4_EDNS_SIZE number
{ cfg_parser->opt->ipv4_edns_size = (size_t)$2; }
| VAR_IPV6_EDNS_SIZE number
Index: configure
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/configure,v
diff -u -p -r1.63 configure
--- configure 6 Sep 2025 17:41:37 -0000 1.63
+++ configure 18 Mar 2026 20:44:03 -0000
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for NSD 4.13.0.
+# Generated by GNU Autoconf 2.71 for NSD 4.14.1.
#
# Report bugs to <https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl>.
#
@@ -612,8 +612,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='NSD'
PACKAGE_TARNAME='nsd'
-PACKAGE_VERSION='4.13.0'
-PACKAGE_STRING='NSD 4.13.0'
+PACKAGE_VERSION='4.14.1'
+PACKAGE_STRING='NSD 4.14.1'
PACKAGE_BUGREPORT='https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl'
PACKAGE_URL=''
@@ -1381,7 +1381,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures NSD 4.13.0 to adapt to many kinds of systems.
+\`configure' configures NSD 4.14.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1447,7 +1447,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of NSD 4.13.0:";;
+ short | recursive ) echo "Configuration of NSD 4.14.1:";;
esac
cat <<\_ACEOF
@@ -1635,7 +1635,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-NSD configure 4.13.0
+NSD configure 4.14.1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2292,7 +2292,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by NSD $as_me 4.13.0, which was
+It was created by NSD $as_me 4.14.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -10441,8 +10441,19 @@ printf "%s\n" "#define IDENTITY \"uniden
printf "%s\n" "#define VERSION PACKAGE_STRING" >>confdefs.h
+case "$host" in
+ *bsd*|*BSD*|*linux*|*Linux*)
+
+printf "%s\n" "#define TCP_BACKLOG -1" >>confdefs.h
+
+ ;;
+ *)
+
printf "%s\n" "#define TCP_BACKLOG 256" >>confdefs.h
+ ;;
+esac
+
printf "%s\n" "#define TCP_PORT \"53\"" >>confdefs.h
@@ -12149,6 +12160,19 @@ else $as_nop
as_fn_error $? "The fstrm library was not found. It is needed for dnstap, use --disable-dnstap, or install fstrm-devel" "$LINENO" 5
fi
+
+ for ac_func in fstrm_tcp_writer_options_init
+do :
+ ac_fn_c_check_func "$LINENO" "fstrm_tcp_writer_options_init" "ac_cv_func_fstrm_tcp_writer_options_init"
+if test "x$ac_cv_func_fstrm_tcp_writer_options_init" = xyes
+then :
+ printf "%s\n" "#define HAVE_FSTRM_TCP_WRITER_OPTIONS_INIT 1" >>confdefs.h
+
+else $as_nop
+ as_fn_error $? "The fstrm library >= 0.4 was not found. It is needed for dnstap, use --disable-dnstap, or install fstrm-devel" "$LINENO" 5
+fi
+
+done
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5
printf %s "checking for library containing protobuf_c_message_pack... " >&6; }
if test ${ac_cv_search_protobuf_c_message_pack+y}
@@ -12384,9 +12408,6 @@ printf "%s\n" "no" >&6; }
PKG_CONFIG=""
fi
fi
-if test -z "$PKG_CONFIG"; then
- as_fn_error $? "pkg-config not found" "$LINENO" 5
-fi
if test "x$enable_systemd" != xno
then :
@@ -13144,7 +13165,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by NSD $as_me 4.13.0, which was
+This file was extended by NSD $as_me 4.14.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -13208,7 +13229,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-NSD config.status 4.13.0
+NSD config.status 4.14.1
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
Index: configure.ac
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/configure.ac,v
diff -u -p -r1.62 configure.ac
--- configure.ac 6 Sep 2025 17:41:37 -0000 1.62
+++ configure.ac 18 Mar 2026 20:44:03 -0000
@@ -7,7 +7,7 @@ sinclude(dnstap/dnstap.m4)
# autoconf-2.70 is needed for @runstatedir@
AC_PREREQ([2.70])
-AC_INIT([NSD],[4.13.0],[https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl])
+AC_INIT([NSD],[4.14.1],[https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl])
AC_CONFIG_HEADERS([config.h])
#
@@ -178,10 +178,7 @@ AC_ARG_WITH([user],
AC_SUBST(user)
AC_DEFINE_UNQUOTED(USER, ["$user"], [the user name to drop privileges to])
-m4_version_prereq([2.70], [AC_PROG_CC], [m4_warn([obsolete],
-[AC_PROG_CC_STDC is obsolete; use AC_PROG_CC
-])dnl
-AC_REQUIRE(AC_PROG_CC)])
+m4_version_prereq([2.70], [AC_PROG_CC], [AC_PROG_CC_STDC])
AC_PROG_SED
AC_PROG_AWK
AC_PROG_GREP
@@ -950,7 +947,16 @@ dnl Some random defines's
dnl
AC_DEFINE_UNQUOTED([IDENTITY], ["unidentified server"], [Define to the default nsd identity.])
AC_DEFINE_UNQUOTED([VERSION], [PACKAGE_STRING], [Define to the NSD version to answer version.server query.])
-AC_DEFINE_UNQUOTED([TCP_BACKLOG], [256], [Define to the backlog to be used with listen.])
+
+case "$host" in
+ *bsd*|*BSD*|*linux*|*Linux*)
+ AC_DEFINE_UNQUOTED([TCP_BACKLOG], [-1], [Define to the backlog to be used with listen.])
+ ;;
+ *)
+ AC_DEFINE_UNQUOTED([TCP_BACKLOG], [256], [Define to the backlog to be used with listen.])
+ ;;
+esac
+
AC_DEFINE_UNQUOTED([TCP_PORT], ["53"], [Define to the default tcp port.])
AC_DEFINE_UNQUOTED([TCP_MAX_MESSAGE_LEN], [65535], [Define to the default maximum message length.])
AC_DEFINE_UNQUOTED([UDP_PORT], ["53"], [Define to the default udp port.])
@@ -1505,4 +1511,4 @@ if test -n "$dnstap_config"; then
fi
fi
m4_unquote(
- _m4_defn([_m4_wrap_text])_m4_popdef([_m4_wrap_text]))
\ No newline at end of file
+ _m4_defn([_m4_wrap_text])_m4_popdef([_m4_wrap_text]))
Index: dbaccess.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dbaccess.c,v
diff -u -p -r1.13 dbaccess.c
--- dbaccess.c 3 Sep 2025 18:46:48 -0000 1.13
+++ dbaccess.c 18 Mar 2026 20:44:03 -0000
@@ -135,12 +135,22 @@ namedb_zone_delete(namedb_type* db, zone
}
}
- /* soa_rrset is freed when the SOA was deleted */
+ /* soa_nx_rrset is kept around, between zone delete and new zone
+ * contents. When the SOA was deleted, the usage for domain references
+ * was lowered. */
if(zone->soa_nx_rrset) {
+ region_recycle(db->region, zone->soa_nx_rrset->rrs[0],
+ sizeof(rr_type)+zone->soa_nx_rrset->rrs[0]->rdlength);
+#ifndef PACKED_STRUCTS
region_recycle(db->region, zone->soa_nx_rrset->rrs,
- sizeof(rr_type));
+ sizeof(rr_type*));
+#endif
region_recycle(db->region, zone->soa_nx_rrset,
- sizeof(rrset_type));
+ sizeof(rrset_type)
+#ifdef PACKED_STRUCTS
+ + sizeof(rr_type*)
+#endif
+ );
}
#ifdef NSEC3
hash_tree_delete(db->region, zone->nsec3tree);
Index: dbcreate.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dbcreate.c,v
diff -u -p -r1.9 dbcreate.c
--- dbcreate.c 3 Sep 2025 18:46:48 -0000 1.9
+++ dbcreate.c 18 Mar 2026 20:44:03 -0000
@@ -26,44 +26,6 @@
/* pathname directory separator character */
#define PATHSEP '/'
-/** add an rdata (uncompressed) to the destination */
-static size_t
-add_rdata(rr_type* rr, unsigned i, uint8_t* buf, size_t buflen)
-{
- switch(rdata_atom_wireformat_type(rr->type, i)) {
- case RDATA_WF_COMPRESSED_DNAME:
- case RDATA_WF_UNCOMPRESSED_DNAME:
- {
- const dname_type* dname = domain_dname(
- rdata_atom_domain(rr->rdatas[i]));
- if(dname->name_size > buflen)
- return 0;
- memmove(buf, dname_name(dname), dname->name_size);
- return dname->name_size;
- }
- default:
- break;
- }
- if(rdata_atom_size(rr->rdatas[i]) > buflen)
- return 0;
- memmove(buf, rdata_atom_data(rr->rdatas[i]),
- rdata_atom_size(rr->rdatas[i]));
- return rdata_atom_size(rr->rdatas[i]);
-}
-
-/* marshal rdata into buffer, must be MAX_RDLENGTH in size */
-size_t
-rr_marshal_rdata(rr_type* rr, uint8_t* rdata, size_t sz)
-{
- size_t len = 0;
- unsigned i;
- assert(rr);
- for(i=0; i<rr->rdata_count; i++) {
- len += add_rdata(rr, i, rdata+len, sz-len);
- }
- return len;
-}
-
int
print_rrs(FILE* out, struct zone* zone)
{
@@ -77,7 +39,7 @@ print_rrs(FILE* out, struct zone* zone)
if(zone->soa_rrset) {
size_t i;
for(i=0; i < zone->soa_rrset->rr_count; i++) {
- if(!print_rr(out, state, &zone->soa_rrset->rrs[i],
+ if(!print_rr(out, state, zone->soa_rrset->rrs[i],
rr_region, rr_buffer)){
log_msg(LOG_ERR, "There was an error "
"printing SOARR to zone %s",
@@ -97,7 +59,7 @@ print_rrs(FILE* out, struct zone* zone)
if(rrset->zone != zone || rrset == zone->soa_rrset)
continue;
for(i=0; i < rrset->rr_count; i++) {
- if(!print_rr(out, state, &rrset->rrs[i],
+ if(!print_rr(out, state, rrset->rrs[i],
rr_region, rr_buffer)){
log_msg(LOG_ERR, "There was an error "
"printing RR to zone %s",
Index: difffile.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/difffile.c,v
diff -u -p -r1.24 difffile.c
--- difffile.c 6 Sep 2025 17:41:37 -0000 1.24
+++ difffile.c 18 Mar 2026 20:44:03 -0000
@@ -235,19 +235,10 @@ diff_read_str(FILE* in, char* buf, size_
}
static void
-add_rdata_to_recyclebin(namedb_type* db, rr_type* rr)
+add_rr_to_recyclebin(namedb_type* db, rr_type* rr)
{
- /* add rdatas to recycle bin. */
- size_t i;
- for(i=0; i<rr->rdata_count; i++)
- {
- if(!rdata_atom_is_domain(rr->type, i))
- region_recycle(db->region, rr->rdatas[i].data,
- rdata_atom_size(rr->rdatas[i])
- + sizeof(uint16_t));
- }
- region_recycle(db->region, rr->rdatas,
- sizeof(rdata_atom_type)*rr->rdata_count);
+ /* add rr and rdata to recycle bin. */
+ region_recycle(db->region, rr, sizeof(rr_type) + rr->rdlength);
}
/* this routine determines if below a domain there exist names with
@@ -324,7 +315,7 @@ rrset_delete(namedb_type* db, domain_typ
}
if(domain == rrset->zone->apex && rrset_rrtype(rrset) == TYPE_RRSIG) {
for (i = 0; i < rrset->rr_count; ++i) {
- if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY) {
+ if(rr_rrsig_type_covered(rrset->rrs[i])==TYPE_DNSKEY) {
rrset->zone->is_secure = 0;
break;
}
@@ -332,104 +323,164 @@ rrset_delete(namedb_type* db, domain_typ
}
/* recycle the memory space of the rrset */
for (i = 0; i < rrset->rr_count; ++i)
- add_rdata_to_recyclebin(db, &rrset->rrs[i]);
- region_recycle(db->region, rrset->rrs,
- sizeof(rr_type) * rrset->rr_count);
+ add_rr_to_recyclebin(db, rrset->rrs[i]);
+#ifndef PACKED_STRUCTS
+ region_recycle(db->region, rrset->rrs, sizeof(rr_type*) * rrset->rr_count);
rrset->rr_count = 0;
- region_recycle(db->region, rrset, sizeof(rrset_type));
+#endif
+ region_recycle(db->region, rrset, sizeof(rrset_type)
+#ifdef PACKED_STRUCTS
+ + rrset->rr_count*sizeof(rr_type*)
+#endif
+ );
}
static int
-rdatas_equal(rdata_atom_type *a, rdata_atom_type *b, int num, uint16_t type,
+rdatas_equal(const rr_type *rr1, const rr_type *rr2, uint16_t type,
int* rdnum, char** reason)
{
- int k, start, end;
- start = 0;
- end = num;
+ size_t offset = 0;
+ const nsd_type_descriptor_type *descriptor;
+
+ if(rr1->rdlength != rr2->rdlength) {
+ *rdnum = 0;
+ *reason = "rr length different";
+ return 0;
+ }
+ assert(rr1->rdlength == rr2->rdlength);
+
/**
* SOA RDATA comparisons in XFR are more lenient,
* only serial rdata is checked.
**/
if (type == TYPE_SOA) {
- start = 2;
- end = 3;
+ offset = 2 * sizeof(void*);
+ if(rr1->rdlength != offset + 20) {
+ *rdnum = 0;
+ *reason = "invalid SOA length";
+ return 0;
+ }
+ assert(rr1->rdlength == offset + 20);
+ if (memcmp(rr1->rdata + offset, rr2->rdata + offset, 4) == 0)
+ return 1;
+ *rdnum = 2;
+ *reason = "rdata data";
+ return 0;
}
- for(k = start; k < end; k++)
- {
- if(rdata_atom_is_domain(type, k)) {
- if(dname_compare(domain_dname(a[k].domain),
- domain_dname(b[k].domain))!=0) {
- *rdnum = k;
+
+ if (memcmp(rr1->rdata, rr2->rdata, rr1->rdlength) == 0)
+ return 1;
+
+ descriptor = nsd_type_descriptor(type);
+ for (size_t i=0; i < descriptor->rdata.length && offset < rr1->rdlength; i++) {
+ uint16_t field_len1, field_len2;
+ struct domain *domain1, *domain2;
+ if(offset == rr1->rdlength &&
+ descriptor->rdata.fields[i].is_optional)
+ break;
+ if(!lookup_rdata_field_entry(descriptor, i, rr1, offset,
+ &field_len1, &domain1)) {
+ *rdnum = i;
+ *reason = "malformed field rr1";
+ return 0;
+ }
+ if(!lookup_rdata_field_entry(descriptor, i, rr2, offset,
+ &field_len2, &domain2)) {
+ *rdnum = i;
+ *reason = "malformed field rr2";
+ return 0;
+ }
+ if(domain1 && domain2) {
+ const struct dname *dname1, *dname2;
+ dname1 = domain_dname(domain1);
+ dname2 = domain_dname(domain2);
+ if (dname_compare(dname1, dname2) != 0) {
+ *rdnum = i;
*reason = "dname data";
return 0;
}
- } else if(rdata_atom_is_literal_domain(type, k)) {
- /* literal dname, but compare case insensitive */
- if(a[k].data[0] != b[k].data[0]) {
- *rdnum = k;
- *reason = "literal dname len";
- return 0; /* uncompressed len must be equal*/
- }
- if(!dname_equal_nocase((uint8_t*)(a[k].data+1),
- (uint8_t*)(b[k].data+1), a[k].data[0])) {
- *rdnum = k;
- *reason = "literal dname data";
+ offset += field_len1;
+ continue;
+ } else if(descriptor->rdata.fields[i].length ==
+ RDATA_LITERAL_DNAME) {
+ uint8_t length1, length2;
+ const uint8_t *name1 = rr1->rdata + offset;
+ const uint8_t *name2 = rr2->rdata + offset;
+ if(field_len1 != field_len2) {
+ *rdnum = i;
+ *reason = "literal dname field len";
return 0;
}
- } else {
- /* check length */
- if(a[k].data[0] != b[k].data[0]) {
- *rdnum = k;
- *reason = "rdata len";
+ length1 = buf_dname_length(name1, rr1->rdlength - offset);
+ length2 = buf_dname_length(name2, rr2->rdlength - offset);
+
+ if (!length1 || !length2 || length1 != length2) {
+ *rdnum = i;
+ *reason = "literal dname len";
return 0;
}
- /* check data */
- if(memcmp(a[k].data+1, b[k].data+1, a[k].data[0])!=0) {
- *rdnum = k;
- *reason = "rdata data";
+ if (!dname_equal_nocase((uint8_t*)name1, (uint8_t*)name2, length1)) {
+ *rdnum = i;
+ *reason = "literal dname data";
return 0;
}
+ offset += field_len1;
+ continue;
+ }
+ if(field_len1 != field_len2) {
+ *rdnum = i;
+ *reason = "rdata len";
+ return 0;
+ }
+ if(memcmp(rr1->rdata+offset, rr2->rdata+offset, field_len1) != 0) {
+ *rdnum = i;
+ *reason = "rdata data";
+ return 0;
}
+ offset += field_len1;
}
+
return 1;
}
static void
debug_find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass,
- rdata_atom_type *rdatas, ssize_t rdata_num)
+ rr_type *rr)
{
int i, rd;
char* reason = "";
for(i=0; i < rrset->rr_count; ++i) {
- if (rrset->rrs[i].type != type) {
+ if (rrset->rrs[i]->type != type) {
log_msg(LOG_WARNING, "diff: RR <%s, %s> does not match "
"RR num %d type %s",
- dname_to_string(domain_dname(rrset->rrs[i].owner),0),
+ dname_to_string(domain_dname(rrset->rrs[i]->owner),0),
rrtype_to_string(type), i,
- rrtype_to_string(rrset->rrs[i].type));
+ rrtype_to_string(rrset->rrs[i]->type));
+ continue; /* rdata equality needs same type. */
}
- if (rrset->rrs[i].klass != klass) {
+ if (rrset->rrs[i]->klass != klass) {
log_msg(LOG_WARNING, "diff: RR <%s, %s> class %d "
"does not match RR num %d class %d",
- dname_to_string(domain_dname(rrset->rrs[i].owner),0),
+ dname_to_string(domain_dname(rrset->rrs[i]->owner),0),
rrtype_to_string(type),
klass, i,
- rrset->rrs[i].klass);
+ rrset->rrs[i]->klass);
+ continue;
}
- if (rrset->rrs[i].rdata_count != rdata_num) {
+ if (rrset->rrs[i]->rdlength != rr->rdlength) {
log_msg(LOG_WARNING, "diff: RR <%s, %s> rdlen %u "
"does not match RR num %d rdlen %d",
- dname_to_string(domain_dname(rrset->rrs[i].owner),0),
+ dname_to_string(domain_dname(rrset->rrs[i]->owner),0),
rrtype_to_string(type),
- (unsigned) rdata_num, i,
- (unsigned) rrset->rrs[i].rdata_count);
+ (unsigned) rr->rdlength, i,
+ (unsigned) rrset->rrs[i]->rdlength);
}
- if (!rdatas_equal(rdatas, rrset->rrs[i].rdatas, rdata_num, type,
+ if (!rdatas_equal(rr, rrset->rrs[i], type,
&rd, &reason)) {
log_msg(LOG_WARNING, "diff: RR <%s, %s> rdata element "
"%d differs from RR num %d rdata (%s)",
- dname_to_string(domain_dname(rrset->rrs[i].owner),0),
+ dname_to_string(domain_dname(rrset->rrs[i]->owner),0),
rrtype_to_string(type),
rd, i, reason);
}
@@ -438,16 +489,16 @@ debug_find_rr_num(rrset_type* rrset, uin
static int
find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass,
- rdata_atom_type *rdatas, ssize_t rdata_num, int add)
+ rr_type *rr, int add)
{
int i, rd;
char* reason;
for(i=0; i < rrset->rr_count; ++i) {
- if(rrset->rrs[i].type == type &&
- rrset->rrs[i].klass == klass &&
- rrset->rrs[i].rdata_count == rdata_num &&
- rdatas_equal(rdatas, rrset->rrs[i].rdatas, rdata_num, type,
+ if(rrset->rrs[i]->type == type &&
+ rrset->rrs[i]->klass == klass &&
+ rrset->rrs[i]->rdlength == rr->rdlength &&
+ rdatas_equal(rrset->rrs[i], rr, type,
&rd, &reason))
{
return i;
@@ -455,7 +506,7 @@ find_rr_num(rrset_type* rrset, uint16_t
}
/* this is odd. Log why rr cannot be found. */
if (!add) {
- debug_find_rr_num(rrset, type, klass, rdatas, rdata_num);
+ debug_find_rr_num(rrset, type, klass, rr);
}
return -1;
}
@@ -640,38 +691,26 @@ nsec3_add_rrset_trigger(namedb_type* db,
}
#endif /* NSEC3 */
-/* fixup usage lower for domain names in the rdata */
-static void
-rr_lower_usage(namedb_type* db, rr_type* rr)
-{
- unsigned i;
- for(i=0; i<rr->rdata_count; i++) {
- if(rdata_atom_is_domain(rr->type, i)) {
- assert(rdata_atom_domain(rr->rdatas[i])->usage > 0);
- rdata_atom_domain(rr->rdatas[i])->usage --;
- if(rdata_atom_domain(rr->rdatas[i])->usage == 0)
- domain_table_deldomain(db,
- rdata_atom_domain(rr->rdatas[i]));
- }
- }
-}
-
static void
rrset_lower_usage(namedb_type* db, rrset_type* rrset)
{
unsigned i;
for(i=0; i<rrset->rr_count; i++)
- rr_lower_usage(db, &rrset->rrs[i]);
+ rr_lower_usage(db, rrset->rrs[i]);
}
int
delete_RR(namedb_type* db, const dname_type* dname,
- uint16_t type, uint16_t klass,
+ uint16_t type, uint16_t klass, uint32_t ttl,
buffer_type* packet, size_t rdatalen, zone_type *zone,
- region_type* temp_region, int* softfail)
+ region_type* temp_region, int* softfail, struct ixfr_store* ixfr_store)
{
domain_type *domain;
rrset_type *rrset;
+#ifdef PACKED_STRUCTS
+ rrset_type* rrset_prev;
+#endif
+ const nsd_type_descriptor_type *descriptor = nsd_type_descriptor(type);
domain = domain_table_find(db->domains, dname);
if(!domain) {
log_msg(LOG_WARNING, "diff: domain %s does not exist",
@@ -680,7 +719,11 @@ delete_RR(namedb_type* db, const dname_t
*softfail = 1;
return 1; /* not fatal error */
}
+#ifndef PACKED_STRUCTS
rrset = domain_find_rrset(domain, zone, type);
+#else
+ rrset = domain_find_rrset_and_prev(domain, zone, type, &rrset_prev);
+#endif
if(!rrset) {
log_msg(LOG_WARNING, "diff: rrset %s does not exist",
dname_to_string(dname,0));
@@ -690,21 +733,33 @@ delete_RR(namedb_type* db, const dname_t
} else {
/* find the RR in the rrset */
domain_table_type *temptable;
- rdata_atom_type *rdatas;
- ssize_t rdata_num;
- int rrnum;
+ int32_t rrnum, code;
+ struct rr *rr;
temptable = domain_table_create(temp_region);
/* This will ensure that the dnames in rdata are
* normalized, conform RFC 4035, section 6.2
*/
- rdata_num = rdata_wireformat_to_rdata_atoms(
- temp_region, temptable, type, rdatalen, packet, &rdatas);
- if(rdata_num == -1) {
- log_msg(LOG_ERR, "diff: bad rdata for %s",
- dname_to_string(dname,0));
- return 0;
+ code = descriptor->read_rdata(temptable, rdatalen, packet, &rr);
+ if(code < 0) {
+ log_msg(LOG_ERR, "diff: could not read rdata for "
+ "%s %s %s", dname_to_string(dname,0),
+ rrtype_to_string(type),
+ read_rdata_fail_str(code));
}
- rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num, 0);
+ rr->owner = domain;
+ rr->type = type;
+ rr->klass = klass;
+ rr->ttl = ttl;
+
+ /* Now that the RR has been read with its RRtype specific read
+ * routine, store the read data and rdata, for an ixfr store.
+ * Store the delete RR information, for the softfail cases, the
+ * IXFR is stopped and an AXFR is attempted, so it would not
+ * need to be stored as the transfer is rejected. */
+ if(ixfr_store)
+ ixfr_store_delrr(ixfr_store, rr);
+
+ rrnum = find_rr_num(rrset, type, klass, rr, 0);
if(rrnum == -1 && type == TYPE_SOA && domain == zone->apex
&& rrset->rr_count != 0)
rrnum = 0; /* replace existing SOA if no match */
@@ -716,11 +771,11 @@ delete_RR(namedb_type* db, const dname_t
}
#ifdef NSEC3
/* process triggers for RR deletions */
- nsec3_delete_rr_trigger(db, &rrset->rrs[rrnum], zone);
+ nsec3_delete_rr_trigger(db, rrset->rrs[rrnum], zone);
#endif
/* lower usage (possibly deleting other domains, and thus
* invalidating the current RR's domain pointers) */
- rr_lower_usage(db, &rrset->rrs[rrnum]);
+ rr_lower_usage(db, rrset->rrs[rrnum]);
if(rrset->rr_count == 1) {
/* delete entire rrset */
rrset_delete(db, domain, rrset);
@@ -734,37 +789,49 @@ delete_RR(namedb_type* db, const dname_t
domain_table_deldomain(db, domain);
} else {
/* swap out the bad RR and decrease the count */
- rr_type* rrs_orig = rrset->rrs;
- add_rdata_to_recyclebin(db, &rrset->rrs[rrnum]);
+#ifndef PACKED_STRUCTS
+ rr_type** rrs_orig = rrset->rrs;
+#else
+ rrset_type* rrset_orig = rrset;
+#endif
+ add_rr_to_recyclebin(db, rrset->rrs[rrnum]);
if(rrnum < rrset->rr_count-1)
rrset->rrs[rrnum] = rrset->rrs[rrset->rr_count-1];
- memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
+ rrset->rrs[rrset->rr_count-1] = NULL;
/* realloc the rrs array one smaller */
+#ifndef PACKED_STRUCTS
rrset->rrs = region_alloc_array_init(db->region, rrs_orig,
- (rrset->rr_count-1), sizeof(rr_type));
+ (rrset->rr_count-1), sizeof(rr_type*));
if(!rrset->rrs) {
log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
exit(1);
}
region_recycle(db->region, rrs_orig,
- sizeof(rr_type) * rrset->rr_count);
-#ifdef NSEC3
- if(type == TYPE_NSEC3PARAM && zone->nsec3_param) {
- /* fixup nsec3_param pointer to same RR */
- assert(zone->nsec3_param >= rrs_orig &&
- zone->nsec3_param <=
- rrs_orig+rrset->rr_count);
- /* last moved to rrnum, others at same index*/
- if(zone->nsec3_param == &rrs_orig[
- rrset->rr_count-1])
- zone->nsec3_param = &rrset->rrs[rrnum];
- else
- zone->nsec3_param = (void*)
- ((char*)zone->nsec3_param
- -(char*)rrs_orig +
- (char*)rrset->rrs);
+ sizeof(rr_type*) * rrset->rr_count);
+#else
+ rrset = region_alloc_init(db->region, rrset_orig,
+ sizeof(rrset_type) +
+ (rrset_orig->rr_count-1)*sizeof(rr_type*));
+ if(!rrset) {
+ log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
+ exit(1);
}
-#endif /* NSEC3 */
+ if(rrset_prev)
+ rrset_prev->next = rrset;
+ else domain->rrsets = rrset;
+ region_recycle(db->region, rrset_orig,
+ sizeof(rrset_type) +
+ rrset_orig->rr_count*sizeof(rr_type*));
+ if(domain == zone->apex) {
+ /* Because the rrset struct is reallocated,
+ * a pointer to it may need to be set again. */
+ if(type == TYPE_SOA) {
+ zone->soa_rrset = rrset;
+ } else if(type == TYPE_NS) {
+ zone->ns_rrset = rrset;
+ }
+ }
+#endif /* PACKED_STRUCTS */
rrset->rr_count --;
#ifdef NSEC3
/* for type nsec3, the domain may have become a
@@ -778,116 +845,214 @@ delete_RR(namedb_type* db, const dname_t
return 1;
}
-int
-add_RR(namedb_type* db, const dname_type* dname,
- uint16_t type, uint16_t klass, uint32_t ttl,
- buffer_type* packet, size_t rdatalen, zone_type *zone,
- int* softfail)
+static void
+commit_RRset(namedb_type* db, zone_type* zone, struct collect_rrs* collect_rrs)
{
- domain_type* domain;
- rrset_type* rrset;
- rdata_atom_type *rdatas;
- rr_type *rrs_old;
- ssize_t rdata_num;
- int rrnum;
+ struct rrset *rrset;
+
+ if(!collect_rrs->domain || collect_rrs->rr_count == 0)
+ return;
+ if (!collect_rrs->rrset) {
#ifdef NSEC3
- int rrset_added = 0;
+ domain_type* p;
#endif
- domain = domain_table_find(db->domains, dname);
- if(!domain) {
- /* create the domain */
- domain = domain_table_insert(db->domains, dname);
- }
- rrset = domain_find_rrset(domain, zone, type);
- if(!rrset) {
- /* create the rrset */
- rrset = region_alloc(db->region, sizeof(rrset_type));
+ rrset = region_alloc(db->region, sizeof(*rrset)
+#ifdef PACKED_STRUCTS
+ + sizeof(rr_type*) * collect_rrs->rr_count /* Add space for RRs. */
+#endif
+ );
if(!rrset) {
log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
exit(1);
}
rrset->zone = zone;
- rrset->rrs = 0;
- rrset->rr_count = 0;
- domain_add_rrset(domain, rrset);
+ rrset->rr_count = collect_rrs->rr_count;
+#ifndef PACKED_STRUCTS
+ rrset->rrs = region_alloc(db->region,
+ sizeof(rr_type*) * collect_rrs->rr_count);
+#endif
+ memcpy(rrset->rrs, collect_rrs->rrs, collect_rrs->rr_count * sizeof(rr_type*));
+ /* Add it */
+ domain_add_rrset(collect_rrs->domain, rrset);
+#ifdef NSEC3
+ p = collect_rrs->domain->parent;
+ nsec3_add_rrset_trigger(db, collect_rrs->domain, zone, collect_rrs->type);
+ /* go up and process (possibly created) empty nonterminals,
+ * until we hit the apex or root */
+ while(p && p->rrsets == NULL && !p->is_apex) {
+ nsec3_rrsets_changed_add_prehash(db, p, zone);
+ p = p->parent;
+ }
+#endif
+ } else {
+#ifndef PACKED_STRUCTS
+ struct rr **rrs;
+#else
+ struct rrset *rrset_orig;
+#endif
+ /* Add it... */
+ rrset = collect_rrs->rrset;
+#ifndef PACKED_STRUCTS
+ rrs = rrset->rrs;
+ rrset->rrs = region_alloc_array(
+ db->region, rrset->rr_count + collect_rrs->rr_count, sizeof(*rrs));
+ if(!rrset->rrs) {
+ log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
+ exit(1);
+ }
+ if(rrs)
+ memcpy(rrset->rrs, rrs, rrset->rr_count * sizeof(*rrs));
+ region_recycle(db->region, rrs, rrset->rr_count * sizeof(*rrs));
+#else
+ rrset_orig = rrset;
+ rrset = region_alloc(db->region,
+ sizeof(rrset_type) +
+ (rrset_orig->rr_count+collect_rrs->rr_count)*sizeof(rr_type*));
+ if(!rrset) {
+ log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
+ exit(1);
+ }
+ memcpy(rrset, rrset_orig,
+ sizeof(rrset_type) +
+ rrset_orig->rr_count*sizeof(rr_type*));
+ if(collect_rrs->rrset_prev)
+ collect_rrs->rrset_prev->next = rrset;
+ else collect_rrs->domain->rrsets = rrset;
+ region_recycle(db->region, rrset_orig,
+ sizeof(rrset_type) +
+ rrset_orig->rr_count*sizeof(rr_type*));
+#endif /* PACKED_STRUCTS */
+ memcpy(rrset->rrs + rrset->rr_count, collect_rrs->rrs, collect_rrs->rr_count * sizeof(rr_type*));
+ rrset->rr_count += collect_rrs->rr_count;
+ }
+ /* Check we have SOA */
+ if (collect_rrs->domain == zone->apex)
+ apex_rrset_checks(db, rrset, collect_rrs->domain);
+
+ collect_rrs->domain = NULL;
+ collect_rrs->type = -1;
+ collect_rrs->rrset = NULL;
+#ifdef PACKED_STRUCTS
+ collect_rrs->rrset_prev = NULL;
+#endif
#ifdef NSEC3
- rrset_added = 1;
+ for (int i = 0; i < collect_rrs->rr_count; i++) {
+ nsec3_add_rr_trigger(db, collect_rrs->rrs[i], zone);
+ }
+#endif /* NSEC3 */
+ collect_rrs->rr_count = 0;
+}
+
+
+int
+add_RR(namedb_type* db, const dname_type* dname,
+ uint16_t type, uint16_t klass, uint32_t ttl,
+ buffer_type* packet, size_t rdatalen, zone_type *zone,
+ int* softfail, struct ixfr_store* ixfr_store,
+ struct collect_rrs* collect_rrs)
+{
+ domain_type* domain;
+ rr_type *rr;
+ int32_t code;
+ const nsd_type_descriptor_type *descriptor;
+
+ if (collect_rrs == NULL) {
+ struct collect_rrs collect_rrs2;
+
+ collect_rrs2.domain = NULL;
+ collect_rrs2.type = -1;
+ collect_rrs2.rrset = NULL;
+#ifdef PACKED_STRUCTS
+ collect_rrs2.rrset_prev = NULL;
+#endif
+ collect_rrs2.rr_count = 0;
+ if (!add_RR(db, dname, type, klass, ttl, packet, rdatalen,
+ zone, softfail, ixfr_store, &collect_rrs2)) {
+ return 0;
+ }
+ commit_RRset(db, zone, &collect_rrs2);
+ return 1;
+ }
+ domain = domain_table_insert(db->domains, dname);
+ assert(domain);
+ if (domain != collect_rrs->domain || type != collect_rrs->type
+ || collect_rrs->rr_count >= (int)(sizeof(collect_rrs->rrs) / sizeof(*collect_rrs->rrs))){
+ commit_RRset(db, zone, collect_rrs);
+ collect_rrs->domain = domain;
+ collect_rrs->type = type;
+ collect_rrs->rrset = NULL;
+#ifdef PACKED_STRUCTS
+ collect_rrs->rrset_prev = NULL;
#endif
}
/* dnames in rdata are normalized, conform RFC 4035,
* Section 6.2
*/
- rdata_num = rdata_wireformat_to_rdata_atoms(
- db->region, db->domains, type, rdatalen, packet, &rdatas);
- if(rdata_num == -1) {
- log_msg(LOG_ERR, "diff: bad rdata for %s",
- dname_to_string(dname,0));
+ descriptor = nsd_type_descriptor(type);
+ code = descriptor->read_rdata(db->domains, rdatalen, packet, &rr);
+ if(code < 0) {
+ log_msg(LOG_ERR, "diff: could not read rdata for %s %s %s",
+ dname_to_string(dname,0), rrtype_to_string(type),
+ read_rdata_fail_str(code));
return 0;
}
- rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num, 1);
- if(rrnum != -1) {
+ rr->owner = domain;
+ rr->type = type;
+ rr->klass = klass;
+ rr->ttl = ttl;
+
+ /* Now that the RR has been read with its RRtype specific read
+ * routine, store the read data and rdata, for an ixfr store. */
+ if (ixfr_store) {
+ ixfr_store_addrr(ixfr_store, rr);
+ }
+ /* With the first RR for a RRset in this position in the zone transfer,
+ * find the RRset */
+ if (collect_rrs->rr_count == 0) {
+#ifndef PACKED_STRUCTS
+ collect_rrs->rrset = domain_find_rrset(collect_rrs->domain, zone, collect_rrs->type);
+#else
+ collect_rrs->rrset = domain_find_rrset_and_prev(collect_rrs->domain, zone, collect_rrs->type, &collect_rrs->rrset_prev);
+#endif
+ }
+ if (collect_rrs->rrset) {
+ /* Search for possible duplicates in existing RRset */
+ for (int i = 0; i < collect_rrs->rrset->rr_count; i++) {
+ if (!equal_rr_rdata(descriptor, rr, collect_rrs->rrset->rrs[i]))
+ continue;
+ /* Discard the duplicates... */
+ /* Lower the usage counter for domains in the rdata. */
+ rr_lower_usage(db, rr);
+ region_recycle(db->region, rr, sizeof(*rr) + rr->rdlength);
+ DEBUG(DEBUG_XFRD, 2, (LOG_ERR, "diff: RR <%s, %s> already exists",
+ dname_to_string(dname,0), rrtype_to_string(type)));
+ /* ignore already existing RR: lenient accepting of messages */
+ *softfail = 1;
+ return 1;
+ }
+ }
+ /* Search for possible duplicates in already batched RRs */
+ for (int i = 0; i < collect_rrs->rr_count; i++) {
+ if (!equal_rr_rdata(descriptor, rr, collect_rrs->rrs[i]))
+ continue;
+ /* Discard the duplicates... */
+ /* Lower the usage counter for domains in the rdata. */
+ rr_lower_usage(db, rr);
+ region_recycle(db->region, rr, sizeof(*rr) + rr->rdlength);
DEBUG(DEBUG_XFRD, 2, (LOG_ERR, "diff: RR <%s, %s> already exists",
dname_to_string(dname,0), rrtype_to_string(type)));
/* ignore already existing RR: lenient accepting of messages */
*softfail = 1;
return 1;
}
- if(rrset->rr_count == 65535) {
+ if(collect_rrs->rr_count + ( collect_rrs->rrset
+ ? collect_rrs->rrset->rr_count : 0) >= 65535) {
log_msg(LOG_ERR, "diff: too many RRs at %s",
dname_to_string(dname,0));
return 0;
}
-
- /* re-alloc the rrs and add the new */
- rrs_old = rrset->rrs;
- rrset->rrs = region_alloc_array(db->region,
- (rrset->rr_count+1), sizeof(rr_type));
- if(!rrset->rrs) {
- log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
- exit(1);
- }
- if(rrs_old)
- memcpy(rrset->rrs, rrs_old, rrset->rr_count * sizeof(rr_type));
- region_recycle(db->region, rrs_old, sizeof(rr_type) * rrset->rr_count);
- rrset->rr_count ++;
-
- rrset->rrs[rrset->rr_count - 1].owner = domain;
- rrset->rrs[rrset->rr_count - 1].rdatas = rdatas;
- rrset->rrs[rrset->rr_count - 1].ttl = ttl;
- rrset->rrs[rrset->rr_count - 1].type = type;
- rrset->rrs[rrset->rr_count - 1].klass = klass;
- rrset->rrs[rrset->rr_count - 1].rdata_count = rdata_num;
-
- /* see if it is a SOA */
- if(domain == zone->apex) {
- apex_rrset_checks(db, rrset, domain);
-#ifdef NSEC3
- if(type == TYPE_NSEC3PARAM && zone->nsec3_param) {
- /* the pointer just changed, fix it up to point
- * to the same record */
- assert(zone->nsec3_param >= rrs_old &&
- zone->nsec3_param < rrs_old+rrset->rr_count);
- /* in this order to make sure no overflow/underflow*/
- zone->nsec3_param = (void*)((char*)zone->nsec3_param -
- (char*)rrs_old + (char*)rrset->rrs);
- }
-#endif /* NSEC3 */
- }
-
-#ifdef NSEC3
- if(rrset_added) {
- domain_type* p = domain->parent;
- nsec3_add_rrset_trigger(db, domain, zone, type);
- /* go up and process (possibly created) empty nonterminals,
- * until we hit the apex or root */
- while(p && p->rrsets == NULL && !p->is_apex) {
- nsec3_rrsets_changed_add_prehash(db, p, zone);
- p = p->parent;
- }
- }
- nsec3_add_rr_trigger(db, &rrset->rrs[rrset->rr_count - 1], zone);
-#endif /* NSEC3 */
+ collect_rrs->rrs[collect_rrs->rr_count++] = rr;
return 1;
}
@@ -1002,6 +1167,7 @@ apply_ixfr(nsd_type* nsd, FILE *in, uint
int qcount, ancount;
buffer_type* packet;
region_type* region;
+ struct collect_rrs collect_rrs;
/* note that errors could not really happen due to format of the
* packet since xfrd has checked all dnames and RRs before commit,
@@ -1072,8 +1238,16 @@ apply_ixfr(nsd_type* nsd, FILE *in, uint
}
}
- DEBUG(DEBUG_XFRD, 2, (LOG_INFO, "diff: started packet for zone %s",
- domain_to_string(zone->apex)));
+ collect_rrs.domain = NULL;
+ collect_rrs.type = -1;
+ collect_rrs.rrset = NULL;
+#ifdef PACKED_STRUCTS
+ collect_rrs.rrset_prev = NULL;
+#endif
+ collect_rrs.rr_count = 0;
+
+ DEBUG(DEBUG_XFRD, 2, (LOG_INFO, "diff: started packet %d/%d for zone %s",
+ (int)seq_nr, (int)seq_total, domain_to_string(zone->apex)));
for(int i=0; i < ancount; ++i, ++(*rr_count)) {
const dname_type *owner;
@@ -1226,26 +1400,38 @@ axfr:
if(*delete_mode) {
assert(!*is_axfr);
/* delete this rr */
- if(ixfr_store)
- ixfr_store_delrr(ixfr_store, owner, type,
- klass, ttl, packet, rrlen, region);
- if(!delete_RR(nsd->db, owner, type, klass, packet,
- rrlen, zone, region, softfail)) {
+ if(!delete_RR(nsd->db, owner, type, klass, ttl, packet,
+ rrlen, zone, region, softfail, ixfr_store)) {
region_destroy(region);
return 0;
}
} else {
/* add this rr */
- if(ixfr_store)
- ixfr_store_addrr(ixfr_store, owner, type,
- klass, ttl, packet, rrlen, region);
- if(!add_RR(nsd->db, owner, type, klass, ttl, packet,
- rrlen, zone, softfail)) {
+ if(!(add_RR(nsd->db, owner, type, klass, ttl, packet,
+ rrlen, zone, softfail, ixfr_store, &collect_rrs))) {
+ /* The collect_rrs->rrs that have not been committed yet, need to
+ have rr_lower_usage(db, collect_rrs.rrs[i]); for them. This is
+ needed to remove references to the db domain tree. However
+ the failure is fatal to the process, so it is not necessary.
+ But we do it anyway in case with a future change this will
+ not be fatal to the process anymore.
+ */
+ /* With all socked up RRs,
+ * lower the usage counter for domains in the rdata.
+ */
+ for (int i = 0; i < collect_rrs.rr_count; i++) {
+ /* Lower the usage counter for domains in the rdata. */
+ rr_lower_usage( nsd->db, collect_rrs.rrs[i]);
+ region_recycle( nsd->db->region, collect_rrs.rrs[i]
+ , sizeof(*collect_rrs.rrs[i])
+ + collect_rrs.rrs[i]->rdlength);
+ }
region_destroy(region);
return 0;
}
}
}
+ commit_RRset(nsd->db, zone, &collect_rrs);
region_destroy(region);
return 1;
}
@@ -1263,10 +1449,9 @@ check_for_bad_serial(namedb_type* db, co
zone = domain_find_zone(db, domain);
if(zone && zone->apex == domain && zone->soa_rrset && old_serial)
{
- uint32_t memserial;
- memcpy(&memserial, rdata_atom_data(zone->soa_rrset->rrs[0].rdatas[2]),
- sizeof(uint32_t));
- if(old_serial != ntohl(memserial)) {
+ uint32_t memserial = 0;
+ retrieve_soa_rdata_serial(zone->soa_rrset->rrs[0], &memserial);
+ if(old_serial != memserial) {
region_destroy(region);
return 1;
}
@@ -1492,15 +1677,14 @@ void task_new_soainfo(struct udb_base* u
apex = domain_dname(z->apex);
sz = sizeof(struct task_list_d) + dname_total_size(apex);
if(z->soa_rrset && hint == soainfo_ok) {
- ns = domain_dname(rdata_atom_domain(
- z->soa_rrset->rrs[0].rdatas[0]));
- em = domain_dname(rdata_atom_domain(
- z->soa_rrset->rrs[0].rdatas[1]));
+ ns = domain_dname(rdata_domain_ref(z->soa_rrset->rrs[0]));
+ em = domain_dname(rdata_domain_ref_offset(
+ z->soa_rrset->rrs[0], sizeof(void*)));
sz += sizeof(uint32_t)*6 + sizeof(uint8_t)*2
+ ns->name_size + em->name_size;
} else {
- ns = 0;
- em = 0;
+ ns = NULL;
+ em = NULL;
}
/* create new task_list item */
@@ -1512,7 +1696,7 @@ void task_new_soainfo(struct udb_base* u
TASKLIST(&e)->yesno = (uint64_t)hint;
if(z->soa_rrset && hint == soainfo_ok) {
- uint32_t ttl = htonl(z->soa_rrset->rrs[0].ttl);
+ uint32_t ttl = htonl(z->soa_rrset->rrs[0]->ttl);
uint8_t* p = (uint8_t*)TASKLIST(&e)->zname;
p += dname_total_size(apex);
memmove(p, &ttl, sizeof(uint32_t));
@@ -1525,20 +1709,8 @@ void task_new_soainfo(struct udb_base* u
p += sizeof(uint8_t);
memmove(p, dname_name(em), em->name_size);
p += em->name_size;
- memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[2]),
- sizeof(uint32_t));
- p += sizeof(uint32_t);
- memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[3]),
- sizeof(uint32_t));
- p += sizeof(uint32_t);
- memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[4]),
- sizeof(uint32_t));
- p += sizeof(uint32_t);
- memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[5]),
- sizeof(uint32_t));
- p += sizeof(uint32_t);
- memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[6]),
- sizeof(uint32_t));
+ memmove(p, z->soa_rrset->rrs[0]->rdata + sizeof(void*)*2,
+ sizeof(uint32_t)*5);
}
udb_ptr_unlink(&e, udb);
}
Index: difffile.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/difffile.h,v
diff -u -p -r1.7 difffile.h
--- difffile.h 3 Sep 2025 18:46:48 -0000 1.7
+++ difffile.h 18 Mar 2026 20:44:03 -0000
@@ -15,6 +15,8 @@
#include "udb.h"
struct nsd;
struct nsdst;
+struct ixfr_store;
+struct collect_rrs;
#define DIFF_PART_XXFR ('X'<<24 | 'X'<<16 | 'F'<<8 | 'R')
#define DIFF_PART_XFRF ('X'<<24 | 'F'<<16 | 'R'<<8 | 'F')
@@ -57,14 +59,16 @@ int diff_read_str(FILE* in, char* buf, s
void delete_zone_rrs(namedb_type* db, zone_type* zone);
/* delete an RR */
int delete_RR(namedb_type* db, const dname_type* dname,
- uint16_t type, uint16_t klass,
+ uint16_t type, uint16_t klass, uint32_t ttl,
buffer_type* packet, size_t rdatalen, zone_type *zone,
- region_type* temp_region, int* softfail);
+ region_type* temp_region, int* softfail,
+ struct ixfr_store* ixfr_store);
/* add an RR */
int add_RR(namedb_type* db, const dname_type* dname,
uint16_t type, uint16_t klass, uint32_t ttl,
buffer_type* packet, size_t rdatalen, zone_type *zone,
- int* softfail);
+ int* softfail, struct ixfr_store* ixfr_store,
+ struct collect_rrs* collect_rrs);
/* apply the xfr file identified by xfrfilenr to zone */
int apply_ixfr_for_zone(struct nsd* nsd, zone_type* zone, FILE* in,
Index: dname.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dname.c,v
diff -u -p -r1.17 dname.c
--- dname.c 6 Sep 2025 17:41:37 -0000 1.17
+++ dname.c 18 Mar 2026 20:44:03 -0000
@@ -26,7 +26,7 @@ const dname_type *
dname_make(region_type *region, const uint8_t *name, int normalize)
{
size_t name_size = 0;
- uint8_t label_offsets[MAXDOMAINLEN];
+ uint8_t label_offsets[MAXDOMAINLEN/2+1];
uint8_t label_count = 0;
const uint8_t *label = name;
dname_type *result;
@@ -42,17 +42,14 @@ dname_make(region_type *region, const ui
++label_count;
name_size += label_length(label) + 1;
- if (label_is_root(label))
- break;
if (name_size > MAXDOMAINLEN)
return NULL;
+ if (label_is_root(label))
+ break;
label = label_next(label);
}
- if (name_size > MAXDOMAINLEN)
- return NULL;
-
assert(label_count <= MAXDOMAINLEN / 2 + 1);
/* Reverse label offsets. */
@@ -619,4 +616,103 @@ is_dname_subdomain_of_case(const uint8_t
/* The trailing portion is not at a label point. */
return 0;
+}
+
+size_t
+buf_dname_length(const uint8_t* buf, size_t len)
+{
+ size_t l = 0;
+ if(!buf || len == 0)
+ return l;
+ while(len > 0 && buf[0] != 0) {
+ size_t lablen = (size_t)(buf[0]);
+ if( (lablen&0xc0) )
+ return 0; /* the name should be uncompressed */
+ if(lablen+1 > len)
+ return 0; /* should fit in the buffer */
+ l += lablen+1;
+ len -= lablen+1;
+ buf += lablen+1;
+ if(l > MAXDOMAINLEN)
+ return 0;
+ }
+ if(len == 0)
+ return 0; /* end label should fit in buffer */
+ if(buf[0] != 0)
+ return 0; /* must end in root label */
+ l += 1; /* for the end root label */
+ if(l > MAXDOMAINLEN)
+ return 0;
+ return l;
+}
+
+int
+dname_make_buffered(struct dname_buffer* dname, uint8_t *name, int normalize)
+{
+ size_t name_size = 0;
+ uint8_t label_offsets[MAXDOMAINLEN/2+1];
+ uint8_t label_count = 0;
+ const uint8_t *label = name;
+ ssize_t i;
+
+ assert(name);
+
+ while (1) {
+ if(!label_is_normal(label))
+ return 0;
+
+ label_offsets[label_count] = (uint8_t) (label - name);
+ ++label_count;
+ name_size += label_length(label) + 1;
+
+ if (name_size > MAXDOMAINLEN)
+ return 0;
+ if (label_is_root(label))
+ break;
+
+ label = label_next(label);
+ }
+
+ assert(label_count <= MAXDOMAINLEN / 2 + 1);
+
+ /* Reverse label offsets. */
+ for (i = 0; i < label_count / 2; ++i) {
+ uint8_t tmp = label_offsets[i];
+ label_offsets[i] = label_offsets[label_count - i - 1];
+ label_offsets[label_count - i - 1] = tmp;
+ }
+
+ /* Move the name to the correct part of the result */
+ memmove( ((char*)dname)+sizeof(struct dname)+
+ label_count*sizeof(uint8_t), name, name_size);
+ dname->dname.name_size = name_size;
+ dname->dname.label_count = label_count;
+ memcpy((uint8_t *) dname_label_offsets((void*)dname),
+ label_offsets, label_count * sizeof(uint8_t));
+ if (normalize) {
+ uint8_t *src = (uint8_t *) dname_name((void*)dname);
+ while (!label_is_root(src)) {
+ ssize_t len = label_length(src);
+ src++;
+ for (i = 0; i < len; ++i) {
+ *src = DNAME_NORMALIZE((unsigned char)*src);
+ src++;
+ }
+ }
+ }
+ return 1;
+}
+
+int
+dname_make_from_packet_buffered(struct dname_buffer* dname,
+ buffer_type *packet, int allow_pointers, int normalize)
+{
+ int wirelen = dname_make_wire_from_packet(dname->storage,
+ packet, allow_pointers);
+ if(wirelen == 0)
+ return 0;
+ if(!dname_make_buffered(dname, dname->storage, normalize))
+ return 0;
+ assert(wirelen == dname->dname.name_size);
+ return wirelen;
}
Index: dname.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dname.h,v
diff -u -p -r1.5 dname.h
--- dname.h 3 Sep 2025 18:46:48 -0000 1.5
+++ dname.h 18 Mar 2026 20:44:03 -0000
@@ -403,4 +403,49 @@ int dname_equal_nocase(uint8_t* a, uint8
int is_dname_subdomain_of_case(const uint8_t* d, unsigned int len,
const uint8_t* d2, unsigned int len2);
+/*
+ * Calculate length of dname in uncompressed wireformat in buffer.
+ * @param buf: The buffer with the uncompressed dname.
+ * @param len: length of the buffer.
+ * @return 0 on error, otherwise the uncompressed wireformat dname
+ * length is returned.
+ */
+size_t buf_dname_length(const uint8_t* buf, size_t len);
+
+/* This structure is sufficient in size for a struct dname. It can
+ * be cast to a struct dname*, since it has the same data. */
+struct dname_buffer {
+ struct dname dname;
+ /* storage for labelcount, and for the wireformat name.
+ * The labelcount can be 1 byte per label, maxlen/2 + 1(root label).
+ * The wireformat name, MAXDOMAINLEN+1.
+ * This allocates storage for it, due to alignment, the struct
+ * dname may have padding. The content is stored after the
+ * sizeof(struct dname), with label_offsets and name. */
+ uint8_t storage[MAXDOMAINLEN/2 + 1 + MAXDOMAINLEN+1 ];
+};
+
+/*
+ * Make the dname and label offsets.
+ * @param dname: the buffer with size. The result is in here, at the
+ * start of the allocated size. The input is also buffered temporarily
+ * in here.
+ * @param name: input name, points into the buffer space of dname.
+ * @param normalize: if the dname has to be normalized.
+ * @return 0 on failure.
+ */
+int dname_make_buffered(struct dname_buffer* dname, uint8_t *name,
+ int normalize);
+
+/*
+ * Parse a domain name from packet and store it in the buffer.
+ * @param dname: the buffer with sufficient size for the dname.
+ * @param packet: packet, at the position of the dname. The position is moved.
+ * @param allow_pointers: set to true if compression pointers are allowed.
+ * @param normalize: set to true if the domain name has to be normalized.
+ * @return 0 on failure, or name_length when done.
+ */
+int dname_make_from_packet_buffered(struct dname_buffer* dname,
+ buffer_type *packet, int allow_pointers, int normalize);
+
#endif /* DNAME_H */
Index: dns.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dns.c,v
diff -u -p -r1.23 dns.c
--- dns.c 6 Sep 2025 17:41:37 -0000 1.23
+++ dns.c 18 Mar 2026 20:44:03 -0000
@@ -21,7 +21,7 @@
#endif
#include "dns.h"
-#include "zonec.h"
+#include "rdata.h"
/* Taken from RFC 1035, section 3.2.4. */
static lookup_table_type dns_rrclasses[] = {
@@ -32,937 +32,1039 @@ static lookup_table_type dns_rrclasses[]
{ 0, NULL }
};
-static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+2)] = {
+/* For a standard field, it is not optional, has no rdata field functions. */
+#define FIELD(name, size) { name, 0 /* is_optional */, size, NULL /* calc_len_func */, NULL /* calc_len_uncompressed_wire_func */ }
+
+/* For a field entry with all values, for optional fields, or with defined
+ * rdata field functions. */
+#define FIELD_ENTRY(name, is_optional, size, calc_len_func, cal_len_uncompressed_wire_func ) { name, is_optional, size, calc_len_func, cal_len_uncompressed_wire_func }
+
+static const struct nsd_rdata_descriptor generic_rdata_fields[] = {
+ FIELD("", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor a_rdata_fields[] = {
+ FIELD("address", 4)
+};
+
+static const struct nsd_rdata_descriptor ns_rdata_fields[] = {
+ FIELD("host", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor md_rdata_fields[] = {
+ FIELD("madname", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor mf_rdata_fields[] = {
+ FIELD("madname", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor cname_rdata_fields[] = {
+ FIELD("host", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor soa_rdata_fields[] = {
+ FIELD("primary", RDATA_COMPRESSED_DNAME),
+ FIELD("mailbox", RDATA_COMPRESSED_DNAME),
+ FIELD("serial", 4),
+ FIELD("refresh", 4),
+ FIELD("retry", 4),
+ FIELD("expire", 4),
+ FIELD("minimum", 4)
+};
+
+static const struct nsd_rdata_descriptor mb_rdata_fields[] = {
+ FIELD("madname", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor mg_rdata_fields[] = {
+ FIELD("mgmname", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor mr_rdata_fields[] = {
+ FIELD("newname", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor wks_rdata_fields[] = {
+ FIELD("address", 4),
+ FIELD("protocol", 1),
+ FIELD("bitmap", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor ptr_rdata_fields[] = {
+ FIELD("ptrdname", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor hinfo_rdata_fields[] = {
+ FIELD("cpu", RDATA_STRING),
+ FIELD("os", RDATA_STRING)
+};
+
+static const struct nsd_rdata_descriptor minfo_rdata_fields[] = {
+ FIELD("rmailbx", RDATA_COMPRESSED_DNAME),
+ FIELD("emailbx", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor mx_rdata_fields[] = {
+ FIELD("priority", 2),
+ FIELD("hostname", RDATA_COMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor txt_rdata_fields[] = {
+ FIELD("text", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor rp_rdata_fields[] = {
+ FIELD("mailbox", RDATA_UNCOMPRESSED_DNAME),
+ FIELD("text", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor afsdb_rdata_fields[] = {
+ FIELD("subtype", 2),
+ FIELD("hostname", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor x25_rdata_fields[] = {
+ FIELD("address", RDATA_STRING)
+};
+
+static const struct nsd_rdata_descriptor isdn_rdata_fields[] = {
+ FIELD("address", RDATA_STRING),
+ FIELD_ENTRY("subaddress", 1, RDATA_STRING, NULL, NULL)
+};
+
+static const struct nsd_rdata_descriptor rt_rdata_fields[] = {
+ FIELD("preference", 2),
+ FIELD("hostname", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor nsap_rdata_fields[] = {
+ FIELD("address", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor nsap_ptr_rdata_fields[] = {
+ FIELD("hostname", RDATA_STRING)
+};
+
+static const struct nsd_rdata_descriptor sig_rdata_fields[] = {
+ FIELD("sigtype", 2),
+ FIELD("algorithm", 1),
+ FIELD("labels", 1),
+ FIELD("origttl", 4),
+ FIELD("expire", 4),
+ FIELD("inception", 4),
+ FIELD("keytag", 2),
+ FIELD("signer", RDATA_LITERAL_DNAME),
+ FIELD("signature", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor key_rdata_fields[] = {
+ FIELD("flags", 2),
+ FIELD("protocol", 1),
+ FIELD("algorithm", 1),
+ FIELD("publickey", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor px_rdata_fields[] = {
+ FIELD("preference", 2),
+ FIELD("map822", RDATA_UNCOMPRESSED_DNAME),
+ FIELD("mapx400", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor gpos_rdata_fields[] = {
+ FIELD("latitude", RDATA_STRING),
+ FIELD("longitude", RDATA_STRING),
+ FIELD("altitude", RDATA_STRING)
+};
+
+static const struct nsd_rdata_descriptor aaaa_rdata_fields[] = {
+ FIELD("address", 16)
+};
+
+static const struct nsd_rdata_descriptor loc_rdata_fields[] = {
+ FIELD("version", 1),
+ FIELD("size", 1),
+ FIELD("horizontal precision", 1),
+ FIELD("vertical precision", 1),
+ FIELD("latitude", 4),
+ FIELD("longitude", 4),
+ FIELD("altitude", 4),
+};
+
+static const struct nsd_rdata_descriptor nxt_rdata_fields[] = {
+ FIELD("next domain name", RDATA_UNCOMPRESSED_DNAME),
+ FIELD("type bit map", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor eid_rdata_fields[] = {
+ FIELD("end point identifier", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor nimloc_rdata_fields[] = {
+ FIELD("nimrod locator", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor srv_rdata_fields[] = {
+ FIELD("priority", 2),
+ FIELD("weight", 2),
+ FIELD("port", 2),
+ FIELD("target", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor atma_rdata_fields[] = {
+ FIELD("address", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor naptr_rdata_fields[] = {
+ FIELD("order", 2),
+ FIELD("preference", 2),
+ FIELD("flags", RDATA_STRING),
+ FIELD("services", RDATA_STRING),
+ FIELD("regex", RDATA_STRING),
+ FIELD("replacement", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor kx_rdata_fields[] = {
+ FIELD("preference", 2),
+ FIELD("exchanger", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor cert_rdata_fields[] = {
+ FIELD("type", 2),
+ FIELD("key tag", 2),
+ FIELD("algorithm", 1),
+ FIELD("certificate", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor a6_rdata_fields[] = {
+ FIELD("address", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor dname_rdata_fields[] = {
+ FIELD("source", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor sink_rdata_fields[] = {
+ FIELD("coding", 1),
+ FIELD("subcoding", 1),
+ FIELD("data", RDATA_REMAINDER),
+};
+
+static const struct nsd_rdata_descriptor apl_rdata_fields[] = {
+ FIELD_ENTRY("prefix", 1, RDATA_REMAINDER, NULL, NULL)
+};
+
+static const struct nsd_rdata_descriptor ds_rdata_fields[] = {
+ FIELD("keytag", 2),
+ FIELD("algorithm", 1),
+ FIELD("digtype", 1),
+ FIELD("digest", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor sshfp_rdata_fields[] = {
+ FIELD("algorithm", 1),
+ FIELD("ftype", 1),
+ FIELD("fingerprint", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor ipseckey_rdata_fields[] = {
+ FIELD("precedence", 1),
+ FIELD("gateway type", 1),
+ FIELD("algorithm", 1),
+ FIELD_ENTRY("gateway", 0, RDATA_IPSECGATEWAY,
+ ipseckey_gateway_length, ipseckey_gateway_length),
+ FIELD_ENTRY("public key", 1, RDATA_REMAINDER, NULL, NULL)
+};
+
+static const struct nsd_rdata_descriptor rrsig_rdata_fields[] = {
+ FIELD("rrtype", 2),
+ FIELD("algorithm", 1),
+ FIELD("labels", 1),
+ FIELD("origttl", 4),
+ FIELD("expire", 4),
+ FIELD("inception", 4),
+ FIELD("keytag", 2),
+ FIELD("signer", RDATA_LITERAL_DNAME),
+ FIELD("signature", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor nsec_rdata_fields[] = {
+ FIELD("next", RDATA_LITERAL_DNAME),
+ FIELD("types", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor dnskey_rdata_fields[] = {
+ FIELD("flags", 2),
+ FIELD("protocol", 1),
+ FIELD("algorithm", 1),
+ FIELD("publickey", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor dhcid_rdata_fields[] = {
+ FIELD("dhcpinfo", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor nsec3_rdata_fields[] = {
+ FIELD("algorithm", 1),
+ FIELD("flags", 1),
+ FIELD("iterations", 2),
+ FIELD("salt", RDATA_BINARY),
+ FIELD("next", RDATA_BINARY),
+ FIELD("types", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor nsec3param_rdata_fields[] = {
+ FIELD("algorithm", 1),
+ FIELD("flags", 1),
+ FIELD("iterations", 2),
+ FIELD("salt", RDATA_BINARY)
+};
+
+static const struct nsd_rdata_descriptor tlsa_rdata_fields[] = {
+ FIELD("usage", 1),
+ FIELD("selector", 1),
+ FIELD("matching type", 1),
+ FIELD("certificate association data", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor smimea_rdata_fields[] = {
+ FIELD("usage", 1),
+ FIELD("selector", 1),
+ FIELD("matching type", 1),
+ FIELD("certificate association data", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor hip_rdata_fields[] = {
+ FIELD("hip", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor ninfo_rdata_fields[] = {
+ FIELD("text", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor rkey_rdata_fields[] = {
+ FIELD("flags", 2),
+ FIELD("protocol", 1),
+ FIELD("algorithm", 1),
+ FIELD("publickey", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor talink_rdata_fields[] = {
+ FIELD("start or previous", RDATA_LITERAL_DNAME),
+ FIELD("end or next", RDATA_LITERAL_DNAME)
+};
+
+static const struct nsd_rdata_descriptor cds_rdata_fields[] = {
+ FIELD("keytag", 2),
+ FIELD("algorithm", 1),
+ FIELD("digtype", 1),
+ FIELD("digest", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor cdnskey_rdata_fields[] = {
+ FIELD("flags", 2),
+ FIELD("protocol", 1),
+ FIELD("algorithm", 1),
+ FIELD("publickey", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor openpgpkey_rdata_fields[] = {
+ FIELD("key", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor csync_rdata_fields[] = {
+ FIELD("serial", 4),
+ FIELD("flags", 2),
+ FIELD("types", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor zonemd_rdata_fields[] = {
+ FIELD("serial", 4),
+ FIELD("scheme", 1),
+ FIELD("algorithm", 1),
+ FIELD("digest", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor svcb_rdata_fields[] = {
+ FIELD("priority", 2),
+ FIELD("target", RDATA_UNCOMPRESSED_DNAME),
+ FIELD("params", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor https_rdata_fields[] = {
+ FIELD("priority", 2),
+ FIELD("target", RDATA_UNCOMPRESSED_DNAME),
+ FIELD("params", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor dsync_rdata_fields[] = {
+ FIELD("rrtype", 2),
+ FIELD("scheme", 1),
+ FIELD("port", 2),
+ FIELD("target", RDATA_LITERAL_DNAME)
+};
+
+static const struct nsd_rdata_descriptor spf_rdata_fields[] = {
+ FIELD("text", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor nid_rdata_fields[] = {
+ FIELD("nid", 2),
+ FIELD("locator", 8)
+};
+
+static const struct nsd_rdata_descriptor l32_rdata_fields[] = {
+ FIELD("preference", 2),
+ FIELD("locator", 4)
+};
+
+static const struct nsd_rdata_descriptor l64_rdata_fields[] = {
+ FIELD("preference", 2),
+ FIELD("locator", 8)
+};
+
+static const struct nsd_rdata_descriptor lp_rdata_fields[] = {
+ FIELD("preference", 2),
+ FIELD("pointer", RDATA_UNCOMPRESSED_DNAME)
+};
+
+static const struct nsd_rdata_descriptor eui48_rdata_fields[] = {
+ FIELD("address", 6)
+};
+
+static const struct nsd_rdata_descriptor eui64_rdata_fields[] = {
+ FIELD("address", 8)
+};
+
+static const struct nsd_rdata_descriptor uri_rdata_fields[] = {
+ FIELD("priority", 2),
+ FIELD("weight", 2),
+ FIELD("target", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor caa_rdata_fields[] = {
+ FIELD("flags", 1),
+ FIELD("tag", RDATA_STRING),
+ FIELD("value", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor avc_rdata_fields[] = {
+ FIELD("text", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor doa_rdata_fields[] = {
+ FIELD("enterprise", 4),
+ FIELD("type", 4),
+ FIELD("location", 1),
+ FIELD("media type", RDATA_STRING),
+ FIELD("data", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor amtrelay_rdata_fields[] = {
+ FIELD("precedence", 1),
+ FIELD("discovery_type", 1),
+ FIELD_ENTRY("relay", 0, RDATA_AMTRELAY_RELAY,
+ amtrelay_relay_length, amtrelay_relay_length)
+};
+
+static const struct nsd_rdata_descriptor resinfo_rdata_fields[] = {
+ FIELD("text", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor wallet_rdata_fields[] = {
+ FIELD("wallet", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor cla_rdata_fields[] = {
+ FIELD("CLA", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor ipn_rdata_fields[] = {
+ FIELD("CBHE Node Number", 8)
+};
+
+static const struct nsd_rdata_descriptor ta_rdata_fields[] = {
+ FIELD("key", 2),
+ FIELD("algorithm", 1),
+ FIELD("type", 1),
+ FIELD("digest", RDATA_REMAINDER)
+};
+
+static const struct nsd_rdata_descriptor dlv_rdata_fields[] = {
+ FIELD("key", 2),
+ FIELD("algorithm", 1),
+ FIELD("type", 1),
+ FIELD("digest", RDATA_REMAINDER)
+};
+
+#define TYPE(name, code, bools, read, write, print, fields) \
+ { code, name, bools, read, write, print, { sizeof(fields)/sizeof(fields[0]), fields } }
+
+#define UNKNOWN_TYPE(code) \
+ { code, NULL /* mnemonic */, 0 /* has_references */, 0 /* is_compressible */, 0 /* has_dnames */, read_generic_rdata, write_generic_rdata, print_generic_rdata, { sizeof(generic_rdata_fields)/sizeof(generic_rdata_fields[0]), generic_rdata_fields } }
+
+/* The RR type has no references, it is a binary wireformat.
+ * has_references, is_compressible, has_dnames. */
+#define TYPE_HAS_NO_REFS 0, 0, 0
+/* The RR type has references, it has compressed dnames. */
+#define TYPE_HAS_COMPRESSED_DNAME 1, 1, 1
+/* The RR type has references, it has uncompressed dnames. */
+#define TYPE_HAS_UNCOMPRESSED_DNAME 1, 0, 1
+/* The RR type has no references, it has literal dnames. */
+#define TYPE_HAS_LITERAL_DNAME 0, 0, 1
+/* Set the bools, has_references, is_compressible, has_dnames. */
+#define TYPE_HAS_FLAGS(has_references, is_compressible, has_dnames) has_references, is_compressible, has_dnames
+
+const nsd_type_descriptor_type type_descriptors[] = {
/* 0 */
- { 0, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
+ UNKNOWN_TYPE(0), /* Type 0 - Reserved [RFC 6895] */
/* 1 */
- { TYPE_A, "A", 1, 1,
- { RDATA_WF_A }, { RDATA_ZF_A } },
+ TYPE("A", TYPE_A, TYPE_HAS_NO_REFS,
+ read_a_rdata, write_generic_rdata,
+ print_a_rdata, a_rdata_fields),
/* 2 */
- { TYPE_NS, "NS", 1, 1,
- { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("NS", TYPE_NS, TYPE_HAS_COMPRESSED_DNAME,
+ read_compressed_name_rdata, write_compressed_name_rdata,
+ print_name_rdata, ns_rdata_fields),
/* 3 */
- { TYPE_MD, "MD", 1, 1,
- { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("MD", TYPE_MD, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_uncompressed_name_rdata, write_uncompressed_name_rdata,
+ print_name_rdata, md_rdata_fields),
/* 4 */
- { TYPE_MF, "MF", 1, 1,
- { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("MF", TYPE_MF, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_uncompressed_name_rdata, write_uncompressed_name_rdata,
+ print_name_rdata, mf_rdata_fields),
/* 5 */
- { TYPE_CNAME, "CNAME", 1, 1,
- { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("CNAME", TYPE_CNAME, TYPE_HAS_COMPRESSED_DNAME,
+ read_compressed_name_rdata, write_compressed_name_rdata,
+ print_name_rdata, cname_rdata_fields),
/* 6 */
- { TYPE_SOA, "SOA", 7, 7,
- { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME, RDATA_WF_LONG,
- RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG },
- { RDATA_ZF_DNAME, RDATA_ZF_DNAME, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD,
- RDATA_ZF_PERIOD, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD } },
+ TYPE("SOA", TYPE_SOA, TYPE_HAS_COMPRESSED_DNAME,
+ read_soa_rdata, write_soa_rdata,
+ print_soa_rdata, soa_rdata_fields),
/* 7 */
- { TYPE_MB, "MB", 1, 1,
- { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("MB", TYPE_MB, TYPE_HAS_COMPRESSED_DNAME,
+ read_compressed_name_rdata, write_compressed_name_rdata,
+ print_name_rdata, mb_rdata_fields),
/* 8 */
- { TYPE_MG, "MG", 1, 1,
- { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("MG", TYPE_MG, TYPE_HAS_COMPRESSED_DNAME,
+ read_compressed_name_rdata, write_compressed_name_rdata,
+ print_name_rdata, mg_rdata_fields),
/* 9 */
- { TYPE_MR, "MR", 1, 1,
- { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("MR", TYPE_MR, TYPE_HAS_COMPRESSED_DNAME,
+ read_compressed_name_rdata, write_compressed_name_rdata,
+ print_name_rdata, mr_rdata_fields),
/* 10 */
- { TYPE_NULL, "NULL", 1, 1,
- { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
+ TYPE("NULL", TYPE_NULL, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_generic_rdata, generic_rdata_fields),
/* 11 */
- { TYPE_WKS, "WKS", 2, 2,
- { RDATA_WF_A, RDATA_WF_BINARY },
- { RDATA_ZF_A, RDATA_ZF_SERVICES } },
+ TYPE("WKS", TYPE_WKS, TYPE_HAS_NO_REFS,
+ read_wks_rdata, write_generic_rdata,
+ print_wks_rdata, wks_rdata_fields),
/* 12 */
- { TYPE_PTR, "PTR", 1, 1,
- { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("PTR", TYPE_PTR, TYPE_HAS_COMPRESSED_DNAME,
+ read_compressed_name_rdata, write_compressed_name_rdata,
+ print_name_rdata, ptr_rdata_fields),
/* 13 */
- { TYPE_HINFO, "HINFO", 2, 2,
- { RDATA_WF_TEXT, RDATA_WF_TEXT }, { RDATA_ZF_TEXT, RDATA_ZF_TEXT } },
+ TYPE("HINFO", TYPE_HINFO, TYPE_HAS_NO_REFS,
+ read_hinfo_rdata, write_generic_rdata,
+ print_hinfo_rdata, hinfo_rdata_fields),
/* 14 */
- { TYPE_MINFO, "MINFO", 2, 2,
- { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME },
- { RDATA_ZF_DNAME, RDATA_ZF_DNAME } },
+ TYPE("MINFO", TYPE_MINFO, TYPE_HAS_COMPRESSED_DNAME,
+ read_minfo_rdata, write_minfo_rdata,
+ print_minfo_rdata, minfo_rdata_fields),
/* 15 */
- { TYPE_MX, "MX", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_COMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
+ TYPE("MX", TYPE_MX, TYPE_HAS_COMPRESSED_DNAME,
+ read_mx_rdata, write_mx_rdata,
+ print_mx_rdata, mx_rdata_fields),
/* 16 */
- { TYPE_TXT, "TXT", 1, 1,
- { RDATA_WF_TEXTS },
- { RDATA_ZF_TEXTS } },
+ TYPE("TXT", TYPE_TXT, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_txt_rdata, txt_rdata_fields),
/* 17 */
- { TYPE_RP, "RP", 2, 2,
- { RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_DNAME, RDATA_ZF_DNAME } },
+ TYPE("RP", TYPE_RP, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_rp_rdata, write_rp_rdata, print_rp_rdata,
+ rp_rdata_fields),
/* 18 */
- { TYPE_AFSDB, "AFSDB", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
+ TYPE("AFSDB", TYPE_AFSDB, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_afsdb_rdata, write_afsdb_rdata, print_afsdb_rdata,
+ afsdb_rdata_fields),
/* 19 */
- { TYPE_X25, "X25", 1, 1,
- { RDATA_WF_TEXT },
- { RDATA_ZF_TEXT } },
+ TYPE("X25", TYPE_X25, TYPE_HAS_NO_REFS,
+ read_x25_rdata, write_generic_rdata, print_x25_rdata,
+ x25_rdata_fields),
/* 20 */
- { TYPE_ISDN, "ISDN", 1, 2,
- { RDATA_WF_TEXT, RDATA_WF_TEXT },
- { RDATA_ZF_TEXT, RDATA_ZF_TEXT } },
+ TYPE("ISDN", TYPE_ISDN, TYPE_HAS_NO_REFS,
+ read_isdn_rdata, write_generic_rdata, print_isdn_rdata,
+ isdn_rdata_fields),
/* 21 */
- { TYPE_RT, "RT", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
+ TYPE("RT", TYPE_RT, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_rt_rdata, write_rt_rdata, print_mx_rdata,
+ rt_rdata_fields),
/* 22 */
- { TYPE_NSAP, "NSAP", 1, 1,
- { RDATA_WF_BINARY },
- { RDATA_ZF_NSAP } },
+ TYPE("NSAP", TYPE_NSAP, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_nsap_rdata,
+ nsap_rdata_fields),
/* 23 */
- { TYPE_NSAP_PTR, "NSAP-PTR", 1, 1,
- { RDATA_WF_TEXT }, { RDATA_ZF_UNQUOTED } },
+ TYPE("NSAP-PTR", TYPE_NSAP_PTR, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_nsap_ptr_rdata, nsap_ptr_rdata_fields),
/* 24 */
- { TYPE_SIG, "SIG", 9, 9,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG,
- RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT,
- RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY },
- { RDATA_ZF_RRTYPE, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_PERIOD,
- RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT,
- RDATA_ZF_LITERAL_DNAME, RDATA_ZF_BASE64 } },
+ TYPE("SIG", TYPE_SIG, TYPE_HAS_LITERAL_DNAME,
+ read_rrsig_rdata, write_generic_rdata, print_rrsig_rdata,
+ sig_rdata_fields),
/* 25 */
- { TYPE_KEY, "KEY", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM,
- RDATA_ZF_BASE64 } },
+ TYPE("KEY", TYPE_KEY, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_key_rdata,
+ key_rdata_fields),
/* 26 */
- { TYPE_PX, "PX", 3, 3,
- { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME,
- RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_DNAME, RDATA_ZF_DNAME } },
+ TYPE("PX", TYPE_PX, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_px_rdata, write_px_rdata, print_px_rdata,
+ px_rdata_fields),
/* 27 */
- { TYPE_GPOS, "GPOS", 3, 3,
- { RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT },
- { RDATA_ZF_UNQUOTED, RDATA_ZF_UNQUOTED, RDATA_ZF_UNQUOTED} },
+ TYPE("GPOS", TYPE_GPOS, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_gpos_rdata,
+ gpos_rdata_fields),
/* 28 */
- { TYPE_AAAA, "AAAA", 1, 1,
- { RDATA_WF_AAAA },
- { RDATA_ZF_AAAA } },
+ TYPE("AAAA", TYPE_AAAA, TYPE_HAS_NO_REFS,
+ read_aaaa_rdata, write_generic_rdata, print_aaaa_rdata,
+ aaaa_rdata_fields),
/* 29 */
- { TYPE_LOC, "LOC", 1, 1,
- { RDATA_WF_BINARY },
- { RDATA_ZF_LOC } },
+ TYPE("LOC", TYPE_LOC, TYPE_HAS_NO_REFS,
+ read_loc_rdata, write_generic_rdata, print_loc_rdata,
+ loc_rdata_fields),
/* 30 */
- { TYPE_NXT, "NXT", 2, 2,
- { RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_BINARY },
- { RDATA_ZF_DNAME, RDATA_ZF_NXT } },
+ TYPE("NXT", TYPE_NXT, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_nxt_rdata, write_nxt_rdata, print_nxt_rdata,
+ nxt_rdata_fields),
/* 31 */
- { TYPE_EID, "EID", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_HEX } },
+ TYPE("EID", TYPE_EID, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_eid_rdata,
+ eid_rdata_fields),
/* 32 */
- { TYPE_NIMLOC, "NIMLOC", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_HEX } },
+ TYPE("NIMLOC", TYPE_NIMLOC, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_nimloc_rdata,
+ nimloc_rdata_fields),
/* 33 */
- { TYPE_SRV, "SRV", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_SHORT,
- RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
+ TYPE("SRV", TYPE_SRV, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_srv_rdata, write_srv_rdata,
+ print_srv_rdata, srv_rdata_fields),
/* 34 */
- { TYPE_ATMA, "ATMA", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_ATMA } },
+ TYPE("ATMA", TYPE_ATMA, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_atma_rdata,
+ atma_rdata_fields),
/* 35 */
- { TYPE_NAPTR, "NAPTR", 6, 6,
- { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_TEXT, RDATA_WF_TEXT,
- RDATA_WF_TEXT, RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
- RDATA_ZF_TEXT, RDATA_ZF_DNAME } },
+ TYPE("NAPTR", TYPE_NAPTR, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_naptr_rdata, write_naptr_rdata,
+ print_naptr_rdata, naptr_rdata_fields),
/* 36 */
- { TYPE_KX, "KX", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
+ TYPE("KX", TYPE_KX, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_kx_rdata, write_kx_rdata,
+ print_mx_rdata, kx_rdata_fields),
/* 37 */
- { TYPE_CERT, "CERT", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_CERTIFICATE_TYPE, RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM,
- RDATA_ZF_BASE64 } },
+ TYPE("CERT", TYPE_CERT, TYPE_HAS_NO_REFS,
+ read_cert_rdata, write_generic_rdata,
+ print_cert_rdata, cert_rdata_fields),
/* 38 */
- { TYPE_A6, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
+ TYPE("A6", TYPE_A6, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_generic_rdata, a6_rdata_fields),
/* 39 */
- { TYPE_DNAME, "DNAME", 1, 1,
- { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
+ TYPE("DNAME", TYPE_DNAME, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_uncompressed_name_rdata, write_uncompressed_name_rdata,
+ print_name_rdata, dname_rdata_fields),
/* 40 */
- { TYPE_SINK, "SINK", 3, 3,
- { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BASE64 } },
- /* 41 */
- { TYPE_OPT, "OPT", 1, 1,
- { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
+ TYPE("SINK", TYPE_SINK, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata, print_sink_rdata,
+ sink_rdata_fields),
+
+ UNKNOWN_TYPE(41), /* Type 41 - OPT */
+
/* 42 */
- { TYPE_APL, "APL", 0, MAXRDATALEN,
- { RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
- RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL },
- { RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
- RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL } },
+ TYPE("APL", TYPE_APL, TYPE_HAS_NO_REFS,
+ read_apl_rdata, write_generic_rdata,
+ print_apl_rdata, apl_rdata_fields),
/* 43 */
- { TYPE_DS, "DS", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
+ TYPE("DS", TYPE_DS, TYPE_HAS_NO_REFS,
+ read_ds_rdata, write_generic_rdata,
+ print_ds_rdata, ds_rdata_fields),
/* 44 */
- { TYPE_SSHFP, "SSHFP", 3, 3,
- { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
+ TYPE("SSHFP", TYPE_SSHFP, TYPE_HAS_NO_REFS,
+ read_sshfp_rdata, write_generic_rdata,
+ print_sshfp_rdata, sshfp_rdata_fields),
/* 45 */
- { TYPE_IPSECKEY, "IPSECKEY", 4, 5,
- { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_IPSECGATEWAY,
- RDATA_WF_BINARY },
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_IPSECGATEWAY,
- RDATA_ZF_BASE64 } },
+ TYPE("IPSECKEY", TYPE_IPSECKEY, TYPE_HAS_LITERAL_DNAME,
+ read_ipseckey_rdata, write_generic_rdata,
+ print_ipseckey_rdata, ipseckey_rdata_fields),
/* 46 */
- { TYPE_RRSIG, "RRSIG", 9, 9,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG,
- RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT,
- RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY },
- { RDATA_ZF_RRTYPE, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_PERIOD,
- RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT,
- RDATA_ZF_LITERAL_DNAME, RDATA_ZF_BASE64 } },
+ TYPE("RRSIG", TYPE_RRSIG, TYPE_HAS_LITERAL_DNAME,
+ read_rrsig_rdata, write_generic_rdata,
+ print_rrsig_rdata, rrsig_rdata_fields),
/* 47 */
- { TYPE_NSEC, "NSEC", 2, 2,
- { RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY },
- { RDATA_ZF_LITERAL_DNAME, RDATA_ZF_NSEC } },
+ TYPE("NSEC", TYPE_NSEC, TYPE_HAS_LITERAL_DNAME,
+ read_nsec_rdata, write_generic_rdata,
+ print_nsec_rdata, nsec_rdata_fields),
/* 48 */
- { TYPE_DNSKEY, "DNSKEY", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM,
- RDATA_ZF_BASE64 } },
+ TYPE("DNSKEY", TYPE_DNSKEY, TYPE_HAS_NO_REFS,
+ read_dnskey_rdata, write_generic_rdata,
+ print_dnskey_rdata, dnskey_rdata_fields),
/* 49 */
- { TYPE_DHCID, "DHCID", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_BASE64 } },
+ TYPE("DHCID", TYPE_DHCID, TYPE_HAS_NO_REFS,
+ read_dhcid_rdata, write_generic_rdata,
+ print_dhcid_rdata, dhcid_rdata_fields),
/* 50 */
- { TYPE_NSEC3, "NSEC3", 6, 6,
- { RDATA_WF_BYTE, /* hash type */
- RDATA_WF_BYTE, /* flags */
- RDATA_WF_SHORT, /* iterations */
- RDATA_WF_BINARYWITHLENGTH, /* salt */
- RDATA_WF_BINARYWITHLENGTH, /* next hashed name */
- RDATA_WF_BINARY /* type bitmap */ },
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_SHORT, RDATA_ZF_HEX_LEN,
- RDATA_ZF_BASE32, RDATA_ZF_NSEC } },
+ TYPE("NSEC3", TYPE_NSEC3, TYPE_HAS_NO_REFS,
+ read_nsec3_rdata, write_generic_rdata,
+ print_nsec3_rdata, nsec3_rdata_fields),
/* 51 */
- { TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4,
- { RDATA_WF_BYTE, /* hash type */
- RDATA_WF_BYTE, /* flags */
- RDATA_WF_SHORT, /* iterations */
- RDATA_WF_BINARYWITHLENGTH /* salt */ },
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_SHORT, RDATA_ZF_HEX_LEN } },
+ TYPE("NSEC3PARAM", TYPE_NSEC3PARAM, TYPE_HAS_NO_REFS,
+ read_nsec3param_rdata, write_generic_rdata,
+ print_nsec3param_rdata, nsec3param_rdata_fields),
/* 52 */
- { TYPE_TLSA, "TLSA", 4, 4,
- { RDATA_WF_BYTE, /* usage */
- RDATA_WF_BYTE, /* selector */
- RDATA_WF_BYTE, /* matching type */
- RDATA_WF_BINARY }, /* certificate association data */
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
+ TYPE("TLSA", TYPE_TLSA, TYPE_HAS_NO_REFS,
+ read_tlsa_rdata, write_generic_rdata,
+ print_tlsa_rdata, tlsa_rdata_fields),
/* 53 */
- { TYPE_SMIMEA, "SMIMEA", 4, 4,
- { RDATA_WF_BYTE, /* usage */
- RDATA_WF_BYTE, /* selector */
- RDATA_WF_BYTE, /* matching type */
- RDATA_WF_BINARY }, /* certificate association data */
- { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
- /* 54 */
- { 54, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 55 - HIP [RFC 5205] */
- { TYPE_HIP, "HIP", 1, MAXRDATALEN,
- { RDATA_WF_HIP, RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME
- , RDATA_WF_LITERAL_DNAME },
- { RDATA_ZF_HIP, RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME
- , RDATA_ZF_LITERAL_DNAME } },
- /* 56 - NINFO */
- { TYPE_NINFO, "NINFO", 1, 1,
- { RDATA_WF_TEXTS },
- { RDATA_ZF_TEXTS } },
- /* 57 - RKEY */
- { TYPE_RKEY, "RKEY", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM,
- RDATA_ZF_BASE64 } },
- /* 58 - TALINK */
- { TYPE_TALINK, "TALINK", 2, 2,
- { RDATA_WF_LITERAL_DNAME, RDATA_WF_LITERAL_DNAME },
- { RDATA_ZF_LITERAL_DNAME, RDATA_ZF_LITERAL_DNAME } },
- /* 59 - CDS */
- { TYPE_CDS, "CDS", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
- /* 60 - CDNSKEY */
- { TYPE_CDNSKEY, "CDNSKEY", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM,
- RDATA_ZF_BASE64 } },
- /* 61 - OPENPGPKEY */
- { TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1,
- { RDATA_WF_BINARY }, { RDATA_ZF_BASE64 } },
- /* 62 - CSYNC */
- { TYPE_CSYNC, "CSYNC", 3, 3, { RDATA_WF_LONG, RDATA_WF_SHORT,
- RDATA_WF_BINARY }, { RDATA_ZF_LONG, RDATA_ZF_SHORT, RDATA_ZF_NSEC } },
- /* 63 - ZONEMD */
- { TYPE_ZONEMD, "ZONEMD", 4, 4,
- { RDATA_WF_LONG, /* serial */
- RDATA_WF_BYTE, /* scheme */
- RDATA_WF_BYTE, /* hash Algorithm */
- RDATA_WF_BINARY }, /* digest */
- { RDATA_ZF_PERIOD, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
- /* 64 - SVCB */
- { TYPE_SVCB, "SVCB", 2, MAXRDATALEN,
- { RDATA_WF_SHORT /* SvcFieldPriority */
- , RDATA_WF_UNCOMPRESSED_DNAME /* SvcDomainName */
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM /* SvcFieldValue */
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- },
- { RDATA_ZF_SHORT , RDATA_ZF_DNAME
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- } },
- /* 65 - HTTPS */
- { TYPE_HTTPS, "HTTPS", 2, MAXRDATALEN,
- { RDATA_WF_SHORT /* SvcFieldPriority */
- , RDATA_WF_UNCOMPRESSED_DNAME /* SvcDomainName */
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM /* SvcFieldValue */
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM
- },
- { RDATA_ZF_SHORT , RDATA_ZF_DNAME
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM
- } },
+ TYPE("SMIMEA", TYPE_SMIMEA, TYPE_HAS_NO_REFS,
+ read_tlsa_rdata, write_generic_rdata,
+ print_tlsa_rdata, smimea_rdata_fields),
+
+ UNKNOWN_TYPE(54),
+
+ /* 55 */
+ TYPE("HIP", TYPE_HIP, TYPE_HAS_LITERAL_DNAME,
+ read_hip_rdata, write_generic_rdata,
+ print_hip_rdata, hip_rdata_fields),
+ /* 56 */
+ TYPE("NINFO", TYPE_NINFO, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_txt_rdata, ninfo_rdata_fields),
+ /* 57 */
+ TYPE("RKEY", TYPE_RKEY, TYPE_HAS_NO_REFS,
+ read_rkey_rdata, write_generic_rdata,
+ print_rkey_rdata, rkey_rdata_fields),
+ /* 58 */
+ TYPE("TALINK", TYPE_TALINK, TYPE_HAS_LITERAL_DNAME,
+ read_talink_rdata, write_generic_rdata,
+ print_talink_rdata, talink_rdata_fields),
+ /* 59 */
+ TYPE("CDS", TYPE_CDS, TYPE_HAS_NO_REFS,
+ read_ds_rdata, write_generic_rdata,
+ print_ds_rdata, cds_rdata_fields),
+ /* 60 */
+ TYPE("CDNSKEY", TYPE_CDNSKEY, TYPE_HAS_NO_REFS,
+ read_dnskey_rdata, write_generic_rdata,
+ print_dnskey_rdata, cdnskey_rdata_fields),
+ /* 61 */
+ TYPE("OPENPGPKEY", TYPE_OPENPGPKEY, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_openpgpkey_rdata, openpgpkey_rdata_fields),
+ /* 62 */
+ TYPE("CSYNC", TYPE_CSYNC, TYPE_HAS_NO_REFS,
+ read_csync_rdata, write_generic_rdata,
+ print_csync_rdata, csync_rdata_fields),
+ /* 63 */
+ TYPE("ZONEMD", TYPE_ZONEMD, TYPE_HAS_NO_REFS,
+ read_zonemd_rdata, write_generic_rdata,
+ print_zonemd_rdata, zonemd_rdata_fields),
+ /* 64 */
+ TYPE("SVCB", TYPE_SVCB, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_svcb_rdata, write_svcb_rdata,
+ print_svcb_rdata, svcb_rdata_fields),
+ /* 65 */
+ TYPE("HTTPS", TYPE_HTTPS, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_svcb_rdata, write_svcb_rdata,
+ print_svcb_rdata, https_rdata_fields),
/* 66 */
- { TYPE_DSYNC, "DSYNC", 4, 4,
- { RDATA_WF_SHORT , RDATA_WF_BYTE, RDATA_WF_SHORT
- , RDATA_WF_LITERAL_DNAME },
- { RDATA_ZF_RRTYPE, RDATA_ZF_BYTE, RDATA_ZF_SHORT
- , RDATA_ZF_LITERAL_DNAME } },
- /* 67 */
- { 67, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 68 */
- { 68, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 69 */
- { 69, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 70 */
- { 70, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 71 */
- { 71, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 72 */
- { 72, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 73 */
- { 73, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 74 */
- { 74, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 75 */
- { 75, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 76 */
- { 76, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 77 */
- { 77, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 78 */
- { 78, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 79 */
- { 79, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 80 */
- { 80, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 81 */
- { 81, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 82 */
- { 82, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 83 */
- { 83, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 84 */
- { 84, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 85 */
- { 85, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 86 */
- { 86, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 87 */
- { 87, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 88 */
- { 88, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 89 */
- { 89, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 90 */
- { 90, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 91 */
- { 91, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 92 */
- { 92, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 93 */
- { 93, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 94 */
- { 94, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 95 */
- { 95, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 96 */
- { 96, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 97 */
- { 97, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 98 */
- { 98, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
+ TYPE("DSYNC", TYPE_DSYNC, TYPE_HAS_LITERAL_DNAME,
+ read_dsync_rdata, write_generic_rdata,
+ print_dsync_rdata, dsync_rdata_fields),
+
+ UNKNOWN_TYPE(67),
+ UNKNOWN_TYPE(68),
+ UNKNOWN_TYPE(69),
+ UNKNOWN_TYPE(70),
+ UNKNOWN_TYPE(71),
+ UNKNOWN_TYPE(72),
+ UNKNOWN_TYPE(73),
+ UNKNOWN_TYPE(74),
+ UNKNOWN_TYPE(75),
+ UNKNOWN_TYPE(76),
+ UNKNOWN_TYPE(77),
+ UNKNOWN_TYPE(78),
+ UNKNOWN_TYPE(79),
+ UNKNOWN_TYPE(80),
+ UNKNOWN_TYPE(81),
+ UNKNOWN_TYPE(82),
+ UNKNOWN_TYPE(83),
+ UNKNOWN_TYPE(84),
+ UNKNOWN_TYPE(85),
+ UNKNOWN_TYPE(86),
+ UNKNOWN_TYPE(87),
+ UNKNOWN_TYPE(88),
+ UNKNOWN_TYPE(89),
+ UNKNOWN_TYPE(90),
+ UNKNOWN_TYPE(91),
+ UNKNOWN_TYPE(92),
+ UNKNOWN_TYPE(93),
+ UNKNOWN_TYPE(94),
+ UNKNOWN_TYPE(95),
+ UNKNOWN_TYPE(96),
+ UNKNOWN_TYPE(97),
+ UNKNOWN_TYPE(98),
+
/* 99 */
- { TYPE_SPF, "SPF", 1, MAXRDATALEN,
- { RDATA_WF_TEXTS }, { RDATA_ZF_TEXTS } },
- /* 100 - UINFO */
- { 100, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 101 - UID */
- { 101, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 102 - GID */
- { 102, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 103 - UNSPEC */
- { 103, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
+ TYPE("SPF", TYPE_SPF, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_txt_rdata, spf_rdata_fields),
+
+ UNKNOWN_TYPE(100), /* Type 100 - UINFO [The RR type code is reserved, no reference] */
+ UNKNOWN_TYPE(101), /* Type 101 - UID [The RR type code is reserved, no reference] */
+ UNKNOWN_TYPE(102), /* Type 102 - GID [The RR type code is reserved, no reference] */
+ UNKNOWN_TYPE(103), /* Type 103 - UNSPEC [The RR type code is reserved, no reference] */
+
/* 104 */
- { TYPE_NID, "NID", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_ILNP64 },
- { RDATA_ZF_SHORT, RDATA_ZF_ILNP64 } },
+ TYPE("NID", TYPE_NID, TYPE_HAS_NO_REFS,
+ read_nid_rdata, write_generic_rdata,
+ print_nid_rdata, nid_rdata_fields),
/* 105 */
- { TYPE_L32, "L32", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_A },
- { RDATA_ZF_SHORT, RDATA_ZF_A } },
+ TYPE("L32", TYPE_L32, TYPE_HAS_NO_REFS,
+ read_l32_rdata, write_generic_rdata,
+ print_l32_rdata, l32_rdata_fields),
/* 106 */
- { TYPE_L64, "L64", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_ILNP64 },
- { RDATA_ZF_SHORT, RDATA_ZF_ILNP64 } },
+ TYPE("L64", TYPE_L64, TYPE_HAS_NO_REFS,
+ read_l64_rdata, write_generic_rdata,
+ print_l64_rdata, l64_rdata_fields),
/* 107 */
- { TYPE_LP, "LP", 2, 2,
- { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME },
- { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
+ TYPE("LP", TYPE_LP, TYPE_HAS_UNCOMPRESSED_DNAME,
+ read_lp_rdata, write_lp_rdata,
+ print_lp_rdata, lp_rdata_fields),
/* 108 */
- { TYPE_EUI48, "EUI48", 1, 1,
- { RDATA_WF_EUI48 }, { RDATA_ZF_EUI48 } },
+ TYPE("EUI48", TYPE_EUI48, TYPE_HAS_NO_REFS,
+ read_eui48_rdata, write_generic_rdata,
+ print_eui48_rdata, eui48_rdata_fields),
/* 109 */
- { TYPE_EUI64, "EUI64", 1, 1,
- { RDATA_WF_EUI64 }, { RDATA_ZF_EUI64 } },
- /* 110 */
- { 110, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 111 */
- { 111, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 112 */
- { 112, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 113 */
- { 113, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 114 */
- { 114, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 115 */
- { 115, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 116 */
- { 116, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 117 */
- { 117, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 118 */
- { 118, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 119 */
- { 119, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 120 */
- { 120, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 121 */
- { 121, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 122 */
- { 122, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 123 */
- { 123, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 124 */
- { 124, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 125 */
- { 125, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 126 */
- { 126, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 127 */
- { 127, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 128 */
- { 128, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 129 */
- { 129, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 130 */
- { 130, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 131 */
- { 131, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 132 */
- { 132, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 133 */
- { 133, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 134 */
- { 134, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 135 */
- { 135, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 136 */
- { 136, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 137 */
- { 137, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 138 */
- { 138, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 139 */
- { 139, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 140 */
- { 140, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 141 */
- { 141, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 142 */
- { 142, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 143 */
- { 143, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 144 */
- { 144, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 145 */
- { 145, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 146 */
- { 146, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 147 */
- { 147, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 148 */
- { 148, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 149 */
- { 149, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 150 */
- { 150, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 151 */
- { 151, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 152 */
- { 152, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 153 */
- { 153, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 154 */
- { 154, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 155 */
- { 155, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 156 */
- { 156, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 157 */
- { 157, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 158 */
- { 158, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 159 */
- { 159, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 160 */
- { 160, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 161 */
- { 161, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 162 */
- { 162, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 163 */
- { 163, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 164 */
- { 164, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 165 */
- { 165, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 166 */
- { 166, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 167 */
- { 167, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 168 */
- { 168, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 169 */
- { 169, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 170 */
- { 170, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 171 */
- { 171, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 172 */
- { 172, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 173 */
- { 173, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 174 */
- { 174, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 175 */
- { 175, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 176 */
- { 176, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 177 */
- { 177, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 178 */
- { 178, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 179 */
- { 179, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 180 */
- { 180, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 181 */
- { 181, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 182 */
- { 182, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 183 */
- { 183, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 184 */
- { 184, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 185 */
- { 185, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 186 */
- { 186, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 187 */
- { 187, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 188 */
- { 188, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 189 */
- { 189, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 190 */
- { 190, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 191 */
- { 191, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 192 */
- { 192, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 193 */
- { 193, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 194 */
- { 194, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 195 */
- { 195, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 196 */
- { 196, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 197 */
- { 197, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 198 */
- { 198, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 199 */
- { 199, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 200 */
- { 200, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 201 */
- { 201, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 202 */
- { 202, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 203 */
- { 203, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 204 */
- { 204, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 205 */
- { 205, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 206 */
- { 206, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 207 */
- { 207, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 208 */
- { 208, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 209 */
- { 209, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 210 */
- { 210, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 211 */
- { 211, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 212 */
- { 212, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 213 */
- { 213, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 214 */
- { 214, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 215 */
- { 215, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 216 */
- { 216, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 217 */
- { 217, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 218 */
- { 218, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 219 */
- { 219, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 220 */
- { 220, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 221 */
- { 221, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 222 */
- { 222, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 223 */
- { 223, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 224 */
- { 224, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 225 */
- { 225, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 226 */
- { 226, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 227 */
- { 227, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 228 */
- { 228, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 229 */
- { 229, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 230 */
- { 230, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 231 */
- { 231, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 232 */
- { 232, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 233 */
- { 233, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 234 */
- { 234, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 235 */
- { 235, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 236 */
- { 236, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 237 */
- { 237, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 238 */
- { 238, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 239 */
- { 239, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 240 */
- { 240, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 241 */
- { 241, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 242 */
- { 242, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 243 */
- { 243, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 244 */
- { 244, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 245 */
- { 245, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 246 */
- { 246, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 247 */
- { 247, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 248 */
- { 248, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 249 - TKEY [RFC 2930] */
- { 249, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 250 - TSIG [RFC 2845] */
- { 250, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 251 - IXFR [RFC 1995] */
- { 251, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 252 - AXFR [RFC 1035, RFC 5936] */
- { 252, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 253 - MAILB [RFC 1035] */
- { 253, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 254 - MAILA [RFC 1035] */
- { 254, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 255 - * [RFC 1035, RFC 6895] */
- { 255, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
- /* 256 - URI */
- { TYPE_URI, "URI", 3, 3,
- { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_LONG_TEXT },
- { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_LONG_TEXT } },
- /* 257 - CAA [RFC 6844] */
- { TYPE_CAA, "CAA", 3, 3,
- { RDATA_WF_BYTE, RDATA_WF_TEXT, RDATA_WF_LONG_TEXT },
- { RDATA_ZF_BYTE, RDATA_ZF_TAG, RDATA_ZF_LONG_TEXT } },
- /* 258 - AVC */
- { TYPE_AVC, "AVC", 1, 1,
- { RDATA_WF_TEXTS },
- { RDATA_ZF_TEXTS } },
- /* 259 - DOA */
- { TYPE_DOA, "DOA", 5, 5,
- { RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_BYTE,
- RDATA_WF_TEXT, RDATA_WF_BINARY },
- { RDATA_ZF_LONG, RDATA_ZF_LONG, RDATA_ZF_BYTE,
- RDATA_ZF_TEXT, RDATA_ZF_BASE64 } },
- /* 260 - AMTRELAY */
- { TYPE_AMTRELAY, "AMTRELAY", 3, 3,
- { RDATA_WF_BYTE, RDATA_WF_BYTE , RDATA_WF_AMTRELAY_RELAY },
- { RDATA_ZF_BYTE, RDATA_ZF_AMTRELAY_D_TYPE, RDATA_ZF_AMTRELAY_RELAY } },
- /* 261 - RESINFO */
- { TYPE_RESINFO, "RESINFO", 1, 1, { RDATA_WF_TEXTS }, { RDATA_ZF_UNQUOTEDS } },
- /* 262 - WALLET */
- { TYPE_WALLET, "WALLET", 1, 1, { RDATA_WF_TEXTS }, { RDATA_ZF_TEXTS } },
- /* 263 - CLA */
- { TYPE_CLA, "CLA", 1, 1, { RDATA_WF_TEXTS }, { RDATA_ZF_TEXTS } },
- /* 264 - IPN */
- { TYPE_IPN, "IPN", 1, 1, { RDATA_WF_LONGLONG }, { RDATA_ZF_LONGLONG } },
-
- /* 32768 - TA */
- { TYPE_TA, "TA", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
- /* 32769 */
- { TYPE_DLV, "DLV", 4, 4,
- { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
- { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
-};
+ TYPE("EUI64", TYPE_EUI64, TYPE_HAS_NO_REFS,
+ read_eui64_rdata, write_generic_rdata,
+ print_eui64_rdata, eui64_rdata_fields),
-rrtype_descriptor_type *
-rrtype_descriptor_by_type(uint16_t type)
-{
- if (type < RRTYPE_DESCRIPTORS_LENGTH)
- return &rrtype_descriptors[type];
- else if (type == TYPE_DLV)
- return &rrtype_descriptors[PSEUDO_TYPE_DLV];
- else if (type == TYPE_TA)
- return &rrtype_descriptors[PSEUDO_TYPE_TA];
- return &rrtype_descriptors[0];
-}
+ UNKNOWN_TYPE(110),
+ UNKNOWN_TYPE(111),
+ UNKNOWN_TYPE(112),
+ UNKNOWN_TYPE(113),
+ UNKNOWN_TYPE(114),
+ UNKNOWN_TYPE(115),
+ UNKNOWN_TYPE(116),
+ UNKNOWN_TYPE(117),
+ UNKNOWN_TYPE(118),
+ UNKNOWN_TYPE(119),
+ UNKNOWN_TYPE(120),
+ UNKNOWN_TYPE(121),
+ UNKNOWN_TYPE(122),
+ UNKNOWN_TYPE(123),
+ UNKNOWN_TYPE(124),
+ UNKNOWN_TYPE(125),
+ UNKNOWN_TYPE(126),
+ UNKNOWN_TYPE(127),
-rrtype_descriptor_type *
-rrtype_descriptor_by_name(const char *name)
-{
- int i;
+ /* 128 */
+ /* The mnemonic is included so it can be printed in type bitmaps.*/
+ TYPE("NXNAME", TYPE_NXNAME, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_generic_rdata, generic_rdata_fields),
- for (i = 0; i < RRTYPE_DESCRIPTORS_LENGTH; ++i) {
- if (rrtype_descriptors[i].name
- && strcasecmp(rrtype_descriptors[i].name, name) == 0)
- {
- return &rrtype_descriptors[i];
- }
- }
+ UNKNOWN_TYPE(129),
+ UNKNOWN_TYPE(130),
+ UNKNOWN_TYPE(131),
+ UNKNOWN_TYPE(132),
+ UNKNOWN_TYPE(133),
+ UNKNOWN_TYPE(134),
+ UNKNOWN_TYPE(135),
+ UNKNOWN_TYPE(136),
+ UNKNOWN_TYPE(137),
+ UNKNOWN_TYPE(138),
+ UNKNOWN_TYPE(139),
+ UNKNOWN_TYPE(140),
+ UNKNOWN_TYPE(141),
+ UNKNOWN_TYPE(142),
+ UNKNOWN_TYPE(143),
+ UNKNOWN_TYPE(144),
+ UNKNOWN_TYPE(145),
+ UNKNOWN_TYPE(146),
+ UNKNOWN_TYPE(147),
+ UNKNOWN_TYPE(148),
+ UNKNOWN_TYPE(149),
+ UNKNOWN_TYPE(150),
+ UNKNOWN_TYPE(151),
+ UNKNOWN_TYPE(152),
+ UNKNOWN_TYPE(153),
+ UNKNOWN_TYPE(154),
+ UNKNOWN_TYPE(155),
+ UNKNOWN_TYPE(156),
+ UNKNOWN_TYPE(157),
+ UNKNOWN_TYPE(158),
+ UNKNOWN_TYPE(159),
+ UNKNOWN_TYPE(160),
+ UNKNOWN_TYPE(161),
+ UNKNOWN_TYPE(162),
+ UNKNOWN_TYPE(163),
+ UNKNOWN_TYPE(164),
+ UNKNOWN_TYPE(165),
+ UNKNOWN_TYPE(166),
+ UNKNOWN_TYPE(167),
+ UNKNOWN_TYPE(168),
+ UNKNOWN_TYPE(169),
+ UNKNOWN_TYPE(170),
+ UNKNOWN_TYPE(171),
+ UNKNOWN_TYPE(172),
+ UNKNOWN_TYPE(173),
+ UNKNOWN_TYPE(174),
+ UNKNOWN_TYPE(175),
+ UNKNOWN_TYPE(176),
+ UNKNOWN_TYPE(177),
+ UNKNOWN_TYPE(178),
+ UNKNOWN_TYPE(179),
+ UNKNOWN_TYPE(180),
+ UNKNOWN_TYPE(181),
+ UNKNOWN_TYPE(182),
+ UNKNOWN_TYPE(183),
+ UNKNOWN_TYPE(184),
+ UNKNOWN_TYPE(185),
+ UNKNOWN_TYPE(186),
+ UNKNOWN_TYPE(187),
+ UNKNOWN_TYPE(188),
+ UNKNOWN_TYPE(189),
+ UNKNOWN_TYPE(190),
+ UNKNOWN_TYPE(191),
+ UNKNOWN_TYPE(192),
+ UNKNOWN_TYPE(193),
+ UNKNOWN_TYPE(194),
+ UNKNOWN_TYPE(195),
+ UNKNOWN_TYPE(196),
+ UNKNOWN_TYPE(197),
+ UNKNOWN_TYPE(198),
+ UNKNOWN_TYPE(199),
+ UNKNOWN_TYPE(200),
+ UNKNOWN_TYPE(201),
+ UNKNOWN_TYPE(202),
+ UNKNOWN_TYPE(203),
+ UNKNOWN_TYPE(204),
+ UNKNOWN_TYPE(205),
+ UNKNOWN_TYPE(206),
+ UNKNOWN_TYPE(207),
+ UNKNOWN_TYPE(208),
+ UNKNOWN_TYPE(209),
+ UNKNOWN_TYPE(210),
+ UNKNOWN_TYPE(211),
+ UNKNOWN_TYPE(212),
+ UNKNOWN_TYPE(213),
+ UNKNOWN_TYPE(214),
+ UNKNOWN_TYPE(215),
+ UNKNOWN_TYPE(216),
+ UNKNOWN_TYPE(217),
+ UNKNOWN_TYPE(218),
+ UNKNOWN_TYPE(219),
+ UNKNOWN_TYPE(220),
+ UNKNOWN_TYPE(221),
+ UNKNOWN_TYPE(222),
+ UNKNOWN_TYPE(223),
+ UNKNOWN_TYPE(224),
+ UNKNOWN_TYPE(225),
+ UNKNOWN_TYPE(226),
+ UNKNOWN_TYPE(227),
+ UNKNOWN_TYPE(228),
+ UNKNOWN_TYPE(229),
+ UNKNOWN_TYPE(230),
+ UNKNOWN_TYPE(231),
+ UNKNOWN_TYPE(232),
+ UNKNOWN_TYPE(233),
+ UNKNOWN_TYPE(234),
+ UNKNOWN_TYPE(235),
+ UNKNOWN_TYPE(236),
+ UNKNOWN_TYPE(237),
+ UNKNOWN_TYPE(238),
+ UNKNOWN_TYPE(239),
+ UNKNOWN_TYPE(240),
+ UNKNOWN_TYPE(241),
+ UNKNOWN_TYPE(242),
+ UNKNOWN_TYPE(243),
+ UNKNOWN_TYPE(244),
+ UNKNOWN_TYPE(245),
+ UNKNOWN_TYPE(246),
+ UNKNOWN_TYPE(247),
+ UNKNOWN_TYPE(248),
+ UNKNOWN_TYPE(249), /* Type 249 - TKEY [RFC 2930] */
+ UNKNOWN_TYPE(250), /* Type 250 - TSIG */
+ UNKNOWN_TYPE(251), /* Type 251 - IXFR */
+ UNKNOWN_TYPE(252), /* Type 252 - AXFR */
+ UNKNOWN_TYPE(253), /* Type 253 - MAILB */
+ UNKNOWN_TYPE(254), /* Type 254 - MAILA */
+ UNKNOWN_TYPE(255), /* Type 255 - ANY */
- if (rrtype_descriptors[PSEUDO_TYPE_DLV].name
- && strcasecmp(rrtype_descriptors[PSEUDO_TYPE_DLV].name, name) == 0)
- {
- return &rrtype_descriptors[PSEUDO_TYPE_DLV];
- }
+ /* 256 */
+ TYPE("URI", TYPE_URI, TYPE_HAS_NO_REFS,
+ read_uri_rdata, write_generic_rdata,
+ print_uri_rdata, uri_rdata_fields),
+ /* 257 */
+ TYPE("CAA", TYPE_CAA, TYPE_HAS_NO_REFS,
+ read_caa_rdata, write_generic_rdata,
+ print_caa_rdata, caa_rdata_fields),
+ /* 258 */
+ TYPE("AVC", TYPE_AVC, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_txt_rdata, avc_rdata_fields),
+ /* 259 */
+ TYPE("DOA", TYPE_DOA, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_doa_rdata, doa_rdata_fields),
+ /* 260 */
+ TYPE("AMTRELAY", TYPE_AMTRELAY, TYPE_HAS_LITERAL_DNAME,
+ read_amtrelay_rdata, write_generic_rdata,
+ print_amtrelay_rdata, amtrelay_rdata_fields),
+ /* 261 */
+ TYPE("RESINFO", TYPE_RESINFO, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_resinfo_rdata, resinfo_rdata_fields),
+ /* 262 */
+ TYPE("WALLET", TYPE_WALLET, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_txt_rdata, wallet_rdata_fields),
+ /* 263 */
+ TYPE("CLA", TYPE_CLA, TYPE_HAS_NO_REFS,
+ read_txt_rdata, write_generic_rdata,
+ print_txt_rdata, cla_rdata_fields),
+ /* 264 */
+ TYPE("IPN", TYPE_IPN, TYPE_HAS_NO_REFS,
+ read_generic_rdata, write_generic_rdata,
+ print_ipn_rdata, ipn_rdata_fields),
- return NULL;
-}
+ /* 32768 */
+ TYPE("TA", TYPE_TA, TYPE_HAS_NO_REFS,
+ read_dlv_rdata, write_generic_rdata,
+ print_dlv_rdata, ta_rdata_fields),
+ /* 32769 */
+ TYPE("DLV", TYPE_DLV, TYPE_HAS_NO_REFS,
+ read_dlv_rdata, write_generic_rdata,
+ print_dlv_rdata, dlv_rdata_fields)
+};
+
+#undef UNKNOWN_TYPE
+#undef TYPE
+#undef FIELD
+#undef FIELD_ENTRY
+#undef TYPE_HAS_NO_REFS
+#undef TYPE_HAS_COMPRESSED_DNAME
+#undef TYPE_HAS_UNCOMPRESSED_DNAME
+#undef TYPE_HAS_LITERAL_DNAME
+#undef TYPE_HAS_FLAGS
const char *
rrtype_to_string(uint16_t rrtype)
{
static char buf[20];
- rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype);
+ const nsd_type_descriptor_type *descriptor =
+ nsd_type_descriptor(rrtype);
if (descriptor->name) {
return descriptor->name;
} else {
@@ -980,9 +1082,8 @@ rrtype_to_string(uint16_t rrtype)
uint16_t
rrtype_from_string(const char *name)
{
- char *end;
- long rrtype;
- rrtype_descriptor_type *entry;
+ char *end;
+ long rrtype;
/* Because this routine is called during zone parse for every record,
* we optimise for frequently occurring records.
@@ -1063,9 +1164,9 @@ rrtype_from_string(const char *name)
break;
}
- entry = rrtype_descriptor_by_name(name);
- if (entry) {
- return entry->type;
+ for (int i=0, n=sizeof(type_descriptors)/sizeof(type_descriptors[0]); i < n; i++) {
+ if (type_descriptors[i].name && strcasecmp(type_descriptors[i].name, name) == 0)
+ return type_descriptors[i].type;
}
if (strlen(name) < 5)
@@ -1084,7 +1185,7 @@ rrtype_from_string(const char *name)
if (rrtype < 0 || rrtype > 65535L)
return 0;
- return (uint16_t) rrtype;
+ return (uint16_t) rrtype;
}
const char *
Index: dns.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dns.h,v
diff -u -p -r1.22 dns.h
--- dns.h 6 Sep 2025 17:41:37 -0000 1.22
+++ dns.h 18 Mar 2026 20:44:03 -0000
@@ -9,6 +9,11 @@
#ifndef DNS_H
#define DNS_H
+struct rr;
+struct buffer;
+struct domain;
+struct domain_table;
+struct query;
enum rr_section {
QUESTION_SECTION,
@@ -138,7 +143,7 @@ typedef enum nsd_rc nsd_rc_type;
#define TYPE_HIP 55 /* RFC 8005 */
#define TYPE_NINFO 56 /* NINFO/ninfo-completed-template */
#define TYPE_RKEY 57 /* RKEY/rkey-completed-template */
-#define TYPE_TALINK 58 /* draft-iet5f-dnsop-dnssec-trust-history */
+#define TYPE_TALINK 58 /* draft-ietf-dnsop-dnssec-trust-history */
#define TYPE_CDS 59 /* RFC 7344 */
#define TYPE_CDNSKEY 60 /* RFC 7344 */
#define TYPE_OPENPGPKEY 61 /* RFC 7929 */
@@ -146,7 +151,7 @@ typedef enum nsd_rc nsd_rc_type;
#define TYPE_ZONEMD 63 /* RFC 8976 */
#define TYPE_SVCB 64 /* RFC 9460 */
#define TYPE_HTTPS 65 /* RFC 9460 */
-#define TYPE_DSYNC 66 /* draft-ietf-dnsop-generalized-notify */
+#define TYPE_DSYNC 66 /* RFC 9859 */
#define TYPE_SPF 99 /* RFC 4408 */
@@ -157,12 +162,14 @@ typedef enum nsd_rc nsd_rc_type;
#define TYPE_EUI48 108 /* RFC 7043 */
#define TYPE_EUI64 109 /* RFC 7043 */
-#define TYPE_TSIG 250
-#define TYPE_IXFR 251
-#define TYPE_AXFR 252
-#define TYPE_MAILB 253 /* A request for mailbox-related records (MB, MG or MR) */
-#define TYPE_MAILA 254 /* A request for mail agent RRs (Obsolete - see MX) */
-#define TYPE_ANY 255 /* any type (wildcard) */
+#define TYPE_NXNAME 128 /* RFC 9824 */
+
+#define TYPE_TSIG 250 /* RFC 2845 */
+#define TYPE_IXFR 251 /* RFC 1995 */
+#define TYPE_AXFR 252 /* RFC 1035, RFC 5936 */
+#define TYPE_MAILB 253 /* A request for mailbox-related records (MB, MG or MR) [RFC 1035] */
+#define TYPE_MAILA 254 /* A request for mail agent RRs (Obsolete - see MX) [RFC 1035] */
+#define TYPE_ANY 255 /* any type (wildcard) [RFC 1035, RFC 6895] */
#define TYPE_URI 256 /* RFC 7553 */
#define TYPE_CAA 257 /* RFC 6844 */
#define TYPE_AVC 258 /* AVC/avc-completed-template */
@@ -171,12 +178,10 @@ typedef enum nsd_rc nsd_rc_type;
#define TYPE_RESINFO 261 /* RFC 9606 */
#define TYPE_WALLET 262 /* WALLET/wallet-completed-template */
#define TYPE_CLA 263 /* CLA/cla-completed-template */
-#define TYPE_IPN 264 /* IPN/ipn-completed-template */
+#define TYPE_IPN 264 /* IPN/ipn-completed-template draft-johnson-dns-ipn-cla-07 */
#define TYPE_TA 32768 /* http://www.watson.org/~weiler/INI1999-19.pdf */
#define TYPE_DLV 32769 /* RFC 4431 */
-#define PSEUDO_TYPE_TA RRTYPE_DESCRIPTORS_LENGTH
-#define PSEUDO_TYPE_DLV (RRTYPE_DESCRIPTORS_LENGTH + 1)
#define SVCB_KEY_MANDATORY 0
#define SVCB_KEY_ALPN 1
@@ -188,12 +193,10 @@ typedef enum nsd_rc nsd_rc_type;
#define SVCB_KEY_DOHPATH 7
#define SVCB_KEY_OHTTP 8
#define SVCB_KEY_TLS_SUPPORTED_GROUPS 9
-#define SVCPARAMKEY_COUNT 10
#define MAXLABELLEN 63
#define MAXDOMAINLEN 255
-#define MAXRDATALEN 64 /* This is more than enough, think multiple TXT. */
#define MAX_RDLENGTH 65535
/* Maximum size of a single RR. */
@@ -208,102 +211,203 @@ typedef enum nsd_rc nsd_rc_type;
#define NSEC3_HASH_LEN 20
/*
- * The different types of RDATA wireformat data.
+ * The following RDATA values are used in nsd_rdata_descriptor.length to
+ * indicate a specialized value. They are negative, the normal lengths
+ * are 0..65535 and length is int32_t.
*/
-enum rdata_wireformat
-{
- RDATA_WF_COMPRESSED_DNAME, /* Possibly compressed domain name. */
- RDATA_WF_UNCOMPRESSED_DNAME, /* Uncompressed domain name. */
- RDATA_WF_LITERAL_DNAME, /* Literal (not downcased) dname. */
- RDATA_WF_BYTE, /* 8-bit integer. */
- RDATA_WF_SHORT, /* 16-bit integer. */
- RDATA_WF_LONG, /* 32-bit integer. */
- RDATA_WF_LONGLONG, /* 64-bit integer. */
- RDATA_WF_TEXT, /* Text string. */
- RDATA_WF_TEXTS, /* Text string sequence. */
- RDATA_WF_A, /* 32-bit IPv4 address. */
- RDATA_WF_AAAA, /* 128-bit IPv6 address. */
- RDATA_WF_BINARY, /* Binary data (unknown length). */
- RDATA_WF_BINARYWITHLENGTH, /* Binary data preceded by 1 byte length */
- RDATA_WF_APL, /* APL data. */
- RDATA_WF_IPSECGATEWAY, /* IPSECKEY gateway ip4, ip6 or dname. */
- RDATA_WF_ILNP64, /* 64-bit uncompressed IPv6 address. */
- RDATA_WF_EUI48, /* 48-bit address. */
- RDATA_WF_EUI64, /* 64-bit address. */
- RDATA_WF_LONG_TEXT, /* Long (>255) text string. */
- RDATA_WF_SVCPARAM, /* SvcParam <key>[=<value>] */
- RDATA_WF_HIP, /* HIP rdata up to the Rendezvous Servers */
- RDATA_WF_AMTRELAY_RELAY /* ip4, ip6, dname or nothing */
-};
-typedef enum rdata_wireformat rdata_wireformat_type;
+/* The rdata is a compressed domain name. In namedb it is a reference
+ * with a pointer to struct domain. On the wire, the name can be a
+ * compressed name. The pointer is stored in line and is likely unaligned. */
+#define RDATA_COMPRESSED_DNAME -1
+/* The rdata is an uncompressed domain name. In namedb it is a reference
+ * with a pointer to struct domain. The pointer is stored in line and is
+ * likely unaligned. */
+#define RDATA_UNCOMPRESSED_DNAME -2
+/* The rdata is a literal domain name. It is not a reference to struct
+ * domain, and stored as uncompressed wireformat octets. */
+#define RDATA_LITERAL_DNAME -3
+/* The rdata is a string. It starts with a uint8_t length byte. */
+#define RDATA_STRING -4
+/* The rdata is binary. It starts with a uint8_t length byte. */
+#define RDATA_BINARY -5
+/* The rdata is of type IPSECGATEWAY because of its encoding elsewhere in
+ * the RR. */
+#define RDATA_IPSECGATEWAY -6
+/* The rdata is the remainder of the record, to the end of the bytes, possibly
+ * zero bytes. The length of the field is determined by the rdata length. */
+#define RDATA_REMAINDER -7
+/* The rdata is of type AMTRELAYRELAY because of its encoding elsewhere in
+ * the RR. */
+#define RDATA_AMTRELAY_RELAY -8
/*
- * The different types of RDATA that can appear in the zone file.
+ * Function signature to determine length of the rdata field.
+ * @param rdlength: length of the input rdata.
+ * @param rdata: input bytes with rdata of the RR.
+ * @param offset: current byte position in rdata.
+ * offset is required for the ipsecgateway where we need to read
+ * a couple bytes back
+ * @param domain: this value can be returned as NULL, in which case the
+ * function return value is a length in bytes in wireformat.
+ * If this value is returned nonNULL, it is the special reference
+ * object that needs different treatment. The function return value
+ * is the length that needs to be skipped in rdata to get past the
+ * field, that is a reference when that is a pointer.
+ * For other types of objects an additional function argument could be
+ * added, and then handling in the caller.
+ * @return length in bytes. Or -1 on failure, like rdata length too short.
*/
-enum rdata_zoneformat
-{
- RDATA_ZF_DNAME, /* Domain name. */
- RDATA_ZF_LITERAL_DNAME, /* DNS name (not lowercased domain name). */
- RDATA_ZF_TEXT, /* Text string. */
- RDATA_ZF_TEXTS, /* Text string sequence. */
- RDATA_ZF_BYTE, /* 8-bit integer. */
- RDATA_ZF_SHORT, /* 16-bit integer. */
- RDATA_ZF_LONG, /* 32-bit integer. */
- RDATA_ZF_LONGLONG, /* 64-bit integer. */
- RDATA_ZF_A, /* 32-bit IPv4 address. */
- RDATA_ZF_AAAA, /* 128-bit IPv6 address. */
- RDATA_ZF_RRTYPE, /* RR type. */
- RDATA_ZF_ALGORITHM, /* Cryptographic algorithm. */
- RDATA_ZF_CERTIFICATE_TYPE,
- RDATA_ZF_PERIOD, /* Time period. */
- RDATA_ZF_TIME,
- RDATA_ZF_BASE64, /* Base-64 binary data. */
- RDATA_ZF_BASE32, /* Base-32 binary data. */
- RDATA_ZF_HEX, /* Hexadecimal binary data. */
- RDATA_ZF_HEX_LEN, /* Hexadecimal binary data. Skip initial length byte. */
- RDATA_ZF_NSAP, /* NSAP. */
- RDATA_ZF_APL, /* APL. */
- RDATA_ZF_IPSECGATEWAY, /* IPSECKEY gateway ip4, ip6 or dname. */
- RDATA_ZF_SERVICES, /* Protocol and port number bitmap. */
- RDATA_ZF_NXT, /* NXT type bitmap. */
- RDATA_ZF_NSEC, /* NSEC type bitmap. */
- RDATA_ZF_LOC, /* Location data. */
- RDATA_ZF_ILNP64, /* 64-bit uncompressed IPv6 address. */
- RDATA_ZF_EUI48, /* EUI48 address. */
- RDATA_ZF_EUI64, /* EUI64 address. */
- RDATA_ZF_LONG_TEXT, /* Long (>255) text string. */
- RDATA_ZF_UNQUOTED, /* Unquoted text string. */
- RDATA_ZF_UNQUOTEDS, /* A sequence of unquoted text strings. */
- RDATA_ZF_TAG, /* A sequence of letters and numbers. */
- RDATA_ZF_SVCPARAM, /* SvcParam <key>[=<value>] */
- RDATA_ZF_HIP, /* HIP rdata up to the Rendezvous Servers */
- RDATA_ZF_ATMA, /* ATM Address */
- RDATA_ZF_AMTRELAY_D_TYPE,/* Discovery Optional and Type */
- RDATA_ZF_AMTRELAY_RELAY,/* ip4, ip6, dname or nothing */
- RDATA_ZF_UNKNOWN /* Unknown data. */
+typedef int32_t(*nsd_rdata_field_length_type)(
+ uint16_t rdlength,
+ const uint8_t *rdata,
+ uint16_t offset,
+ struct domain** domain);
+
+typedef struct nsd_rdata_descriptor nsd_rdata_descriptor_type;
+
+/*
+ * Descriptor table. For DNS RRTypes has information on the resource record
+ * type. the descriptor table shouldn't be used for validation.
+ * the read function will take care of that. it's used for
+ * implementing copy functions that are very specific, but where
+ * the data has already been checked for validity.
+ */
+struct nsd_rdata_descriptor {
+ /* Field name of the rdata, like 'primary server'. */
+ const char *name;
+
+ /* If the field is optional. When the field is not present, eg. no
+ * bytes of rdata, and it is optional, this is fine and the rdata
+ * is shorter. Also no following rdatas after it. Non optional
+ * rdatas must be present. */
+ int is_optional;
+
+ /* The length, in bytes, of the rdata field. Can be set to
+ * a specialized value, like RDATA_COMPRESSED_DNAME,
+ * RDATA_STRING, ..., if there is a length function, that is used.
+ * That is for any type where the length depends on a value in
+ * the rdata itself. */
+ int32_t length;
+
+ /* Determine size of rdata field. Returns the size of uncompressed
+ * rdata on the wire, or -1 on failure, like when it is malformed.
+ * So for references this is a different number. Used for ipseckey
+ * gateway, because the type depends on earlier data. Also amtrelay
+ * relay. This function takes the in-memory rdata representation.
+ * If the field has a special object, return -1 on failure or the
+ * length of the object in the rdata, with domain ptr returned to
+ * the special object. */
+ nsd_rdata_field_length_type calculate_length;
+
+ /* Determine size of rdata field. Like calculate_length, but this
+ * function takes uncompressed wireformat in the rdata that is passed.
+ */
+ nsd_rdata_field_length_type calculate_length_uncompressed_wire;
};
-typedef enum rdata_zoneformat rdata_zoneformat_type;
-struct rrtype_descriptor
-{
- uint16_t type; /* RR type */
- const char *name; /* Textual name. */
- uint32_t minimum; /* Minimum number of RDATAs. */
- uint32_t maximum; /* Maximum number of RDATAs. */
- uint8_t wireformat[MAXRDATALEN]; /* rdata_wireformat_type */
- uint8_t zoneformat[MAXRDATALEN]; /* rdata_zoneformat_type */
+typedef struct nsd_type_descriptor nsd_type_descriptor_type;
+struct nsd_type_descriptor;
+
+/* The rdata is malformed. The wireformat is not correct.
+ * NSD cannot store a wireformat with a malformed domain name, when that
+ * name needs to become a reference to struct domain. */
+#define MALFORMED -1
+/* The rdata is not read, it is truncated, some was copied, but then
+ * an error occurred, like memory allocation failure. */
+#define TRUNCATED -2
+
+/*
+ * Function signature to read rdata. From a packet into memory.
+ * @param domains: the domain table.
+ * @param rdlength: the length of the rdata in the packet.
+ * @param packet: the packet.
+ * @param rr: an RR is returned.
+ * @return the number of bytes that are read from the packet. Or negative
+ * for an error, like MALFORMED, TRUNCATED.
+ */
+typedef int32_t(*nsd_read_rdata_type)(
+ struct domain_table *domains,
+ uint16_t rdlength,
+ struct buffer *packet,
+ struct rr **rr);
+
+/*
+ * Function signature to write rdata. From memory to an answer.
+ * @param query: the query that is answered.
+ * @param rr: rr to add to the output, in query.packet. It prints the rdata
+ * wireformat to the packet, compressed if needed, not including the
+ * rdlength before the rdata.
+ */
+typedef void(*nsd_write_rdata_type)(
+ struct query *query,
+ const struct rr *rr);
+
+/*
+ * Function signature to print rdata. The string is in the buffer.
+ * The printed string starts with the rdata text. It does not have a newline
+ * at end. No space is put before it.
+ * @param output: buffer with string on return. The position is moved.
+ * @param rr: the record to print the rdata for.
+ * @return false on failure. The wireformat can not be printed in the
+ * nice output format.
+ */
+typedef int(*nsd_print_rdata_type)(
+ struct buffer *output,
+ const struct rr *rr);
+
+/*
+ * Descriptor for a DNS resource record type.
+ * There are conversion routines per type, for wire-to-internal,
+ * internal-to-wire, and internal-to-text. To stop an explosion in code,
+ * there is an rdata field descriptor array to convert between more formats.
+ * For internal to compressed wire format we implement a specialized routine so
+ * that answering of queries is as optimal as can be.
+ * Other formats are conversion from uncompressed wire format to compressed
+ * wire format. For conversion from uncompressed or compressed wire format
+ * to internal the same import routines can be used, by using a packet buffer
+ * and dname_make_from_packet.
+ */
+struct nsd_type_descriptor {
+ /* The RRType number */
+ uint16_t type;
+ /* Mnemonic. */
+ const char *name;
+ /* Whether internal RDATA contains direct pointers.
+ * This means the namedb memory contains an in line pointer to
+ * struct domain for domain names. */
+ int has_references;
+ /* Whether RDATA contains compressible names. The output can be
+ * compressed on the packet. If true, also has_references is true,
+ * for the packet encode routine, that uses the references. */
+ int is_compressible;
+ /* The type has domain names, like literal dnames in the format. */
+ int has_dnames;
+ /* Read function that copies rdata for this type to struct rr. */
+ nsd_read_rdata_type read_rdata;
+ /* Write function, that copies rdata from struct rr to packet. */
+ nsd_write_rdata_type write_rdata;
+ /* Print function, that writes the struct rr to string. */
+ nsd_print_rdata_type print_rdata;
+ /* Description of the rdata fields. Used by functions that need
+ * to iterate over the fields. There are binary fields and
+ * references, and wireformat domain names. */
+ struct {
+ /* Length of the fields array. */
+ size_t length;
+ /* The rdata field descriptors. */
+ const nsd_rdata_descriptor_type *fields;
+ } rdata;
};
-typedef struct rrtype_descriptor rrtype_descriptor_type;
+
+/* The length of the RRTYPE descriptors arrary */
+#define RRTYPE_DESCRIPTORS_LENGTH (TYPE_IPN + 2)
/*
* Indexed by type. The special type "0" can be used to get a
* descriptor for unknown types (with one binary rdata).
- *
- * CLA + 1
*/
-#define RRTYPE_DESCRIPTORS_LENGTH (TYPE_IPN + 1)
-rrtype_descriptor_type *rrtype_descriptor_by_name(const char *name);
-rrtype_descriptor_type *rrtype_descriptor_by_type(uint16_t type);
+static inline const nsd_type_descriptor_type *nsd_type_descriptor(
+ uint16_t rrtype);
const char *rrtype_to_string(uint16_t rrtype);
@@ -317,5 +421,20 @@ uint16_t rrtype_from_string(const char *
const char *rrclass_to_string(uint16_t rrclass);
uint16_t rrclass_from_string(const char *name);
+
+/* The type descriptors array of length RRTYPE_DESCRIPTORS_LENGTH. */
+extern const nsd_type_descriptor_type type_descriptors[];
+
+static inline const nsd_type_descriptor_type *
+nsd_type_descriptor(uint16_t rrtype)
+{
+ if (rrtype <= TYPE_IPN)
+ return &type_descriptors[rrtype];
+ if (rrtype == TYPE_TA)
+ return &type_descriptors[TYPE_IPN + 1];
+ if (rrtype == TYPE_DLV)
+ return &type_descriptors[TYPE_IPN + 2];
+ return &type_descriptors[0];
+}
#endif /* DNS_H */
Index: install-sh
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/install-sh,v
diff -u -p -r1.3 install-sh
--- install-sh 6 Sep 2025 17:41:37 -0000 1.3
+++ install-sh 18 Mar 2026 20:44:03 -0000
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2023-11-23.18; # UTC
+scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -124,9 +124,9 @@ it's up to you to specify -f if you want
If -S is not specified, no backups are attempted.
-Report bugs to <bug-automake@gnu.org>.
-GNU Automake home page: <https://www.gnu.org/software/automake/>.
-General help using GNU software: <https://www.gnu.org/gethelp/>."
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
+"
while test $# -ne 0; do
case $1 in
Index: ixfr.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/ixfr.c,v
diff -u -p -r1.5 ixfr.c
--- ixfr.c 6 Sep 2025 17:41:37 -0000 1.5
+++ ixfr.c 18 Mar 2026 20:44:03 -0000
@@ -185,34 +185,6 @@ static void pktcompression_insert_with_l
}
}
-/* calculate length of dname in uncompressed wireformat in buffer */
-static size_t dname_length(const uint8_t* buf, size_t len)
-{
- size_t l = 0;
- if(!buf || len == 0)
- return l;
- while(len > 0 && buf[0] != 0) {
- size_t lablen = (size_t)(buf[0]);
- if( (lablen&0xc0) )
- return 0; /* the name should be uncompressed */
- if(lablen+1 > len)
- return 0; /* should fit in the buffer */
- l += lablen+1;
- len -= lablen+1;
- buf += lablen+1;
- if(l > MAXDOMAINLEN)
- return 0;
- }
- if(len == 0)
- return 0; /* end label should fit in buffer */
- if(buf[0] != 0)
- return 0; /* must end in root label */
- l += 1; /* for the end root label */
- if(l > MAXDOMAINLEN)
- return 0;
- return l;
-}
-
/* write a compressed domain name into the packet,
* returns uncompressed wireformat length,
* 0 if it does not fit and -1 on failure, bad dname. */
@@ -220,7 +192,7 @@ static int pktcompression_write_dname(st
struct pktcompression* pcomp, const uint8_t* rr, size_t rrlen)
{
size_t wirelen = 0;
- size_t dname_len = dname_length(rr, rrlen);
+ size_t dname_len = buf_dname_length(rr, rrlen);
if(!rr || rrlen == 0 || dname_len == 0)
return 0;
while(rrlen > 0 && rr[0] != 0) {
@@ -263,6 +235,118 @@ static int pktcompression_write_dname(st
return wirelen;
}
+static int ixfr_write_rdata_pkt(struct buffer* packet, uint16_t tp,
+ struct pktcompression* pcomp, const uint8_t* rr, size_t rdlen)
+{
+ const struct nsd_type_descriptor* descriptor = nsd_type_descriptor(tp);
+ size_t i;
+ uint16_t offset; /* The offset in rr. */
+
+ /* The rr points at the start of the rdata of length rdlen.
+ * This is uncompressed wireformat. */
+
+ if(!descriptor->is_compressible) {
+ if(!buffer_available(packet, rdlen))
+ return 0;
+ buffer_write(packet, rr, rdlen);
+ return 1;
+ }
+
+ /* It is compressible, loop over the fields and write compressed
+ * domain names, when the rdata has a compressible name. */
+ offset = 0;
+ for(i=0; i < descriptor->rdata.length; i++) {
+ const nsd_rdata_descriptor_type* field =
+ &descriptor->rdata.fields[i];
+ uint16_t field_len = 0;
+ int already_written = 0;
+ if(rdlen == offset && field->is_optional)
+ break; /* There are no more rdata fields. */
+ if(field->calculate_length_uncompressed_wire) {
+ /* Call field length function. */
+ /* This is called with an uncompressed wireformat
+ * data buffer, instead of the in-memory data buffer.
+ * For IPSECKEY it does not matter, since it has
+ * a literal dname storage. */
+ struct domain* domain;
+ int32_t l = field->calculate_length_uncompressed_wire(
+ rdlen, rr, offset, &domain);
+ if(l < 0)
+ return 1; /* attempt to skip malformed rr */
+ field_len = l;
+ if(domain) {
+ /* Treat as uncompressed dname, to be safe. */
+ /* Write as an uncompressed name. */
+ if(!buffer_available(packet,
+ domain_dname(domain)->name_size))
+ return 0;
+ buffer_write(packet,
+ dname_name(domain_dname(domain)),
+ domain_dname(domain)->name_size);
+ already_written = 1;
+ }
+ } else if(field->length >= 0) {
+ field_len = field->length;
+ } else {
+ size_t dlen;
+ int dname_len;
+ switch(field->length) {
+ /* The dnames are stored in uncompressed
+ * wireformat in the uncompressed wireformat
+ * string. */
+ case RDATA_COMPRESSED_DNAME:
+ /* Attempt to compress the compressible
+ * name. */
+ dname_len = pktcompression_write_dname(packet,
+ pcomp, rr+offset, rdlen-offset);
+ if(dname_len == -1)
+ return 1; /* attempt to skip malformed rr */
+ if(dname_len == 0)
+ return 0;
+ field_len = dname_len;
+ already_written = 1;
+ break;
+ case RDATA_UNCOMPRESSED_DNAME:
+ case RDATA_LITERAL_DNAME:
+ /* Write as an uncompressed name. */
+ if(rdlen-offset<1)
+ return 1; /* attempt to skip malformed rr */
+ dlen = buf_dname_length(rr+offset,
+ rdlen-offset);
+ if(dlen == 0)
+ return 1; /* attempt to skip malformed rr */
+ field_len = dlen;
+ break;
+ case RDATA_STRING:
+ case RDATA_BINARY:
+ if(rdlen-offset<1)
+ return 1; /* attempt to skip malformed rr */
+ field_len = ((uint16_t)(rr+offset)[0]) + 1;
+ break;
+ case RDATA_IPSECGATEWAY:
+ case RDATA_AMTRELAY_RELAY:
+ /* This should have called the callback. */
+ return 1; /* attempt to skip malformed rr */
+ case RDATA_REMAINDER:
+ field_len = rdlen - offset;
+ break;
+ default:
+ /* Unknown specialized value. */
+ return 1; /* attempt to skip malformed rr */
+ }
+ }
+ if((size_t)offset+field_len > rdlen)
+ return 1; /* attempt to skip malformed rr */
+ if(!already_written) {
+ if(!buffer_available(packet, field_len))
+ return 0;
+ buffer_write(packet, rr+offset, field_len);
+ }
+ offset += field_len;
+ }
+ return 1;
+}
+
/* write an RR into the packet with compression for domain names,
* return 0 and resets position if it does not fit in the packet. */
static int ixfr_write_rr_pkt(struct query* query, struct buffer* packet,
@@ -274,8 +358,6 @@ static int ixfr_write_rr_pkt(struct quer
uint16_t tp;
int dname_len;
size_t rdlen;
- size_t i;
- rrtype_descriptor_type* descriptor;
if(total_added == 0) {
size_t oldmaxlen = query->maxlen;
@@ -325,100 +407,11 @@ static int ixfr_write_rr_pkt(struct quer
return 1; /* attempt to skip this malformed rr, could assert */
/* rdata */
- descriptor = rrtype_descriptor_by_type(tp);
- for(i=0; i<descriptor->maximum; i++) {
- size_t copy_len = 0;
- if(rdlen == 0)
- break;
-
- switch(rdata_atom_wireformat_type(tp, i)) {
- case RDATA_WF_COMPRESSED_DNAME:
- dname_len = pktcompression_write_dname(packet, pcomp,
- rr, rdlen);
- if(dname_len == -1)
- return 1; /* attempt to skip malformed rr */
- if(dname_len == 0) {
- buffer_set_position(packet, oldpos);
- return 0;
- }
- rr += dname_len;
- rdlen -= dname_len;
- break;
- case RDATA_WF_UNCOMPRESSED_DNAME:
- case RDATA_WF_LITERAL_DNAME:
- copy_len = rdlen;
- break;
- case RDATA_WF_BYTE:
- copy_len = 1;
- break;
- case RDATA_WF_SHORT:
- copy_len = 2;
- break;
- case RDATA_WF_LONG:
- copy_len = 4;
- break;
- case RDATA_WF_LONGLONG:
- copy_len = 8;
- break;
- case RDATA_WF_TEXTS:
- case RDATA_WF_LONG_TEXT:
- copy_len = rdlen;
- break;
- case RDATA_WF_TEXT:
- case RDATA_WF_BINARYWITHLENGTH:
- copy_len = 1;
- if(rdlen > copy_len)
- copy_len += rr[0];
- break;
- case RDATA_WF_A:
- copy_len = 4;
- break;
- case RDATA_WF_AAAA:
- copy_len = 16;
- break;
- case RDATA_WF_ILNP64:
- copy_len = 8;
- break;
- case RDATA_WF_EUI48:
- copy_len = EUI48ADDRLEN;
- break;
- case RDATA_WF_EUI64:
- copy_len = EUI64ADDRLEN;
- break;
- case RDATA_WF_BINARY:
- copy_len = rdlen;
- break;
- case RDATA_WF_APL:
- copy_len = (sizeof(uint16_t) /* address family */
- + sizeof(uint8_t) /* prefix */
- + sizeof(uint8_t)); /* length */
- if(copy_len <= rdlen)
- copy_len += (rr[copy_len-1]&APL_LENGTH_MASK);
- break;
- case RDATA_WF_IPSECGATEWAY:
- copy_len = rdlen;
- break;
- case RDATA_WF_SVCPARAM:
- copy_len = 4;
- if(copy_len <= rdlen)
- copy_len += read_uint16(rr+2);
- break;
- default:
- copy_len = rdlen;
- break;
- }
- if(copy_len) {
- if(!buffer_available(packet, copy_len)) {
- buffer_set_position(packet, oldpos);
- return 0;
- }
- if(copy_len > rdlen)
- return 1; /* assert of skip malformed */
- buffer_write(packet, rr, copy_len);
- rr += copy_len;
- rdlen -= copy_len;
- }
+ if(!ixfr_write_rdata_pkt(packet, tp, pcomp, rr, rdlen)) {
+ buffer_set_position(packet, oldpos);
+ return 0;
}
+
/* write compressed rdata length */
buffer_write_u16_at(packet, rdpos, buffer_position(packet)-rdpos-2);
if(total_added == 0) {
@@ -486,14 +479,18 @@ static int parse_qserial(struct buffer*
return 0;
}
+/* get serial from SOA rdata */
+static uint32_t soa_rdata_get_serial(uint8_t* rdata, uint16_t rdlength)
+{
+ if(rdlength < 2*sizeof(void*) /* name ptr */ + 4 /* serial */)
+ return 0;
+ return read_uint32(rdata+2*sizeof(void*));
+}
+
/* get serial from SOA RR */
static uint32_t soa_rr_get_serial(struct rr* rr)
{
- if(rr->rdata_count < 3)
- return 0;
- if(rr->rdatas[2].data[0] < 4)
- return 0;
- return read_uint32(&rr->rdatas[2].data[1]);
+ return soa_rdata_get_serial(rr->rdata, rr->rdlength);
}
/* get the current serial from the zone */
@@ -503,11 +500,7 @@ uint32_t zone_get_current_serial(struct
return 0;
if(zone->soa_rrset->rr_count == 0)
return 0;
- if(zone->soa_rrset->rrs[0].rdata_count < 3)
- return 0;
- if(zone->soa_rrset->rrs[0].rdatas[2].data[0] < 4)
- return 0;
- return read_uint32(&zone->soa_rrset->rrs[0].rdatas[2].data[1]);
+ return soa_rr_get_serial(zone->soa_rrset->rrs[0]);
}
/* iterator over ixfr data. find first element, eg. oldest zone version
@@ -811,8 +804,8 @@ query_state_type query_ixfr(struct nsd *
query_add_compression_domain(query, zone->apex,
QHEADERSZ);
if(packet_encode_rr(query, zone->apex,
- &zone->soa_rrset->rrs[0],
- zone->soa_rrset->rrs[0].ttl)) {
+ zone->soa_rrset->rrs[0],
+ zone->soa_rrset->rrs[0]->ttl)) {
ANCOUNT_SET(query->packet, 1);
} else {
RCODE_SET(query->packet, RCODE_SERVFAIL);
@@ -1089,7 +1082,7 @@ void ixfr_store_finish(struct ixfr_store
}
/* read SOA rdata section for SOA storage */
-static int read_soa_rdata(struct buffer* packet, uint8_t* primns,
+static int read_soa_rdata_fields(struct buffer* packet, uint8_t* primns,
int* primns_len, uint8_t* email, int* email_len,
uint32_t* serial, uint32_t* refresh, uint32_t* retry,
uint32_t* expire, uint32_t* minimum, size_t* sz)
@@ -1178,7 +1171,7 @@ void ixfr_store_add_newsoa(struct ixfr_s
buffer_set_position(packet, oldpos);
return;
}
- if(!read_soa_rdata(packet, primns, &primns_len, email, &email_len,
+ if(!read_soa_rdata_fields(packet, primns, &primns_len, email, &email_len,
&serial, &refresh, &retry, &expire, &minimum, &sz)) {
log_msg(LOG_ERR, "ixfr_store newsoa: cannot parse packet");
ixfr_store_cancel(ixfr_store);
@@ -1232,7 +1225,7 @@ void ixfr_store_add_oldsoa(struct ixfr_s
buffer_set_position(packet, oldpos);
return;
}
- if(!read_soa_rdata(packet, primns, &primns_len, email, &email_len,
+ if(!read_soa_rdata_fields(packet, primns, &primns_len, email, &email_len,
&serial, &refresh, &retry, &expire, &minimum, &sz)) {
log_msg(LOG_ERR, "ixfr_store oldsoa: cannot parse packet");
ixfr_store_cancel(ixfr_store);
@@ -1253,25 +1246,21 @@ void ixfr_store_add_oldsoa(struct ixfr_s
buffer_set_position(packet, oldpos);
}
-/* store RR in data segment */
-static int ixfr_putrr(const struct dname* dname, uint16_t type, uint16_t klass,
- uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num,
- uint8_t** rrs, size_t* rrs_len, size_t* rrs_capacity)
+/* store RR in data segment.
+ * return -1 on fail of wireformat, 0 on allocate failure, or 1 success. */
+static int ixfr_putrr(const rr_type* rr, uint8_t** rrs, size_t* rrs_len,
+ size_t* rrs_capacity)
{
- size_t rdlen_uncompressed, sz;
+ int32_t rdlen_uncompressed;
+ size_t sz;
uint8_t* sp;
- int i;
+ const dname_type* dname;
- /* find rdatalen */
- rdlen_uncompressed = 0;
- for(i=0; i<rdata_num; i++) {
- if(rdata_atom_is_domain(type, i)) {
- rdlen_uncompressed += domain_dname(rdatas[i].domain)
- ->name_size;
- } else {
- rdlen_uncompressed += rdatas[i].data[0];
- }
- }
+ rdlen_uncompressed = rr_calculate_uncompressed_rdata_length(rr);
+ if (rdlen_uncompressed < 0)
+ return -1; /* malformed */
+
+ dname = domain_dname(rr->owner);
sz = dname->name_size + 2 /*type*/ + 2 /*class*/ + 4 /*ttl*/ +
2 /*rdlen*/ + rdlen_uncompressed;
@@ -1285,36 +1274,18 @@ static int ixfr_putrr(const struct dname
*rrs_len += sz;
memmove(sp, dname_name(dname), dname->name_size);
sp += dname->name_size;
- write_uint16(sp, type);
- sp += 2;
- write_uint16(sp, klass);
- sp += 2;
- write_uint32(sp, ttl);
- sp += 4;
- write_uint16(sp, rdlen_uncompressed);
- sp += 2;
- for(i=0; i<rdata_num; i++) {
- if(rdata_atom_is_domain(type, i)) {
- memmove(sp, dname_name(domain_dname(rdatas[i].domain)),
- domain_dname(rdatas[i].domain)->name_size);
- sp += domain_dname(rdatas[i].domain)->name_size;
- } else {
- memmove(sp, &rdatas[i].data[1], rdatas[i].data[0]);
- sp += rdatas[i].data[0];
- }
- }
+ write_uint16(sp, rr->type);
+ write_uint16(sp + 2, rr->klass);
+ write_uint32(sp + 4, rr->ttl);
+ write_uint16(sp + 8, rdlen_uncompressed);
+ rr_write_uncompressed_rdata(rr, sp+10, rdlen_uncompressed);
return 1;
}
-void ixfr_store_putrr(struct ixfr_store* ixfr_store, const struct dname* dname,
- uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
- uint16_t rrlen, struct region* temp_region, uint8_t** rrs,
- size_t* rrs_len, size_t* rrs_capacity)
+void ixfr_store_putrr(struct ixfr_store* ixfr_store, const rr_type* rr,
+ uint8_t** rrs, size_t* rrs_len, size_t* rrs_capacity)
{
- domain_table_type *temptable;
- rdata_atom_type *rdatas;
- ssize_t rdata_num;
- size_t oldpos;
+ int code;
if(ixfr_store->cancelled)
return;
@@ -1322,7 +1293,7 @@ void ixfr_store_putrr(struct ixfr_store*
/* The SOA data is stored with separate calls. And then appended
* during the finish operation. We do not have to store it here
* when called from difffile's IXFR processing with type SOA. */
- if(type == TYPE_SOA)
+ if(rr->type == TYPE_SOA)
return;
/* make space for these RRs we have now; basically once we
* grow beyond the current allowed amount an older IXFR is deleted. */
@@ -1331,76 +1302,57 @@ void ixfr_store_putrr(struct ixfr_store*
if(ixfr_store->cancelled)
return;
- /* parse rdata */
- oldpos = buffer_position(packet);
- temptable = domain_table_create(temp_region);
- rdata_num = rdata_wireformat_to_rdata_atoms(temp_region, temptable,
- type, rrlen, packet, &rdatas);
- buffer_set_position(packet, oldpos);
- if(rdata_num == -1) {
- log_msg(LOG_ERR, "ixfr_store addrr: cannot parse packet");
- ixfr_store_cancel(ixfr_store);
- return;
- }
+ /* store rdata */
+ code = ixfr_putrr(rr, rrs, rrs_len, rrs_capacity);
- if(!ixfr_putrr(dname, type, klass, ttl, rdatas, rdata_num,
- rrs, rrs_len, rrs_capacity)) {
- log_msg(LOG_ERR, "ixfr_store addrr: cannot allocate space");
+ if (code <= 0) {
+ if (code == -1)
+ log_msg(LOG_ERR, "ixfr_store addrr: cannot parse rdata format");
+ else
+ log_msg(LOG_ERR, "ixfr_store addrr: cannot allocate space");
ixfr_store_cancel(ixfr_store);
return;
}
}
-void ixfr_store_delrr(struct ixfr_store* ixfr_store, const struct dname* dname,
- uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
- uint16_t rrlen, struct region* temp_region)
+void ixfr_store_delrr(struct ixfr_store* ixfr_store, const rr_type* rr)
{
if(ixfr_store->cancelled)
return;
- ixfr_store_putrr(ixfr_store, dname, type, klass, ttl, packet, rrlen,
- temp_region, &ixfr_store->data->del,
+ ixfr_store_putrr(ixfr_store, rr, &ixfr_store->data->del,
&ixfr_store->data->del_len, &ixfr_store->del_capacity);
}
-void ixfr_store_addrr(struct ixfr_store* ixfr_store, const struct dname* dname,
- uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
- uint16_t rrlen, struct region* temp_region)
+void ixfr_store_addrr(struct ixfr_store* ixfr_store, const rr_type* rr)
{
if(ixfr_store->cancelled)
return;
- ixfr_store_putrr(ixfr_store, dname, type, klass, ttl, packet, rrlen,
- temp_region, &ixfr_store->data->add,
+ ixfr_store_putrr(ixfr_store, rr, &ixfr_store->data->add,
&ixfr_store->data->add_len, &ixfr_store->add_capacity);
}
-int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store,
- const struct dname* dname, uint16_t type, uint16_t klass,
- uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num)
+int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store, const rr_type *rr)
{
if(ixfr_store->cancelled)
return 1;
- if(type == TYPE_SOA)
+ if(rr->type == TYPE_SOA)
return 1;
- return ixfr_putrr(dname, type, klass, ttl, rdatas, rdata_num,
- &ixfr_store->data->add, &ixfr_store->data->add_len,
- &ixfr_store->add_capacity);
+ if(ixfr_putrr(rr, &ixfr_store->data->add, &ixfr_store->data->add_len,
+ &ixfr_store->add_capacity) <= 0)
+ return 0;
+ return 1;
}
int ixfr_store_add_newsoa_rdatas(struct ixfr_store* ixfr_store,
- const struct dname* dname, uint16_t type, uint16_t klass,
- uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num)
+ const rr_type* rr)
{
size_t capacity = 0;
- uint32_t serial;
if(ixfr_store->cancelled)
return 1;
- if(rdata_num < 2 || rdata_atom_size(rdatas[2]) < 4)
+ if(!retrieve_soa_rdata_serial(rr, &ixfr_store->data->newserial))
return 0;
- memcpy(&serial, rdata_atom_data(rdatas[2]), sizeof(serial));
- ixfr_store->data->newserial = ntohl(serial);
- if(!ixfr_putrr(dname, type, klass, ttl, rdatas, rdata_num,
- &ixfr_store->data->newsoa, &ixfr_store->data->newsoa_len,
- &ixfr_store->add_capacity))
+ if(ixfr_putrr(rr, &ixfr_store->data->newsoa,
+ &ixfr_store->data->newsoa_len, &ixfr_store->add_capacity) <= 0)
return 0;
ixfr_trim_capacity(&ixfr_store->data->newsoa,
&ixfr_store->data->newsoa_len, &capacity);
@@ -1475,27 +1427,26 @@ int ixfr_store_oldsoa_uncompressed(struc
uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
uint32_t ttl, uint8_t* rdata, size_t rdata_len)
{
- size_t capacity = 0;
+ uint32_t serial;
+ size_t capacity = 0, index, count;
if(ixfr_store->cancelled)
return 1;
if(!ixfr_storerr_uncompressed(dname, dname_len, type, klass,
ttl, rdata, rdata_len, &ixfr_store->data->oldsoa,
&ixfr_store->data->oldsoa_len, &capacity))
return 0;
- {
- uint32_t serial;
- size_t index, count = 0;
- if (!(count = skip_dname(rdata, rdata_len)))
- return 0;
- index = count;
- if (!(count = skip_dname(rdata+index, rdata_len-index)))
- return 0;
- index += count;
- if (rdata_len - index < 4)
- return 0;
- memcpy(&serial, rdata+index, sizeof(serial));
- ixfr_store->data->oldserial = ntohl(serial);
- }
+
+ if (!(count = skip_dname(rdata, rdata_len)))
+ return 0;
+ index = count;
+ if (!(count = skip_dname(rdata+index, rdata_len-index)))
+ return 0;
+ index += count;
+ if (rdata_len - index < 4)
+ return 0;
+ memcpy(&serial, rdata+index, sizeof(serial));
+ ixfr_store->data->oldserial = ntohl(serial);
+
ixfr_trim_capacity(&ixfr_store->data->oldsoa,
&ixfr_store->data->oldsoa_len, &capacity);
return 1;
@@ -1982,45 +1933,20 @@ static int ixfr_write_file_header(struct
return 1;
}
-/* print rdata on one line */
-static int
-oneline_print_rdata(buffer_type *output, rrtype_descriptor_type *descriptor,
- rr_type* record)
-{
- size_t i;
- size_t saved_position = buffer_position(output);
-
- for (i = 0; i < record->rdata_count; ++i) {
- if (i == 0) {
- buffer_printf(output, "\t");
- } else {
- buffer_printf(output, " ");
- }
- if (!rdata_atom_to_string(
- output,
- (rdata_zoneformat_type) descriptor->zoneformat[i],
- record->rdatas[i], record))
- {
- buffer_set_position(output, saved_position);
- return 0;
- }
- }
-
- return 1;
-}
-
/* parse wireformat RR into a struct RR in temp region */
static int parse_wirerr_into_temp(struct zone* zone, char* fname,
struct region* temp, uint8_t* buf, size_t len,
- const dname_type** dname, struct rr* rr)
+ const dname_type** dname, struct rr** rr)
{
size_t bufpos = 0;
- uint16_t rdlen;
- ssize_t rdata_num;
+ uint16_t rdlen, tp, klass;
+ uint32_t ttl;
+ int32_t code;
+ const struct nsd_type_descriptor *descriptor;
buffer_type packet;
domain_table_type* owners;
+ struct domain *domain;
owners = domain_table_create(temp);
- memset(rr, 0, sizeof(*rr));
*dname = dname_make(temp, buf, 1);
if(!*dname) {
log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: failed to parse dname", zone->opts->name, fname);
@@ -2031,11 +1957,11 @@ static int parse_wirerr_into_temp(struct
log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: buffer too short", zone->opts->name, fname);
return 0;
}
- rr->type = read_uint16(buf+bufpos);
+ tp = read_uint16(buf+bufpos);
bufpos += 2;
- rr->klass = read_uint16(buf+bufpos);
+ klass = read_uint16(buf+bufpos);
bufpos += 2;
- rr->ttl = read_uint32(buf+bufpos);
+ ttl = read_uint32(buf+bufpos);
bufpos += 4;
rdlen = read_uint16(buf+bufpos);
bufpos += 2;
@@ -2043,14 +1969,20 @@ static int parse_wirerr_into_temp(struct
log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: buffer too short for rdatalen", zone->opts->name, fname);
return 0;
}
+ domain = domain_table_insert(owners, *dname);
buffer_create_from(&packet, buf+bufpos, rdlen);
- rdata_num = rdata_wireformat_to_rdata_atoms(
- temp, owners, rr->type, rdlen, &packet, &rr->rdatas);
- if(rdata_num == -1) {
- log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: cannot parse rdata", zone->opts->name, fname);
+ descriptor = nsd_type_descriptor(tp);
+ code = descriptor->read_rdata(owners, rdlen, &packet, rr);
+ if(code < 0) {
+ log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: cannot parse rdata %s %s %s", zone->opts->name, fname,
+ dname_to_string(*dname,0), rrtype_to_string(tp),
+ read_rdata_fail_str(code));
return 0;
}
- rr->rdata_count = rdata_num;
+ (*rr)->owner = domain;
+ (*rr)->type = tp;
+ (*rr)->klass = klass;
+ (*rr)->ttl = ttl;
return 1;
}
@@ -2059,16 +1991,14 @@ static int parse_wirerr_into_temp(struct
static int print_rr_oneline(struct buffer* rr_buffer, const dname_type* dname,
struct rr* rr)
{
- rrtype_descriptor_type *descriptor;
- descriptor = rrtype_descriptor_by_type(rr->type);
+ const nsd_type_descriptor_type *descriptor = nsd_type_descriptor(
+ rr->type);
buffer_printf(rr_buffer, "%s", dname_to_string(dname, NULL));
buffer_printf(rr_buffer, "\t%lu\t%s\t%s", (unsigned long)rr->ttl,
rrclass_to_string(rr->klass), rrtype_to_string(rr->type));
- if(!oneline_print_rdata(rr_buffer, descriptor, rr)) {
- if(!rdata_atoms_to_unknown_string(rr_buffer,
- descriptor, rr->rdata_count, rr->rdatas)) {
+ if (!print_rdata(rr_buffer, descriptor, rr)) {
+ if(!print_unknown_rdata(rr_buffer, descriptor, rr))
return 0;
- }
}
return 1;
}
@@ -2078,7 +2008,7 @@ static int ixfr_write_rr(struct zone* zo
uint8_t* buf, size_t len, struct region* temp, buffer_type* rr_buffer)
{
const dname_type* dname;
- struct rr rr;
+ struct rr* rr;
if(!parse_wirerr_into_temp(zone, fname, temp, buf, len, &dname, &rr)) {
region_free_all(temp);
@@ -2086,7 +2016,7 @@ static int ixfr_write_rr(struct zone* zo
}
buffer_clear(rr_buffer);
- if(!print_rr_oneline(rr_buffer, dname, &rr)) {
+ if(!print_rr_oneline(rr_buffer, dname, rr)) {
log_msg(LOG_ERR, "failed to write zone %s IXFR data %s: cannot spool RR string into buffer", zone->opts->name, fname);
region_free_all(temp);
return 0;
@@ -2316,49 +2246,32 @@ static void ixfr_temp_deldomain(struct d
static void clear_temp_table_of_rr(struct domain_table* temptable,
struct zone* tempzone, struct rr* rr)
{
-#if 0 /* clear out by removing everything, alternate for the cleanout code */
- /* clear domains from the tempzone,
- * the only domain left is the zone apex and its parents */
- domain_type* domain;
-#ifdef USE_RADIX_TREE
- struct radnode* first = radix_first(temptable->nametree);
- domain = first?(domain_type*)first->elem:NULL;
-#else
- domain = (domain_type*)rbtree_first(temptable->names_to_domains);
-#endif
- while(domain != (domain_type*)RBTREE_NULL && domain) {
- domain_type* next = domain_next(domain);
- if(domain != tempzone->apex &&
- !domain_is_subdomain(tempzone->apex, domain)) {
- domain_table_delete(temptable, domain);
- } else {
- if(!domain->parent /* is the root */ ||
- domain == tempzone->apex)
- domain->usage = 1;
- else domain->usage = 0;
- }
- domain = next;
- }
-
- if(rr->owner == tempzone->apex) {
- tempzone->apex->rrsets = NULL;
- tempzone->soa_rrset = NULL;
- tempzone->soa_nx_rrset = NULL;
- tempzone->ns_rrset = NULL;
- }
- return;
-#endif
+ const nsd_type_descriptor_type* descriptor =
+ nsd_type_descriptor(rr->type);
/* clear domains in the rdata */
- unsigned i;
- for(i=0; i<rr->rdata_count; i++) {
- if(rdata_atom_is_domain(rr->type, i)) {
- /* clear out that dname */
- struct domain* domain =
- rdata_atom_domain(rr->rdatas[i]);
- domain->usage --;
- if(domain != tempzone->apex && domain->usage == 0)
- ixfr_temp_deldomain(temptable, domain, rr->owner);
+ if(descriptor->has_references) {
+ uint16_t offset = 0;
+ size_t i;
+ for(i=0; i < descriptor->rdata.length; i++) {
+ uint16_t field_len;
+ struct domain* domain;
+ if(rr->rdlength == offset &&
+ descriptor->rdata.fields[i].is_optional)
+ break; /* There are no more rdata fields. */
+ if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
+ &field_len, &domain))
+ break; /* malformed */
+ if(domain != NULL) {
+ /* The field is a domain reference. */
+ /* clear out that dname */
+ domain->usage --;
+ if(domain != tempzone->apex &&
+ domain->usage == 0)
+ ixfr_temp_deldomain(temptable, domain,
+ rr->owner);
+ }
+ offset += field_len;
}
}
@@ -2383,6 +2296,7 @@ static int ixfr_data_readnewsoa(struct i
uint32_t dest_serial)
{
size_t capacity = 0;
+ int code;
if(rr->type != TYPE_SOA) {
zone_error(parser, "zone %s ixfr data: IXFR data does not start with SOA",
zone->opts->name);
@@ -2410,9 +2324,13 @@ static int ixfr_data_readnewsoa(struct i
dest_serial);
return 0;
}
- if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->newsoa, &data->newsoa_len, &capacity)) {
- zone_error(parser, "zone %s ixfr data: cannot allocate space",
- zone->opts->name);
+ if((code=ixfr_putrr(rr, &data->newsoa, &data->newsoa_len, &capacity))
+ <= 0) {
+ if(code == -1)
+ zone_error(parser, "zone %s ixfr data: cannot parse rdata format",
+ zone->opts->name);
+ else zone_error(parser, "zone %s ixfr data: cannot allocate space",
+ zone->opts->name);
return 0;
}
clear_temp_table_of_rr(temptable, tempzone, rr);
@@ -2449,7 +2367,7 @@ static int ixfr_data_readoldsoa(struct i
return 0;
}
data->oldserial = soa_rr_get_serial(rr);
- if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->oldsoa, &data->oldsoa_len, &capacity)) {
+ if(!ixfr_putrr(rr, &data->oldsoa, &data->oldsoa_len, &capacity)) {
zone_error(parser, "zone %s ixfr data: cannot allocate space",
zone->opts->name);
return 0;
@@ -2467,7 +2385,7 @@ static int ixfr_data_readdel(struct ixfr
struct domain_table* temptable, struct zone* tempzone)
{
size_t capacity = 0;
- if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->del, &data->del_len, &capacity)) {
+ if(!ixfr_putrr(rr, &data->del, &data->del_len, &capacity)) {
zone_error(parser, "zone %s ixdr data: cannot allocate space",
zone->opts->name);
return 0;
@@ -2491,7 +2409,7 @@ static int ixfr_data_readadd(struct ixfr
struct domain_table* temptable, struct zone* tempzone)
{
size_t capacity = 0;
- if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->add, &data->add_len, &capacity)) {
+ if(!ixfr_putrr(rr, &data->add, &data->add_len, &capacity)) {
zone_error(parser, "zone %s ixfr data: cannot allocate space",
zone->opts->name);
return 0;
@@ -2509,7 +2427,8 @@ static int ixfr_data_readadd(struct ixfr
struct ixfr_data_state {
struct zone *zone;
struct ixfr_data *data;
- struct region *tempregion, *stayregion;
+ struct region *stayregion;
+ struct region *tempregion;
struct domain_table *temptable;
struct zone *tempzone;
uint32_t *dest_serial;
@@ -2531,9 +2450,9 @@ static int32_t ixfr_data_accept(
const struct dname *dname;
struct domain *domain;
struct buffer buffer;
- union rdata_atom *rdatas;
- ssize_t rdata_count;
struct ixfr_data_state *state = (struct ixfr_data_state *)user_data;
+ const struct nsd_type_descriptor *descriptor;
+ int32_t code;
assert(parser);
@@ -2544,17 +2463,32 @@ static int32_t ixfr_data_accept(
domain = domain_table_insert(state->temptable, dname);
assert(domain);
- rdata_count = rdata_wireformat_to_rdata_atoms(
- state->tempregion, state->temptable, type, rdlength, &buffer, &rdatas);
- assert(rdata_count > 0);
- rr = region_alloc(state->tempregion, sizeof(*rr));
+ descriptor = nsd_type_descriptor(type);
+ code = descriptor->read_rdata(state->temptable, rdlength, &buffer, &rr);
+ /* This has validated the fields on the rdata. The content can be
+ * dealt with, if this is successful, later on by iterating over the
+ * rdata fields. For compression, and for printout, the rdata field
+ * format is known to be good.
+ * If the field validation is not needed, the wireformat in the
+ * rdata, rdlength could have been used to add to the ixfr store.
+ * But it is more prudent to validate the rdata fields. */
+ if(code < 0) {
+ if(verbosity >= 3) {
+ zone_log(parser, ZONE_ERROR, "the RR rdata fields are wrong for the type");
+ }
+ VERBOSITY(3, (LOG_INFO, "zone %s IXFR bad RR, cannot parse "
+ "rdata of %s %s %s", state->zone->opts->name,
+ dname_to_string(dname, NULL), rrtype_to_string(type),
+ read_rdata_fail_str(code)));
+ if(code == TRUNCATED)
+ return ZONE_OUT_OF_MEMORY;
+ return ZONE_BAD_PARAMETER;
+ }
assert(rr);
rr->owner = domain;
- rr->rdatas = rdatas;
rr->ttl = ttl;
rr->type = type;
rr->klass = class;
- rr->rdata_count = rdata_count;
if (state->rr_count == 0) {
if (!ixfr_data_readnewsoa(state->data, state->zone, rr, parser,
Index: ixfr.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/ixfr.h,v
diff -u -p -r1.3 ixfr.h
--- ixfr.h 20 Dec 2023 17:29:01 -0000 1.3
+++ ixfr.h 18 Mar 2026 20:44:03 -0000
@@ -181,21 +181,15 @@ void ixfr_store_add_newsoa(struct ixfr_s
void ixfr_store_add_oldsoa(struct ixfr_store* ixfr_store, uint32_t ttl,
struct buffer* packet, size_t rrlen);
-void ixfr_store_delrr(struct ixfr_store* ixfr_store, const struct dname* dname,
- uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
- uint16_t rrlen, struct region* temp_region);
-void ixfr_store_addrr(struct ixfr_store* ixfr_store, const struct dname* dname,
- uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet,
- uint16_t rrlen, struct region* temp_region);
-int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store,
- const struct dname* dname, uint16_t type, uint16_t klass,
- uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num);
+void ixfr_store_delrr(struct ixfr_store* ixfr_store,
+ const rr_type *rr);
+void ixfr_store_addrr(struct ixfr_store* ixfr_store, const rr_type *rr);
+int ixfr_store_addrr_rdatas(struct ixfr_store* ixfr_store, const rr_type *rr);
int ixfr_store_delrr_uncompressed(struct ixfr_store* ixfr_store,
uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
uint32_t ttl, uint8_t* rdata, size_t rdata_len);
int ixfr_store_add_newsoa_rdatas(struct ixfr_store* ixfr_store,
- const struct dname* dname, uint16_t type, uint16_t klass,
- uint32_t ttl, rdata_atom_type* rdatas, ssize_t rdata_num);
+ const rr_type* rr);
int ixfr_store_oldsoa_uncompressed(struct ixfr_store* ixfr_store,
uint8_t* dname, size_t dname_len, uint16_t type, uint16_t klass,
uint32_t ttl, uint8_t* rdata, size_t rdata_len);
Index: ixfrcreate.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/ixfrcreate.c,v
diff -u -p -r1.5 ixfrcreate.c
--- ixfrcreate.c 6 Sep 2025 17:41:37 -0000 1.5
+++ ixfrcreate.c 18 Mar 2026 20:44:03 -0000
@@ -15,6 +15,7 @@
#include "namedb.h"
#include "ixfr.h"
#include "options.h"
+#include "rdata.h"
/* spool a uint16_t to file */
static int spool_u16(FILE* out, uint16_t val)
@@ -47,44 +48,25 @@ static int spool_dname(FILE* out, dname_
return 1;
}
-/* calculate the rdatalen of an RR */
-static size_t rr_rdatalen_uncompressed(rr_type* rr)
-{
- int i;
- size_t rdlen_uncompressed = 0;
- for(i=0; i<rr->rdata_count; i++) {
- if(rdata_atom_is_domain(rr->type, i)) {
- rdlen_uncompressed += domain_dname(rr->rdatas[i].domain)
- ->name_size;
- } else {
- rdlen_uncompressed += rr->rdatas[i].data[0];
- }
- }
- return rdlen_uncompressed;
-}
-
/* spool the data for one rr into the file */
static int spool_rr_data(FILE* out, rr_type* rr)
{
- int i;
uint16_t rdlen;
+ int32_t code;
+ uint8_t buf[MAX_RDLENGTH];
if(!spool_u32(out, rr->ttl))
return 0;
- rdlen = rr_rdatalen_uncompressed(rr);
+ code = rr_calculate_uncompressed_rdata_length(rr);
+ if(code < 0)
+ return 0;
+ if((size_t)code > sizeof(buf))
+ return 0; /* Buffer too small. The buffer has max length. */
+ rdlen = (uint16_t)code;
if(!spool_u16(out, rdlen))
return 0;
- for(i=0; i<rr->rdata_count; i++) {
- if(rdata_atom_is_domain(rr->type, i)) {
- if(!fwrite(dname_name(domain_dname(
- rr->rdatas[i].domain)), domain_dname(
- rr->rdatas[i].domain)->name_size, 1, out))
- return 0;
- } else {
- if(!fwrite(&rr->rdatas[i].data[1],
- rr->rdatas[i].data[0], 1, out))
- return 0;
- }
- }
+ rr_write_uncompressed_rdata(rr, buf, rdlen);
+ if(!fwrite(buf, rdlen, 1, out))
+ return 0;
return 1;
}
@@ -94,14 +76,14 @@ static int spool_rrset(FILE* out, rrset_
int i;
if(rrset->rr_count == 0)
return 1;
- if(!spool_u16(out, rrset->rrs[0].type))
+ if(!spool_u16(out, rrset->rrs[0]->type))
return 0;
- if(!spool_u16(out, rrset->rrs[0].klass))
+ if(!spool_u16(out, rrset->rrs[0]->klass))
return 0;
if(!spool_u16(out, rrset->rr_count))
return 0;
for(i=0; i<rrset->rr_count; i++) {
- if(!spool_rr_data(out, &rrset->rrs[i]))
+ if(!spool_rr_data(out, rrset->rrs[i]))
return 0;
}
return 1;
@@ -339,31 +321,11 @@ static int process_store_oldsoa(struct i
/* see if rdata matches, true if equal */
static int rdata_match(struct rr* rr, uint8_t* rdata, uint16_t rdlen)
{
- size_t rdpos = 0;
- int i;
- for(i=0; i<rr->rdata_count; i++) {
- if(rdata_atom_is_domain(rr->type, i)) {
- if(rdpos + domain_dname(rr->rdatas[i].domain)->name_size
- > rdlen)
- return 0;
- if(memcmp(rdata+rdpos,
- dname_name(domain_dname(rr->rdatas[i].domain)),
- domain_dname(rr->rdatas[i].domain)->name_size)
- != 0)
- return 0;
- rdpos += domain_dname(rr->rdatas[i].domain)->name_size;
- } else {
- if(rdpos + rr->rdatas[i].data[0] > rdlen)
- return 0;
- if(memcmp(rdata+rdpos, &rr->rdatas[i].data[1],
- rr->rdatas[i].data[0]) != 0)
- return 0;
- rdpos += rr->rdatas[i].data[0];
- }
- }
- if(rdpos != rdlen)
- return 0;
- return 1;
+ /* The rr has in-memory representation. The rdata is uncompressed
+ * wireformat representation. */
+ const struct nsd_type_descriptor *descriptor = nsd_type_descriptor(
+ rr->type);
+ return equal_rr_rdata_uncompressed_wire(descriptor, rr, rdata, rdlen);
}
/* find an rdata in an rrset, true if found and sets index found */
@@ -372,9 +334,9 @@ static int rrset_find_rdata(struct rrset
{
int i;
for(i=0; i<rrset->rr_count; i++) {
- if(rrset->rrs[i].ttl != ttl)
+ if(rrset->rrs[i]->ttl != ttl)
continue;
- if(rdata_match(&rrset->rrs[i], rdata, rdlen)) {
+ if(rdata_match(rrset->rrs[i], rdata, rdlen)) {
*index = i;
return 1;
}
@@ -457,10 +419,7 @@ static int process_diff_rrset(FILE* spoo
continue;
}
/* not in the marked list, the RR is added */
- if(!ixfr_store_addrr_rdatas(store, domain_dname(domain),
- rrset->rrs[i].type, rrset->rrs[i].klass,
- rrset->rrs[i].ttl, rrset->rrs[i].rdatas,
- rrset->rrs[i].rdata_count)) {
+ if(!ixfr_store_addrr_rdatas(store, rrset->rrs[i])) {
log_msg(LOG_ERR, "out of memory");
return 0;
}
@@ -511,14 +470,11 @@ static int process_spool_delrrset(FILE*
/* add the rrset to the added list */
static int process_add_rrset(struct ixfr_store* ixfr_store,
- struct domain* domain, struct rrset* rrset)
+ struct rrset* rrset)
{
int i;
for(i=0; i<rrset->rr_count; i++) {
- if(!ixfr_store_addrr_rdatas(ixfr_store, domain_dname(domain),
- rrset->rrs[i].type, rrset->rrs[i].klass,
- rrset->rrs[i].ttl, rrset->rrs[i].rdatas,
- rrset->rrs[i].rdata_count)) {
+ if(!ixfr_store_addrr_rdatas(ixfr_store, rrset->rrs[i])) {
log_msg(LOG_ERR, "out of memory");
return 0;
}
@@ -543,7 +499,7 @@ static int process_marktypes(struct ixfr
/* the item is in the marked list, skip it */
continue;
}
- if(!process_add_rrset(store, domain, s))
+ if(!process_add_rrset(store, s))
return 0;
}
return 1;
@@ -615,7 +571,7 @@ static int process_domain_add_RRs(struct
for(s=domain->rrsets; s; s=s->next) {
if(s->zone != zone)
continue;
- if(!process_add_rrset(store, domain, s))
+ if(!process_add_rrset(store, s))
return 0;
}
return 1;
@@ -920,10 +876,7 @@ static int ixfr_create_store_newsoa(stru
log_msg(LOG_ERR, "error empty SOA rrset");
return 0;
}
- if(!ixfr_store_add_newsoa_rdatas(store, domain_dname(zone->apex),
- zone->soa_rrset->rrs[0].type, zone->soa_rrset->rrs[0].klass,
- zone->soa_rrset->rrs[0].ttl, zone->soa_rrset->rrs[0].rdatas,
- zone->soa_rrset->rrs[0].rdata_count)) {
+ if(!ixfr_store_add_newsoa_rdatas(store, zone->soa_rrset->rrs[0])) {
log_msg(LOG_ERR, "out of memory");
return 0;
}
Index: metrics.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/metrics.c,v
diff -u -p -r1.1.1.1 metrics.c
--- metrics.c 6 Sep 2025 17:38:33 -0000 1.1.1.1
+++ metrics.c 18 Mar 2026 20:44:03 -0000
@@ -18,6 +18,7 @@
#include <errno.h>
#include <event2/event.h>
#include <event2/http.h>
+#include <ctype.h>
#include "nsd.h"
#include "xfrd.h"
@@ -95,6 +96,7 @@ void daemon_metrics_close(struct daemon_
if (metrics->http_server) {
evhttp_free(metrics->http_server);
+ metrics->http_server = NULL;
}
}
@@ -291,6 +293,10 @@ daemon_metrics_attach(struct daemon_metr
metrics->xfrd = xfrd;
metrics->http_server = evhttp_new(xfrd->event_base);
+ if(!metrics->http_server) {
+ log_msg(LOG_ERR, "metrics: out of memory in evhttp_new");
+ return;
+ }
for(p = metrics->accept_list; p; p = p->next) {
fd = p->accept_fd;
if (evhttp_accept_socket(metrics->http_server, fd)) {
@@ -343,6 +349,22 @@ metrics_http_callback(struct evhttp_requ
}
#ifdef BIND8_STATS
+/** Change disallowed characters, '.' ':' to underscores '_'. */
+static void
+change_string_underscores(char* prefix)
+{
+ /* Prometheus does not want '.' in the metric names. But the zone
+ * statistics could have then in their name.
+ * Also ':' is not allowed. This routine enforeces that it
+ * has letters,digits,underscores. */
+ char* s = prefix;
+ while(*s) {
+ if(!isalnum((unsigned char)*s) && *s != '_')
+ *s = '_';
+ s++;
+ }
+}
+
/** print long number*/
static int
print_longnum(struct evbuffer *buf, char* desc, uint64_t x)
@@ -381,6 +403,7 @@ print_stat_block(struct evbuffer *buf, s
char prefix[512] = {0};
if (name) {
snprintf(prefix, sizeof(prefix), "nsd_zonestats_%s_", name);
+ change_string_underscores(prefix);
} else {
snprintf(prefix, sizeof(prefix), "nsd_");
}
@@ -504,10 +527,11 @@ metrics_zonestat_print_one(struct evbuff
{
char prefix[512] = {0};
snprintf(prefix, sizeof(prefix), "nsd_zonestats_%s_", name);
+ change_string_underscores(prefix);
print_metric_help_and_type(buf, prefix, "queries_total",
"Total number of queries received.", "counter");
- evbuffer_add_printf(buf, "nsd_zonestats_%s_queries_total %lu\n", name,
+ evbuffer_add_printf(buf, "%squeries_total %lu\n", prefix,
(unsigned long)(zst->qudp + zst->qudp6 + zst->ctcp +
zst->ctcp6 + zst->ctls + zst->ctls6));
print_stat_block(buf, zst, name);
Index: namedb.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/namedb.c,v
diff -u -p -r1.16 namedb.c
--- namedb.c 6 Sep 2025 17:41:37 -0000 1.16
+++ namedb.c 18 Mar 2026 20:44:03 -0000
@@ -160,7 +160,7 @@ int domain_is_prehash(domain_table_type*
void
zone_del_domain_in_hash_tree(rbtree_type* tree, rbnode_type* node)
{
- if(!node->key)
+ if(!node->key || !tree)
return;
rbtree_delete(tree, node->key);
/* note that domain is no longer in the tree */
@@ -539,6 +539,24 @@ domain_find_any_rrset(domain_type* domai
return NULL;
}
+rrset_type *
+domain_find_rrset_and_prev(domain_type* domain, zone_type* zone, uint16_t type,
+ rrset_type** prev)
+{
+ rrset_type* result = domain->rrsets, *prevp = NULL;
+
+ while (result) {
+ if (result->zone == zone && rrset_rrtype(result) == type) {
+ *prev = prevp;
+ return result;
+ }
+ prevp = result;
+ result = result->next;
+ }
+ *prev = NULL;
+ return NULL;
+}
+
zone_type *
domain_find_zone(namedb_type* db, domain_type* domain)
{
@@ -647,11 +665,11 @@ zone_is_secure(zone_type* zone)
uint16_t
rr_rrsig_type_covered(rr_type* rr)
{
+ uint16_t type;
assert(rr->type == TYPE_RRSIG);
- assert(rr->rdata_count > 0);
- assert(rdata_atom_size(rr->rdatas[0]) == sizeof(uint16_t));
-
- return ntohs(* (uint16_t *) rdata_atom_data(rr->rdatas[0]));
+ assert(rr->rdlength > 2);
+ memcpy(&type, rr->rdata, sizeof(type));
+ return ntohs(type);
}
zone_type *
@@ -721,7 +739,7 @@ rr_type *zone_rr_iter_next(struct zone_r
while(iter->rrset != NULL) {
if(iter->index < iter->rrset->rr_count) {
- return &iter->rrset->rrs[iter->index++];
+ return iter->rrset->rrs[iter->index++];
}
iter->index = 0;
if(iter->domain == NULL) {
Index: namedb.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/namedb.h,v
diff -u -p -r1.19 namedb.h
--- namedb.h 6 Sep 2025 17:41:37 -0000 1.19
+++ namedb.h 18 Mar 2026 20:44:03 -0000
@@ -23,7 +23,6 @@ struct udb_ptr;
struct nsd;
struct zone_ixfr;
-typedef union rdata_atom rdata_atom_type;
typedef struct rrset rrset_type;
typedef struct rr rr_type;
@@ -157,14 +156,25 @@ struct zone
unsigned is_bad : 1; /* zone failed verification */
} ATTR_PACKED;
-/* a RR in DNS */
+/* a RR in DNS.
+ * The RDATA is directly allocated with the RR structure and pointers to
+ * domains are directly stored (likely unaligned) in the RDATA. We do this
+ * primarily to save memory, but as the RDATA is directly stored with the RR,
+ * it is likely that data is cached with the RR which should have a positive
+ * impact on performance. When paired with direct conversion routines we are
+ * very likely to improve performance when importing zones and writing RRs out
+ * to the wire. That is in the rr.rdata array, it contains the rdata without
+ * the rdlength bytes. The rdlength contains the length of the rr.rdata array,
+ * that includes the pointer size for names that are pointer references to
+ * struct domain.
+ */
struct rr {
domain_type* owner;
- rdata_atom_type* rdatas;
uint32_t ttl;
uint16_t type;
uint16_t klass;
- uint16_t rdata_count;
+ uint16_t rdlength;
+ uint8_t rdata[]; /* c99 flexible array */
} ATTR_PACKED;
/*
@@ -175,25 +185,30 @@ struct rrset
{
rrset_type* next;
zone_type* zone;
- rr_type* rrs;
+#ifndef PACKED_STRUCTS
+ /* If the storage is not packed, there is a pointer to a separate
+ * array of rr_type pointers. This is then accessed in an aligned
+ * manner.
+ * If the storage is packed, the pointer to the array is not there.
+ * The rr_type pointers for the rrs are stored after the struct rrset,
+ * contiguously allocated. This is then unaligned pointers, as they
+ * are after the packed structure. The region also stores items when
+ * packed structs is enabled without alignment, and thus there are
+ * unaligned accesses. It then has unaligned access for like struct
+ * domain. So unaligned access is used then, here too. This saves
+ * the space used by the rr_type** rrs array pointer.
+ * The rr pointers can then be accessed through the rrs[] member and,
+ * that is an unaligned access, and does not need an accessor function.
+ */
+ rr_type** rrs;
+#endif
uint16_t rr_count;
+#ifdef PACKED_STRUCTS
+ rr_type* rrs[]; /* c99 flexible array */
+#endif
} ATTR_PACKED;
/*
- * The field used is based on the wireformat the atom is stored in.
- * The allowed wireformats are defined by the rdata_wireformat_type
- * enumeration.
- */
-union rdata_atom
-{
- /* RDATA_WF_COMPRESSED_DNAME, RDATA_WF_UNCOMPRESSED_DNAME */
- domain_type* domain;
-
- /* Default. */
- uint16_t* data;
-};
-
-/*
* Create a new domain_table containing only the root domain.
*/
domain_table_type *domain_table_create(region_type *region);
@@ -256,6 +271,8 @@ void domain_add_rrset(domain_type* domai
rrset_type* domain_find_rrset(domain_type* domain, zone_type* zone, uint16_t type);
rrset_type* domain_find_any_rrset(domain_type* domain, zone_type* zone);
+rrset_type* domain_find_rrset_and_prev(domain_type* domain, zone_type* zone,
+ uint16_t type, rrset_type** prev);
zone_type* domain_find_zone(namedb_type* db, domain_type* domain);
zone_type* domain_find_parent_zone(namedb_type* db, zone_type* zone);
@@ -345,28 +362,6 @@ struct namedb
off_t diff_pos;
};
-static inline int rdata_atom_is_domain(uint16_t type, size_t index);
-static inline int rdata_atom_is_literal_domain(uint16_t type, size_t index);
-
-static inline domain_type *
-rdata_atom_domain(rdata_atom_type atom)
-{
- return atom.domain;
-}
-
-static inline uint16_t
-rdata_atom_size(rdata_atom_type atom)
-{
- return *atom.data;
-}
-
-static inline uint8_t *
-rdata_atom_data(rdata_atom_type atom)
-{
- return (uint8_t *) (atom.data + 1);
-}
-
-
/* Find the zone for the specified dname in DB. */
zone_type *namedb_find_zone(namedb_type *db, const dname_type *dname);
/*
@@ -379,8 +374,7 @@ void domain_table_deldomain(namedb_type*
/** dbcreate.c */
int print_rrs(FILE* out, struct zone* zone);
-/** marshal rdata into buffer, must be MAX_RDLENGTH in size */
-size_t rr_marshal_rdata(rr_type* rr, uint8_t* rdata, size_t sz);
+
/* dbaccess.c */
int namedb_lookup (struct namedb* db,
const dname_type* dname,
@@ -413,40 +407,12 @@ int create_dirs(const char* path);
int file_get_mtime(const char* file, struct timespec* mtime, int* nonexist);
void allocate_domain_nsec3(domain_table_type *table, domain_type *result);
-static inline int
-rdata_atom_is_domain(uint16_t type, size_t index)
-{
- const rrtype_descriptor_type *descriptor
- = rrtype_descriptor_by_type(type);
- return (index < descriptor->maximum
- && (descriptor->wireformat[index] == RDATA_WF_COMPRESSED_DNAME
- || descriptor->wireformat[index] == RDATA_WF_UNCOMPRESSED_DNAME));
-}
-
-static inline int
-rdata_atom_is_literal_domain(uint16_t type, size_t index)
-{
- const rrtype_descriptor_type *descriptor
- = rrtype_descriptor_by_type(type);
- return (index < descriptor->maximum
- && (descriptor->wireformat[index] == RDATA_WF_LITERAL_DNAME));
-}
-
-static inline rdata_wireformat_type
-rdata_atom_wireformat_type(uint16_t type, size_t index)
-{
- const rrtype_descriptor_type *descriptor
- = rrtype_descriptor_by_type(type);
- assert(index < descriptor->maximum);
- return (rdata_wireformat_type) descriptor->wireformat[index];
-}
-
static inline uint16_t
rrset_rrtype(rrset_type* rrset)
{
assert(rrset);
assert(rrset->rr_count > 0);
- return rrset->rrs[0].type;
+ return rrset->rrs[0]->type;
}
static inline uint16_t
@@ -454,7 +420,7 @@ rrset_rrclass(rrset_type* rrset)
{
assert(rrset);
assert(rrset->rr_count > 0);
- return rrset->rrs[0].klass;
+ return rrset->rrs[0]->klass;
}
/*
Index: nsd-checkconf.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd-checkconf.8.in,v
diff -u -p -r1.45 nsd-checkconf.8.in
--- nsd-checkconf.8.in 6 Sep 2025 17:41:37 -0000 1.45
+++ nsd-checkconf.8.in 18 Mar 2026 20:44:03 -0000
@@ -1,4 +1,4 @@
-.TH "nsd\-checkconf" "8" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0"
+.TH "nsd\-checkconf" "8" "feb 24, 2026" "NLnet Labs" "nsd 4.14.1"
.\" Copyright (c) 2001\-2024, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
Index: nsd-checkzone.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd-checkzone.8.in,v
diff -u -p -r1.29 nsd-checkzone.8.in
--- nsd-checkzone.8.in 6 Sep 2025 17:41:37 -0000 1.29
+++ nsd-checkzone.8.in 18 Mar 2026 20:44:03 -0000
@@ -1,4 +1,4 @@
-.TH "nsd\-checkzone" "8" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0"
+.TH "nsd\-checkzone" "8" "feb 24, 2026" "NLnet Labs" "nsd 4.14.1"
.\" Copyright (c) 2014-2024, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
Index: nsd-control.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd-control.8.in,v
diff -u -p -r1.33 nsd-control.8.in
--- nsd-control.8.in 6 Sep 2025 17:41:37 -0000 1.33
+++ nsd-control.8.in 18 Mar 2026 20:44:03 -0000
@@ -1,4 +1,4 @@
-.TH "nsd\-control" "8" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0"
+.TH "nsd\-control" "8" "feb 24, 2026" "NLnet Labs" "nsd 4.14.1"
.\" Copyright (c) 2011-2024, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
Index: nsd-mem.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd-mem.c,v
diff -u -p -r1.9 nsd-mem.c
--- nsd-mem.c 6 Sep 2025 17:41:37 -0000 1.9
+++ nsd-mem.c 18 Mar 2026 20:44:03 -0000
@@ -10,6 +10,7 @@
#include "config.h"
#include <assert.h>
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -45,6 +46,8 @@ struct zone_mem {
size_t data;
/* unused space (in db.region) due to alignment */
size_t data_unused;
+ /* space in recycle_bin */
+ size_t recycle_bin;
/* count of number of domains */
size_t domaincount;
@@ -56,6 +59,8 @@ struct tot_mem {
size_t data;
/* unused space (in db.region) due to alignment */
size_t data_unused;
+ /* space in recycle_bin */
+ size_t recycle_bin;
/* count of number of domains */
size_t domaincount;
@@ -64,6 +69,8 @@ struct tot_mem {
size_t opt_data;
/* unused in options region */
size_t opt_unused;
+ /* space in recycle_bin */
+ size_t opt_recycle_bin;
/* dname compression table */
size_t compresstable;
#ifdef RATELIMIT
@@ -80,29 +87,55 @@ account_zone(struct namedb* db, struct z
{
zmem->data = region_get_mem(db->region);
zmem->data_unused = region_get_mem_unused(db->region);
+ zmem->recycle_bin = region_get_recycle_size(db->region);
zmem->domaincount = domain_table_count(db->domains);
}
+static char*
+pretty_num(size_t x)
+{
+ static char buf[32];
+ memset(buf, 0, sizeof(buf));
+ if(snprintf(buf, sizeof(buf), "%12lld", (long long)x) <= 12) {
+ snprintf(buf, sizeof(buf), "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ buf[0], buf[1], buf[2], (buf[2]==' '?' ':'.'),
+ buf[3], buf[4], buf[5], (buf[5]==' '?' ':'.'),
+ buf[6], buf[7], buf[8], (buf[8]==' '?' ':'.'),
+ buf[9], buf[10], buf[11]);
+ }
+ return buf;
+}
+
+static const char*
+skip_ws(const char* str)
+{
+ while (isspace(*str))
+ str++;
+ return str;
+}
+
static void
pretty_mem(size_t x, const char* s)
{
- char buf[32];
- memset(buf, 0, sizeof(buf));
- if(snprintf(buf, sizeof(buf), "%12lld", (long long)x) > 12) {
- printf("%12lld %s\n", (long long)x, s);
- return;
+ printf("%s %s\n", pretty_num(x), s);
+}
+
+static void
+pretty_mem_recycle_bin(size_t x, const char* s, size_t recycle_bin_sz)
+{
+ printf("%s %s", pretty_num(x), s);
+ if (recycle_bin_sz) {
+ printf(" (of which %s in the recycle bin)",
+ skip_ws(pretty_num(recycle_bin_sz)));
}
- printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c %s\n",
- buf[0], buf[1], buf[2], (buf[2]==' '?' ':'.'),
- buf[3], buf[4], buf[5], (buf[5]==' '?' ':'.'),
- buf[6], buf[7], buf[8], (buf[8]==' '?' ':'.'),
- buf[9], buf[10], buf[11], s);
+ printf("\n");
}
+
static void
print_zone_mem(struct zone_mem* z)
{
- pretty_mem(z->data, "zone data");
+ pretty_mem_recycle_bin(z->data, "zone data", z->recycle_bin);
pretty_mem(z->data_unused, "zone unused space (due to alignment)");
}
@@ -111,6 +144,7 @@ account_total(struct nsd_options* opt, s
{
t->opt_data = region_get_mem(opt->region);
t->opt_unused = region_get_mem_unused(opt->region);
+ t->opt_recycle_bin = region_get_recycle_size(opt->region);
t->compresstable = sizeof(uint16_t) *
(t->domaincount + 1 + EXTRA_DOMAIN_NUMBERS);
t->compresstable *= opt->server_count;
@@ -132,9 +166,9 @@ static void
print_tot_mem(struct tot_mem* t)
{
printf("\ntotal\n");
- pretty_mem(t->data, "data");
+ pretty_mem_recycle_bin(t->data, "data", t->recycle_bin);
pretty_mem(t->data_unused, "unused space (due to alignment)");
- pretty_mem(t->opt_data, "options");
+ pretty_mem_recycle_bin(t->opt_data, "options", t->opt_recycle_bin);
pretty_mem(t->opt_unused, "options unused space (due to alignment)");
pretty_mem(t->compresstable, "name table (depends on servercount)");
#ifdef RATELIMIT
@@ -150,6 +184,7 @@ add_mem(struct tot_mem* t, struct zone_m
{
t->data += z->data;
t->data_unused += z->data_unused;
+ t->recycle_bin += z->recycle_bin;
t->domaincount += z->domaincount;
}
Index: nsd.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd.8.in,v
diff -u -p -r1.47 nsd.8.in
--- nsd.8.in 6 Sep 2025 17:41:37 -0000 1.47
+++ nsd.8.in 18 Mar 2026 20:44:03 -0000
@@ -1,9 +1,9 @@
-.TH "NSD" "8" "Sep 3, 2025" "NLnet Labs" "NSD 4.13.0"
+.TH "NSD" "8" "feb 24, 2026" "NLnet Labs" "NSD 4.14.1"
.\" Copyright (c) 2001\-2024, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
.B nsd
-\- Name Server Daemon (NSD) version 4.13.0.
+\- Name Server Daemon (NSD) version 4.14.1.
.SH "SYNOPSIS"
.B nsd
.RB [ \-4 ]
Index: nsd.conf.5.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd.conf.5.in,v
diff -u -p -r1.53 nsd.conf.5.in
--- nsd.conf.5.in 6 Sep 2025 17:41:37 -0000 1.53
+++ nsd.conf.5.in 18 Mar 2026 20:44:03 -0000
@@ -1,4 +1,4 @@
-.TH "nsd.conf" "5" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0"
+.TH "nsd.conf" "5" "feb 24, 2026" "NLnet Labs" "nsd 4.14.1"
.\" Copyright (c) 2001\-2024, NLnet Labs. All rights reserved.
.\" See LICENSE for the license.
.SH "NAME"
@@ -104,16 +104,19 @@ clause. There may only be one
.B server:
clause.
.TP
-.B ip\-address:\fR <ip4 or ip6>[@port] [servers] [bindtodevice] [setfib]
+.B ip\-address:\fR <ip4 or ip6 or interface\-name>[@port] [servers] [bindtodevice] [setfib]
NSD will bind to the listed ip\-address. Can be given multiple times
to bind multiple ip\-addresses. Optionally, a port number can be given.
If none are given NSD listens to the wildcard interface. Same as command-line option
.BR \-a.
.sp
To limit which NSD server(s) listen on the given interface, specify one or
-more servers separated by whitespace after <ip>[@port]. Ranges can be used as
+more servers separated by whitespace after <ip>[@port].
+The NSD server has number 1 to server\-count processes to serve queries.
+This specifies the server processes by number that handle the ip\-address.
+Ranges can be used as
a shorthand to specify multiple consecutive servers. By default every server
-will listen.
+will listen and handle traffic for this.
.sp
If an interface name is used instead of ip4 or ip6, the list of IP addresses
associated with that interface is picked up and used at server start.
@@ -125,8 +128,19 @@ address of 0.0.0.0 then the kernel picks
send to the internet, and it picks the wrong one. Typically needed for
anycast instances. Use ip-transparent to be able to list addresses that
turn on later (typical for certain load-balancing).
+.sp
+The bindtodevice option looks for the device for the address, and then
+uses SO_BINDTODEVICE to bind the socket to the device. This is used as a
+performance optimisation. And it allows the network socket to connect
+directly to the network device. This speeds up the network stack processing.
+The socket only processes packets received from that interface.
+.sp
+The setfib option uses the SO_SETFIB socket option so that the fib from
+getaddrinfo for the address is set on the socket. This associates the FIB,
+the routing table, from the interface for the socket. That bypasses the
+routing selection for traffic. It is used as a performance optimisation.
.TP
-.B interface:\fR <ip4 or ip6>[@port] [servers] [bindtodevice] [setfib]
+.B interface:\fR <ip4 or ip6 or interface\-name>[@port] [servers] [bindtodevice] [setfib]
Same as ip\-address (for ease of compatibility with unbound.conf).
.TP
.B ip\-transparent:\fR <yes or no>
@@ -264,6 +278,14 @@ Note that not all platform supports sock
Default is system default MSS determined by interface MTU and
negotiation between NSD and other servers.
.TP
+.B tcp\-listen\-queue:\fR <number>
+Set the TCP backlog for listening sockets. This allows more pending
+connections with their connection established waiting for TCP service.
+Higher is better for more connections coming in at the same time.
+High values also protect more against flooding and some side-channel issues.
+Default is -1 on BSDs and Linux, and 256 on other systems. The -1 selects
+the largest value allowed.
+.TP
.B xfrd\-tcp\-max:\fR <number>
Number of sockets for xfrd to use for outgoing zone transfers. Default 128.
Increase it to allow more zone transfer sockets, like to 256.
@@ -894,6 +916,10 @@ The string is processed so that one stri
for a lot of different zones. If the label or character does not exist the
percent-character is replaced with a period for output (i.e. for the
third character in a two letter domain name).
+The '/' slash character is escaped as "\\047" when it is inside the '%s'
+string.
+Directories are created as necessary, when the directory is specified
+as part of the zonefile string. Useful for "%1/%2/%s.zone" or so.
.sp
.B %s\fR is replaced with the zone name.
.sp
Index: nsd.conf.sample.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsd.conf.sample.in,v
diff -u -p -r1.26 nsd.conf.sample.in
--- nsd.conf.sample.in 6 Sep 2025 17:41:37 -0000 1.26
+++ nsd.conf.sample.in 18 Mar 2026 20:44:03 -0000
@@ -170,6 +170,10 @@ server:
# Default is 0, system default MSS.
# outgoing-tcp-mss: 0
+ # Set the TCP backlog for listening sockets.
+ # Default 256, or -1 on BSDs and Linux.
+ # tcp-listen-queue: 256
+
# reduce these settings to save memory for NSD, to about
# xfrd-tcp-max: 32 and xfrd-tcp-pipeline: 128, also rrl-size: 1000
# other memory is determined by server-count, tcp-count and zone data
Index: nsec3.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/nsec3.c,v
diff -u -p -r1.29 nsec3.c
--- nsec3.c 6 Sep 2025 17:41:37 -0000 1.29
+++ nsec3.c 18 Mar 2026 20:44:03 -0000
@@ -93,9 +93,13 @@ detect_nsec3_params(rr_type* nsec3_apex,
{
assert(salt && salt_len && iter);
assert(nsec3_apex);
- *salt_len = rdata_atom_data(nsec3_apex->rdatas[3])[0];
- *salt = (unsigned char*)(rdata_atom_data(nsec3_apex->rdatas[3])+1);
- *iter = read_uint16(rdata_atom_data(nsec3_apex->rdatas[2]));
+ if(nsec3_apex->rdlength < 5)
+ return;
+ if(nsec3_apex->rdlength < 5 + (uint16_t)(nsec3_apex->rdata[4]))
+ return;
+ *salt_len = nsec3_apex->rdata[4];
+ *salt = (unsigned char*)(nsec3_apex->rdata + 5);
+ *iter = read_uint16(nsec3_apex->rdata + 2);
}
const dname_type *
@@ -162,13 +166,25 @@ nsec3_lookup_hash_ds(region_type* region
static int
nsec3_has_soa(rr_type* rr)
{
- if(rdata_atom_size(rr->rdatas[NSEC3_RDATA_BITMAP]) >= 3 && /* has types in bitmap */
- rdata_atom_data(rr->rdatas[NSEC3_RDATA_BITMAP])[0] == 0 && /* first window = 0, */
- /* [1]: bitmap length must be >= 1 */
- /* [2]: bit[6] = SOA, thus mask first bitmap octet with 0x02 */
- (rdata_atom_data(rr->rdatas[NSEC3_RDATA_BITMAP])[2]&0x02)) { /* SOA bit set */
+ size_t offset;
+ /* byte + byte + short + string + string + bitmap */
+ if(rr->rdlength < 6)
+ return 0;
+ offset = 4;
+ if(rr->rdlength < offset+1 ||
+ rr->rdlength < offset+1+rr->rdata[offset])
+ return 0;
+ offset += 1 + rr->rdata[offset];
+ if(rr->rdlength < offset+1 ||
+ rr->rdlength < offset+1+rr->rdata[offset])
+ return 0;
+ offset += 1 + rr->rdata[offset];
+ if (rr->rdlength >= offset + 3 && /* has types in bitmap */
+ rr->rdata[offset] == 0 && /* first window = 0, */
+ /* [1]: bitmap length must be >= 1 */
+ /* [2]: bit[6] = SOA, thus mask first bitmap octet with 0x02 */
+ (rr->rdata[offset+2] & 0x02))
return 1;
- }
return 0;
}
@@ -208,9 +224,9 @@ check_apex_soa(namedb_type* namedb, zone
return NULL;
}
for(j=0; j<nsec3_rrset->rr_count; j++) {
- if(nsec3_has_soa(&nsec3_rrset->rrs[j])) {
+ if(nsec3_has_soa(nsec3_rrset->rrs[j])) {
region_destroy(tmpregion);
- return &nsec3_rrset->rrs[j];
+ return nsec3_rrset->rrs[j];
}
}
if(!nolog) {
@@ -226,21 +242,26 @@ check_apex_soa(namedb_type* namedb, zone
static void
nsec3param_to_str(struct rr* rr, char* str, size_t buflen)
{
- rdata_atom_type* rd = rr->rdatas;
size_t len;
+ if(rr->rdlength < 5 || rr->rdlength < 5 + (uint16_t)rr->rdata[4]) {
+ str[0]=0;
+ return;
+ }
len = snprintf(str, buflen, "%u %u %u ",
- (unsigned)rdata_atom_data(rd[0])[0],
- (unsigned)rdata_atom_data(rd[1])[0],
- (unsigned)read_uint16(rdata_atom_data(rd[2])));
- if(rdata_atom_data(rd[3])[0] == 0) {
+ (unsigned)rr->rdata[0], (unsigned)rr->rdata[1],
+ (unsigned)read_uint16(rr->rdata+2));
+ if(rr->rdata[4] == 0) {
if(buflen > len + 2)
str[len++] = '-';
} else {
- len += hex_ntop(rdata_atom_data(rd[3])+1,
- rdata_atom_data(rd[3])[0], str+len, buflen-len-1);
+ len += hex_ntop(rr->rdata+5, rr->rdata[4], str+len, buflen-len-1);
}
- if(buflen > len + 1)
+ if(buflen > len + 1) {
str[len] = 0;
+ } else {
+ assert(buflen > 0);
+ str[buflen-1] = 0;
+ }
}
static struct rr*
@@ -253,14 +274,13 @@ db_find_nsec3param(struct namedb* db, st
return NULL;
/* find first nsec3param we can support (SHA1, no flags) */
for(i=0; i<rrset->rr_count; i++) {
- rdata_atom_type* rd = rrset->rrs[i].rdatas;
/* do not use the RR that is going to be deleted (in IXFR) */
- if(&rrset->rrs[i] == avoid_rr) continue;
- if(rrset->rrs[i].rdata_count < 4) continue;
- if(rdata_atom_data(rd[0])[0] == NSEC3_SHA1_HASH &&
- rdata_atom_data(rd[1])[0] == 0) {
+ if(rrset->rrs[i] == avoid_rr) continue;
+ if(rrset->rrs[i]->rdlength < 5) continue; /* require salt field */
+ if(rrset->rrs[i]->rdata[0] == NSEC3_SHA1_HASH &&
+ rrset->rrs[i]->rdata[1] == 0) {
if(checkchain) {
- z->nsec3_param = &rrset->rrs[i];
+ z->nsec3_param = rrset->rrs[i];
if(!check_apex_soa(db, z, 1)) {
char str[MAX_RDLENGTH*2+16];
nsec3param_to_str(z->nsec3_param,
@@ -271,12 +291,12 @@ db_find_nsec3param(struct namedb* db, st
}
if(2 <= verbosity) {
char str[MAX_RDLENGTH*2+16];
- nsec3param_to_str(&rrset->rrs[i], str,
+ nsec3param_to_str(rrset->rrs[i], str,
sizeof(str));
VERBOSITY(2, (LOG_INFO, "rehash of zone %s with parameters %s",
domain_to_string(z->apex), str));
}
- return &rrset->rrs[i];
+ return rrset->rrs[i];
}
}
return NULL;
@@ -292,27 +312,22 @@ nsec3_find_zone_param(struct namedb* db,
/* check params ok for one RR */
static int
-nsec3_rdata_params_ok(rdata_atom_type* prd, rdata_atom_type* rd)
+nsec3_rdata_params_ok(const rr_type *prr, const rr_type* rr)
{
- return (rdata_atom_data(rd[0])[0] ==
- rdata_atom_data(prd[0])[0] && /* hash algo */
- rdata_atom_data(rd[2])[0] ==
- rdata_atom_data(prd[2])[0] && /* iterations 0 */
- rdata_atom_data(rd[2])[1] ==
- rdata_atom_data(prd[2])[1] && /* iterations 1 */
- rdata_atom_data(rd[3])[0] ==
- rdata_atom_data(prd[3])[0] && /* salt length */
- memcmp(rdata_atom_data(rd[3])+1,
- rdata_atom_data(prd[3])+1, rdata_atom_data(rd[3])[0])
- == 0 );
+ if(prr->rdlength > rr->rdlength)
+ return 0; /* The salt has to fit */
+ if(prr->rdlength < 5)
+ return 0; /* Malformed */
+ return prr->rdata[0] == rr->rdata[0] &&
+ (memcmp(prr->rdata+2, rr->rdata+2, prr->rdlength-2) == 0);
}
int
nsec3_rr_uses_params(rr_type* rr, zone_type* zone)
{
- if(!rr || rr->rdata_count < 4)
+ if(!rr || rr->rdlength < 6)
return 0;
- return nsec3_rdata_params_ok(zone->nsec3_param->rdatas, rr->rdatas);
+ return nsec3_rdata_params_ok(zone->nsec3_param, rr);
}
int
@@ -324,7 +339,7 @@ nsec3_in_chain_count(domain_type* domain
if(!rrset || !zone->nsec3_param)
return 0; /* no NSEC3s, none in the chain */
for(i=0; i<rrset->rr_count; i++) {
- if(nsec3_rr_uses_params(&rrset->rrs[i], zone))
+ if(nsec3_rr_uses_params(rrset->rrs[i], zone))
count++;
}
return count;
@@ -1108,9 +1123,9 @@ domain_has_only_NSEC3(struct domain* dom
{
if(!zone || rrset->zone == zone)
{
- if(rrset->rrs[0].type == TYPE_NSEC3)
+ if(rrset->rrs[0]->type == TYPE_NSEC3)
nsec3_seen = 1;
- else if(rrset->rrs[0].type != TYPE_RRSIG)
+ else if(rrset->rrs[0]->type != TYPE_RRSIG)
return 0;
}
rrset = rrset->next;
Index: options.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/options.c,v
diff -u -p -r1.32 options.c
--- options.c 6 Sep 2025 17:41:37 -0000 1.32
+++ options.c 18 Mar 2026 20:44:03 -0000
@@ -65,8 +65,8 @@ nsd_options_create(region_type* region)
opt->ip_addresses = NULL;
opt->ip_transparent = 0;
opt->ip_freebind = 0;
- opt->send_buffer_size = 0;
- opt->receive_buffer_size = 0;
+ opt->send_buffer_size = 4*1024*1024;
+ opt->receive_buffer_size = 1*1024*1024;
opt->debug_mode = 0;
opt->verbosity = 0;
opt->hide_version = 0;
@@ -94,6 +94,7 @@ nsd_options_create(region_type* region)
opt->tcp_timeout = TCP_TIMEOUT;
opt->tcp_mss = 0;
opt->outgoing_tcp_mss = 0;
+ opt->tcp_listen_queue = TCP_BACKLOG;
opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN;
opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN;
opt->pidfile = PIDFILE;
@@ -2526,6 +2527,20 @@ replace_str(char* str, size_t len, const
}
}
+/* replace occurences of '/' with "\047", as a way to escape the '/'.
+ * This is to escape the slash character when it is part of the domain
+ * name string. It can be used normally when it is in the config string. */
+const char*
+escape_slash_zonefile(const char* input)
+{
+ static char f[1024];
+ if(!strchr(input, '/'))
+ return input;
+ strlcpy(f, input, sizeof(f));
+ replace_str(f, sizeof(f), "/", "\\047");
+ return f;
+}
+
const char*
config_cook_string(struct zone_options* zone, const char* input)
{
@@ -2548,7 +2563,8 @@ config_cook_string(struct zone_options*
if(strstr(f, "%x"))
replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
if(strstr(f, "%s"))
- replace_str(f, sizeof(f), "%s", zone->name);
+ replace_str(f, sizeof(f), "%s", escape_slash_zonefile(
+ zone->name));
return f;
}
@@ -2581,7 +2597,8 @@ config_make_zonefile(struct zone_options
if(strstr(f, "%x"))
replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
if(strstr(f, "%s"))
- replace_str(f, sizeof(f), "%s", zone->name);
+ replace_str(f, sizeof(f), "%s", escape_slash_zonefile(
+ zone->name));
if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' &&
strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0)
/* -1 because chrootdir ends in trailing slash */
Index: options.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/options.h,v
diff -u -p -r1.31 options.h
--- options.h 6 Sep 2025 17:41:37 -0000 1.31
+++ options.h 18 Mar 2026 20:44:03 -0000
@@ -103,6 +103,7 @@ struct nsd_options {
int tcp_timeout;
int tcp_mss;
int outgoing_tcp_mss;
+ int tcp_listen_queue;
size_t ipv4_edns_size;
size_t ipv6_edns_size;
const char* pidfile;
Index: packet.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/packet.c,v
diff -u -p -r1.3 packet.c
--- packet.c 14 May 2020 06:08:40 -0000 1.3
+++ packet.c 18 Mar 2026 20:44:03 -0000
@@ -14,6 +14,7 @@
#include "packet.h"
#include "query.h"
#include "rdata.h"
+#include "dns.h"
int round_robin = 0;
int minimal_responses = 0;
@@ -52,7 +53,8 @@ packet_encode_rr(query_type *q, domain_t
size_t truncation_mark;
uint16_t rdlength = 0;
size_t rdlength_pos;
- uint16_t j;
+ const nsd_type_descriptor_type *descriptor =
+ nsd_type_descriptor(rr->type);
assert(q);
assert(owner);
@@ -73,26 +75,7 @@ packet_encode_rr(query_type *q, domain_t
rdlength_pos = buffer_position(q->packet);
buffer_skip(q->packet, sizeof(rdlength));
- for (j = 0; j < rr->rdata_count; ++j) {
- switch (rdata_atom_wireformat_type(rr->type, j)) {
- case RDATA_WF_COMPRESSED_DNAME:
- encode_dname(q, rdata_atom_domain(rr->rdatas[j]));
- break;
- case RDATA_WF_UNCOMPRESSED_DNAME:
- {
- const dname_type *dname = domain_dname(
- rdata_atom_domain(rr->rdatas[j]));
- buffer_write(q->packet,
- dname_name(dname), dname->name_size);
- break;
- }
- default:
- buffer_write(q->packet,
- rdata_atom_data(rr->rdatas[j]),
- rdata_atom_size(rr->rdatas[j]));
- break;
- }
- }
+ descriptor->write_rdata(q, rr);
if (!query_overflow(q)) {
rdlength = (buffer_position(q->packet) - rdlength_pos
@@ -147,8 +130,8 @@ packet_encode_rrset(query_type *query,
start = (uint16_t)(round_robin_off++ % rrset->rr_count);
else start = 0;
for (i = start; i < rrset->rr_count; ++i) {
- if (packet_encode_rr(query, owner, &rrset->rrs[i],
- rrset->rrs[i].ttl)) {
+ if (packet_encode_rr(query, owner, rrset->rrs[i],
+ rrset->rrs[i]->ttl)) {
++added;
} else {
all_added = 0;
@@ -157,8 +140,8 @@ packet_encode_rrset(query_type *query,
}
}
for (i = 0; i < start; ++i) {
- if (packet_encode_rr(query, owner, &rrset->rrs[i],
- rrset->rrs[i].ttl)) {
+ if (packet_encode_rr(query, owner, rrset->rrs[i],
+ rrset->rrs[i]->ttl)) {
++added;
} else {
all_added = 0;
@@ -173,12 +156,12 @@ packet_encode_rrset(query_type *query,
(rrsig = domain_find_rrset(owner, rrset->zone, TYPE_RRSIG)))
{
for (i = 0; i < rrsig->rr_count; ++i) {
- if (rr_rrsig_type_covered(&rrsig->rrs[i])
+ if (rr_rrsig_type_covered(rrsig->rrs[i])
== rrset_rrtype(rrset))
{
if (packet_encode_rr(query, owner,
- &rrsig->rrs[i],
- rrset_rrtype(rrset)==TYPE_SOA?rrset->rrs[0].ttl:rrsig->rrs[i].ttl))
+ rrsig->rrs[i],
+ rrset_rrtype(rrset)==TYPE_SOA?rrset->rrs[0]->ttl:rrsig->rrs[i]->ttl))
{
++added;
} else {
@@ -263,46 +246,54 @@ rr_type *
packet_read_rr(region_type *region, domain_table_type *owners,
buffer_type *packet, int question_section)
{
+ const nsd_type_descriptor_type *descriptor;
const dname_type *owner;
- uint16_t rdlength;
- ssize_t rdata_count;
- rdata_atom_type *rdatas;
- rr_type *result = (rr_type *) region_alloc(region, sizeof(rr_type));
+ struct domain* domain;
+ uint16_t type, class, rdlength;
+ uint32_t ttl;
+ struct rr *rr;
+ int32_t code;
owner = dname_make_from_packet(region, packet, 1, 1);
if (!owner || !buffer_available(packet, 2*sizeof(uint16_t))) {
return NULL;
}
- result->owner = domain_table_insert(owners, owner);
- result->type = buffer_read_u16(packet);
- result->klass = buffer_read_u16(packet);
+ domain = domain_table_insert(owners, owner);
+ type = buffer_read_u16(packet);
+ class = buffer_read_u16(packet);
if (question_section) {
+ rr_type *result = (rr_type *) region_alloc(region,
+ sizeof(rr_type));
+ result->owner = domain;
+ result->type = type;
+ result->klass = class;
result->ttl = 0;
- result->rdata_count = 0;
- result->rdatas = NULL;
+ result->rdlength = 0;
return result;
} else if (!buffer_available(packet, sizeof(uint32_t) + sizeof(uint16_t))) {
return NULL;
}
- result->ttl = buffer_read_u32(packet);
+ ttl = buffer_read_u32(packet);
rdlength = buffer_read_u16(packet);
if (!buffer_available(packet, rdlength)) {
return NULL;
}
- rdata_count = rdata_wireformat_to_rdata_atoms(
- region, owners, result->type, rdlength, packet, &rdatas);
- if (rdata_count == -1) {
+ descriptor = nsd_type_descriptor(type);
+ code = descriptor->read_rdata(owners, rdlength, packet, &rr);
+ if(code < 0) {
return NULL;
}
- result->rdata_count = rdata_count;
- result->rdatas = rdatas;
+ rr->owner = domain;
+ rr->type = type;
+ rr->klass = class;
+ rr->ttl = ttl;
- return result;
+ return rr;
}
int packet_read_query_section(buffer_type *packet,
Index: query.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/query.c,v
diff -u -p -r1.44 query.c
--- query.c 6 Sep 2025 17:41:37 -0000 1.44
+++ query.c 18 Mar 2026 20:44:03 -0000
@@ -36,6 +36,7 @@
#include "options.h"
#include "nsec3.h"
#include "tsig.h"
+#include "rdata.h"
/* [Bug #253] Adding unnecessary NS RRset may lead to undesired truncation.
* This function determines if the final response packet needs the NS RRset
@@ -706,7 +707,7 @@ struct additional_rr_types rt_additional
static void
add_additional_rrsets(struct query *query, answer_type *answer,
- rrset_type *master_rrset, size_t rdata_index,
+ rrset_type *master_rrset, uint16_t rdata_offset,
int allow_glue, struct additional_rr_types types[])
{
size_t i;
@@ -714,11 +715,11 @@ add_additional_rrsets(struct query *quer
assert(query);
assert(answer);
assert(master_rrset);
- assert(rdata_atom_is_domain(rrset_rrtype(master_rrset), rdata_index));
for (i = 0; i < master_rrset->rr_count; ++i) {
int j;
- domain_type *additional = rdata_atom_domain(master_rrset->rrs[i].rdatas[rdata_index]);
+ domain_type *additional = rdata_domain_ref_offset(
+ master_rrset->rrs[i], rdata_offset);
domain_type *match = additional;
assert(additional);
@@ -796,30 +797,40 @@ add_rrset(struct query *query,
case TYPE_NS:
#if defined(INET6)
/* if query over IPv6, swap A and AAAA; put AAAA first */
- add_additional_rrsets(query, answer, rrset, 0, 1,
+ add_additional_rrsets(query, answer, rrset,
+ 0, 1,
(query->client_addr.ss_family == AF_INET6)?
swap_aaaa_additional_rr_types:
default_additional_rr_types);
#else
- add_additional_rrsets(query, answer, rrset, 0, 1,
+ add_additional_rrsets(query, answer, rrset,
+ 0, 1,
default_additional_rr_types);
#endif
break;
case TYPE_MB:
- add_additional_rrsets(query, answer, rrset, 0, 0,
+ add_additional_rrsets(query, answer, rrset,
+ 0, 0,
default_additional_rr_types);
break;
case TYPE_MX:
+ add_additional_rrsets(query, answer, rrset,
+ 2, 0,
+ default_additional_rr_types);
+ break;
case TYPE_KX:
- add_additional_rrsets(query, answer, rrset, 1, 0,
+ add_additional_rrsets(query, answer, rrset,
+ 2, 0,
default_additional_rr_types);
break;
case TYPE_RT:
- add_additional_rrsets(query, answer, rrset, 1, 0,
+ add_additional_rrsets(query, answer, rrset,
+ 2, 0,
rt_additional_rr_types);
break;
case TYPE_SRV:
- add_additional_rrsets(query, answer, rrset, 3, 0,
+ add_additional_rrsets(query, answer, rrset,
+ 6, 0,
default_additional_rr_types);
break;
default:
@@ -856,10 +867,10 @@ query_synthesize_cname(struct query* q,
for(j=0; j<answer->rrset_count; ++j) {
if(answer->section[j] == ANSWER_SECTION &&
answer->rrsets[j]->rr_count == 1 &&
- answer->rrsets[j]->rrs[0].type == TYPE_CNAME &&
- dname_compare(domain_dname(answer->rrsets[j]->rrs[0].owner), from_name) == 0 &&
- answer->rrsets[j]->rrs[0].rdata_count == 1 &&
- dname_compare(domain_dname(answer->rrsets[j]->rrs[0].rdatas->domain), to_name) == 0) {
+ answer->rrsets[j]->rrs[0]->type == TYPE_CNAME &&
+ dname_compare(domain_dname(answer->rrsets[j]->rrs[0]->owner), from_name) == 0 &&
+ answer->rrsets[j]->rrs[0]->rdlength >= 1 &&
+ dname_compare(domain_dname(rdata_domain_ref(answer->rrsets[j]->rrs[0])), to_name) == 0) {
DEBUG(DEBUG_QUERY,2, (LOG_INFO, "loop for synthesized CNAME rrset for query %s", dname_to_string(q->qname, NULL)));
return 0;
}
@@ -915,20 +926,26 @@ query_synthesize_cname(struct query* q,
*to_closest_match = cname_dest;
/* allocate the CNAME RR */
- rrset = (rrset_type*) region_alloc(q->region, sizeof(rrset_type));
+ rrset = (rrset_type*) region_alloc(q->region, sizeof(rrset_type)
+#ifdef PACKED_STRUCTS
+ + sizeof(rr_type*)
+#endif
+ );
memset(rrset, 0, sizeof(rrset_type));
rrset->zone = q->zone;
rrset->rr_count = 1;
- rrset->rrs = (rr_type*) region_alloc(q->region, sizeof(rr_type));
- memset(rrset->rrs, 0, sizeof(rr_type));
- rrset->rrs->owner = cname_domain;
- rrset->rrs->ttl = ttl;
- rrset->rrs->type = TYPE_CNAME;
- rrset->rrs->klass = CLASS_IN;
- rrset->rrs->rdata_count = 1;
- rrset->rrs->rdatas = (rdata_atom_type*)region_alloc(q->region,
- sizeof(rdata_atom_type));
- rrset->rrs->rdatas->domain = cname_dest;
+#ifndef PACKED_STRUCTS
+ rrset->rrs = (rr_type**) region_alloc(q->region, sizeof(rr_type*));
+#endif
+ rrset->rrs[0] = (rr_type*) region_alloc(q->region,
+ sizeof(rr_type)+sizeof(void*));
+ memset(rrset->rrs[0], 0, sizeof(rr_type));
+ rrset->rrs[0]->owner = cname_domain;
+ rrset->rrs[0]->ttl = ttl;
+ rrset->rrs[0]->type = TYPE_CNAME;
+ rrset->rrs[0]->klass = CLASS_IN;
+ rrset->rrs[0]->rdlength = sizeof(void*);
+ memcpy(rrset->rrs[0]->rdata, &cname_dest, sizeof(void*));
if(!add_rrset(q, answer, ANSWER_SECTION, cname_domain, rrset)) {
DEBUG(DEBUG_QUERY,2, (LOG_INFO, "could not add synthesized CNAME rrset to packet for query %s", dname_to_string(q->qname, NULL)));
@@ -1116,7 +1133,7 @@ answer_domain(struct nsd* nsd, struct qu
assert(rrset->rr_count > 0);
if (added) {
/* only process first CNAME record */
- domain_type *closest_match = rdata_atom_domain(rrset->rrs[0].rdatas[0]);
+ domain_type *closest_match = rdata_domain_ref(rrset->rrs[0]);
domain_type *closest_encloser = closest_match;
zone_type* origzone = q->zone;
++q->cname_count;
@@ -1185,7 +1202,7 @@ answer_authoritative(struct nsd *nsd,
/* process DNAME */
const dname_type* name = qname;
domain_type* src = closest_encloser;
- domain_type *dest = rdata_atom_domain(rrset->rrs[0].rdatas[0]);
+ domain_type *dest = rdata_domain_ref(rrset->rrs[0]);
const dname_type* newname;
size_t newnum = 0;
zone_type* origzone = q->zone;
@@ -1219,7 +1236,7 @@ answer_authoritative(struct nsd *nsd,
(void)namedb_lookup(nsd->db, newname, &closest_match, &closest_encloser);
/* synthesize CNAME record */
newnum = query_synthesize_cname(q, answer, name, newname,
- src, closest_encloser, &closest_match, rrset->rrs[0].ttl);
+ src, closest_encloser, &closest_match, rrset->rrs[0]->ttl);
if(!newnum) {
/* could not synthesize the CNAME. */
/* return previous CNAMEs to make resolver recurse for us */
@@ -1811,8 +1828,8 @@ query_add_optional(query_type *q, nsd_ty
if(q->edns.zoneversion
&& q->zone
&& q->zone->soa_rrset
- && q->zone->soa_rrset->rrs
- && q->zone->soa_rrset->rrs->rdata_count >= 3)
+ && q->zone->soa_rrset->rr_count >= 1
+ && q->zone->soa_rrset->rrs[0]->rdlength >= 20 /* 5x 32bit numbers */ +2*sizeof(void*) /* two pointers to domain names */)
q->edns.opt_reserved_space += sizeof(uint16_t)
+ sizeof(uint16_t)
+ sizeof(uint8_t)
@@ -1836,8 +1853,9 @@ query_add_optional(query_type *q, nsd_ty
if(q->edns.zoneversion
&& q->zone
&& q->zone->soa_rrset
- && q->zone->soa_rrset->rrs
- && q->zone->soa_rrset->rrs->rdata_count >= 3) {
+ && q->zone->soa_rrset->rr_count >= 1
+ && q->zone->soa_rrset->rrs[0]->rdlength >= 20+2*sizeof(void*) /* 5x4 bytes and 2 pointers to domains */ ) {
+ uint32_t serial = 0;
buffer_write_u16(q->packet, ZONEVERSION_CODE);
buffer_write_u16( q->packet
, sizeof(uint8_t)
@@ -1847,9 +1865,8 @@ query_add_optional(query_type *q, nsd_ty
domain_dname(q->zone->apex)->label_count - 1);
buffer_write_u8( q->packet
, ZONEVERSION_SOA_SERIAL);
- buffer_write_u32(q->packet,
- read_uint32(rdata_atom_data(
- q->zone->soa_rrset->rrs->rdatas[2])));
+ retrieve_soa_rdata_serial(q->zone->soa_rrset->rrs[0], &serial);
+ buffer_write_u32(q->packet, serial);
}
if(q->edns.cookie_status != COOKIE_NOT_PRESENT) {
/* cookie opt header */
Index: rdata.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/rdata.c,v
diff -u -p -r1.19 rdata.c
--- rdata.c 6 Sep 2025 17:41:37 -0000 1.19
+++ rdata.c 18 Mar 2026 20:44:03 -0000
@@ -24,6 +24,8 @@
#include "rdata.h"
#include "zonec.h"
+#include "query.h"
+#include "dname.h"
/* Taken from RFC 4398, section 2.1. */
lookup_table_type dns_certificate_types[] = {
@@ -67,150 +69,230 @@ lookup_table_type dns_algorithms[] = {
{ 0, NULL }
};
-const char *svcparamkey_strs[] = {
- "mandatory", "alpn", "no-default-alpn", "port",
- "ipv4hint", "ech", "ipv6hint", "dohpath", "ohttp",
- "tls-supported-groups"
- };
-
-typedef int (*rdata_to_string_type)(buffer_type *output,
- rdata_atom_type rdata,
- rr_type *rr);
+/* Print svcparam key without a value */
+static int print_svcparam_no_value(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam mandatory */
+static int print_svcparam_mandatory(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam alpn */
+static int print_svcparam_alpn(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam port */
+static int print_svcparam_port(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam ipv4hint */
+static int print_svcparam_ipv4hint(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam ech */
+static int print_svcparam_ech(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam ipv6hint */
+static int print_svcparam_ipv6hint(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam dohpath */
+static int print_svcparam_dohpath(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+/* Print svcparam tls-supported-groups */
+static int print_svcparam_tls_supported_groups(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
+
+static const nsd_svcparam_descriptor_type svcparams[] = {
+ { SVCB_KEY_MANDATORY, "mandatory", print_svcparam_mandatory },
+ { SVCB_KEY_ALPN, "alpn", print_svcparam_alpn },
+ { SVCB_KEY_NO_DEFAULT_ALPN, "no-default-alpn",
+ print_svcparam_no_value },
+ { SVCB_KEY_PORT, "port", print_svcparam_port },
+ { SVCB_KEY_IPV4HINT, "ipv4hint", print_svcparam_ipv4hint },
+ { SVCB_KEY_ECH, "ech", print_svcparam_ech },
+ { SVCB_KEY_IPV6HINT, "ipv6hint", print_svcparam_ipv6hint },
+ { SVCB_KEY_DOHPATH, "dohpath", print_svcparam_dohpath },
+ { SVCB_KEY_OHTTP, "ohttp", print_svcparam_no_value },
+ { SVCB_KEY_TLS_SUPPORTED_GROUPS, "tls-supported-groups",
+ print_svcparam_tls_supported_groups },
+};
+/*
+ * Print domain name, as example.com. with escapes.
+ * The domain name is wireformat in the rdata. That is a literal dname
+ * in the rdata.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_dname_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_name_literal(struct buffer *output, uint16_t rdlength,
+ const uint8_t *rdata, uint16_t *offset)
{
- buffer_printf(output,
- "%s",
- dname_to_string(domain_dname(rdata_atom_domain(rdata)),
- NULL));
+ const uint8_t *name, *label, *limit;
+ assert(rdlength >= *offset);
+ if (rdlength - *offset == 0)
+ return 0;
+
+ name = rdata + *offset;
+ label = name;
+ limit = rdata + rdlength;
+
+ if(*label) {
+ do {
+ /* space for labellen, label and a next root label. */
+ if (label - name > MAXDOMAINLEN-1
+ || *label > MAXLABELLEN
+ || limit - label < 2 + *label)
+ return 0;
+ label += 1 + *label;
+ } while (*label);
+ } else {
+ /* root domain. */
+ /* The label is within the rdlength by the checks at start of
+ * the function. */
+ }
+
+ buffer_printf(output, "%s", wiredname2str(name));
+ *offset += (label - name) + 1 /* root label */;
return 1;
}
+/*
+ * Print domain name, as example.com. with escapes.
+ * The domain must be a reference in the rdata. That is a stored pointer
+ * to struct domain.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_dns_name_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_domain(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- const uint8_t *data = rdata_atom_data(rdata);
- size_t offset = 0;
- uint8_t length = data[offset];
- size_t i;
+ const struct dname *dname;
+ struct domain *domain;
+ if(rdlength - *offset < (uint16_t)sizeof(void*))
+ return 0;
+ memcpy(&domain, rdata+*offset, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_printf(output, "%s", dname_to_string(dname, NULL));
+ *offset += sizeof(void*);
+ return 1;
+}
- while (length > 0)
- {
- if (offset) /* concat label */
- buffer_printf(output, ".");
-
- for (i = 1; i <= length; ++i) {
- uint8_t ch = data[i+offset];
-
- if (ch=='.' || ch==';' || ch=='(' || ch==')' || ch=='\\') {
- buffer_printf(output, "\\%c", (char) ch);
- } else if (!isgraph((unsigned char) ch)) {
- buffer_printf(output, "\\%03u", (unsigned int) ch);
- } else if (isprint((unsigned char) ch)) {
- buffer_printf(output, "%c", (char) ch);
- } else {
- buffer_printf(output, "\\%03u", (unsigned int) ch);
- }
- }
- /* next label */
- offset = offset+length+1;
- length = data[offset];
- }
+/* Return length of string or -1 on wireformat error. offset is moved +len. */
+static inline int32_t
+skip_string(struct buffer* output, uint16_t rdlength, uint16_t* offset)
+{
+ int32_t length;
+ if (rdlength - *offset < 1)
+ return -1;
+ length = buffer_read_u8(output);
+ if (length + 1 > rdlength - *offset)
+ return -1;
+ buffer_skip(output, length);
+ *offset += length + 1;
+ return length + 1;
+}
- /* root label */
- buffer_printf(output, ".");
- return 1;
+/* Return length of strings or -1 on wireformat error. offset is moved +len. */
+static inline int32_t
+skip_strings(struct buffer* output, uint16_t rdlength, uint16_t* offset)
+{
+ int32_t olen = 0;
+ while(*offset < rdlength) {
+ int32_t slen = skip_string(output, rdlength, offset);
+ if(slen < 0)
+ return slen;
+ olen += slen;
+ }
+ return olen;
}
+/*
+ * Print string, as "string" with escapes.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_text_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_string(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- const uint8_t *data = rdata_atom_data(rdata);
- uint8_t length = data[0];
- size_t i;
-
+ size_t n;
+ if(rdlength - *offset < 1)
+ return 0;
+ n = rdata[*offset];
+ if((size_t)rdlength - *offset < 1 + n)
+ return 0;
buffer_printf(output, "\"");
- for (i = 1; i <= length; ++i) {
- char ch = (char) data[i];
+ for (size_t i = 1; i <= n; i++) {
+ char ch = (char) rdata[*offset+i];
if (isprint((unsigned char)ch)) {
if (ch == '"' || ch == '\\') {
buffer_printf(output, "\\");
}
buffer_printf(output, "%c", ch);
} else {
- buffer_printf(output, "\\%03u", (unsigned) data[i]);
+ buffer_printf(output, "\\%03u",
+ (unsigned) rdata[*offset+i]);
}
}
buffer_printf(output, "\"");
+ *offset += 1;
+ *offset += n;
return 1;
}
-static int
-rdata_texts_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint16_t pos = 0;
- const uint8_t *data = rdata_atom_data(rdata);
- uint16_t length = rdata_atom_size(rdata);
- size_t i;
-
- while (pos < length && pos + data[pos] < length) {
- buffer_printf(output, "\"");
- for (i = 1; i <= data[pos]; ++i) {
- char ch = (char) data[pos + i];
- if (isprint((unsigned char)ch)) {
- if (ch == '"' || ch == '\\') {
- buffer_printf(output, "\\");
- }
- buffer_printf(output, "%c", ch);
- } else {
- buffer_printf(output, "\\%03u", (unsigned) data[pos+i]);
- }
- }
- pos += data[pos]+1;
- buffer_printf(output, pos < length?"\" ":"\"");
- }
- return 1;
-}
-
-static int
-rdata_long_text_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+static int32_t
+print_text(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- const uint8_t *data = rdata_atom_data(rdata);
- uint16_t length = rdata_atom_size(rdata);
- size_t i;
-
buffer_printf(output, "\"");
- for (i = 0; i < length; ++i) {
- char ch = (char) data[i];
+ for (size_t i = *offset; i < rdlength; ++i) {
+ char ch = (char) rdata[i];
if (isprint((unsigned char)ch)) {
if (ch == '"' || ch == '\\') {
buffer_printf(output, "\\");
}
buffer_printf(output, "%c", ch);
} else {
- buffer_printf(output, "\\%03u", (unsigned) data[i]);
+ buffer_printf(output, "\\%03u", (unsigned) rdata[i]);
}
}
buffer_printf(output, "\"");
+ *offset = rdlength;
return 1;
}
static int
-rdata_unquoted_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_unquoted(buffer_type *output, uint16_t rdlength,
+ const uint8_t* rdata, uint16_t* offset)
{
- const uint8_t *data = rdata_atom_data(rdata);
- uint8_t length = data[0];
+ uint8_t len;
size_t i;
- for (i = 1; i <= length; ++i) {
- char ch = (char) data[i];
+ if(rdlength - *offset < 1)
+ return 0;
+ len = rdata[*offset];
+ if(((size_t)len) + 1 > (size_t)rdlength - *offset)
+ return 0;
+
+ for (i = 1; i <= (size_t)len; ++i) {
+ char ch = (char) rdata[*offset + i];
if (isprint((unsigned char)ch)) {
if (ch == '"' || ch == '\\' || ch == '(' || ch == ')'
|| ch == '\'' || isspace((unsigned char)ch)) {
@@ -218,267 +300,229 @@ rdata_unquoted_to_string(buffer_type *ou
}
buffer_printf(output, "%c", ch);
} else {
- buffer_printf(output, "\\%03u", (unsigned) data[i]);
- }
- }
- return 1;
-}
-
-static int
-rdata_unquoteds_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint16_t pos = 0;
- const uint8_t *data = rdata_atom_data(rdata);
- uint16_t length = rdata_atom_size(rdata);
- size_t i;
-
- while (pos < length && pos + data[pos] < length) {
- for (i = 1; i <= data[pos]; ++i) {
- char ch = (char) data[pos + i];
- if (isprint((unsigned char)ch)) {
- if (ch == '"' || ch == '\\'
- || isspace((unsigned char)ch)) {
- buffer_printf(output, "\\");
- }
- buffer_printf(output, "%c", ch);
- } else {
- buffer_printf(output, "\\%03u", (unsigned) data[pos+i]);
- }
+ buffer_printf(output, "\\%03u",
+ (unsigned) rdata[*offset + i]);
}
- pos += data[pos]+1;
- buffer_printf(output, pos < length?" ":"");
}
+ *offset += 1;
+ *offset += len;
return 1;
}
static int
-rdata_tag_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_unquoteds(buffer_type *output, uint16_t rdlength,
+ const uint8_t* rdata, uint16_t* offset)
{
- const uint8_t *data = rdata_atom_data(rdata);
- uint8_t length = data[0];
- size_t i;
- for (i = 1; i <= length; ++i) {
- char ch = (char) data[i];
- if (isdigit((unsigned char)ch) || islower((unsigned char)ch))
- buffer_printf(output, "%c", ch);
- else return 0;
+ while (*offset < rdlength) {
+ if(!print_unquoted(output, rdlength, rdata, offset))
+ return 0;
+ if(*offset < rdlength)
+ buffer_printf(output, " ");
}
return 1;
}
+/*
+ * Print IP4 address.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_byte_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint8_t data = *rdata_atom_data(rdata);
- buffer_printf(output, "%lu", (unsigned long) data);
- return 1;
-}
-
-static int
-rdata_short_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint16_t data = read_uint16(rdata_atom_data(rdata));
- buffer_printf(output, "%lu", (unsigned long) data);
- return 1;
-}
-
-static int
-rdata_long_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_ip4(struct buffer *output, size_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- uint32_t data = read_uint32(rdata_atom_data(rdata));
- buffer_printf(output, "%lu", (unsigned long) data);
+ char str[INET_ADDRSTRLEN + 1];
+ assert(rdlength >= *offset);
+ if(((size_t)*offset) + 4 > rdlength)
+ return 0;
+ if(!inet_ntop(AF_INET, rdata + *offset, str, sizeof(str)))
+ return 0;
+ buffer_printf(output, "%s", str);
+ *offset += 4;
return 1;
}
+/*
+ * Print IP6 address.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_longlong_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_ip6(struct buffer *output, size_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- uint64_t data = read_uint64(rdata_atom_data(rdata));
- buffer_printf(output, "%llu", (unsigned long long) data);
+ char str[INET6_ADDRSTRLEN + 1];
+ assert(rdlength >= *offset);
+ if (rdlength - *offset < 16)
+ return 0;
+ if (!inet_ntop(AF_INET6, rdata + *offset, str, sizeof(str)))
+ return 0;
+ buffer_printf(output, "%s", str);
+ *offset += 16;
return 1;
}
+/*
+ * Print ilnp64 field.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_a_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- int result = 0;
- char str[200];
- if (inet_ntop(AF_INET, rdata_atom_data(rdata), str, sizeof(str))) {
- buffer_printf(output, "%s", str);
- result = 1;
- }
- return result;
-}
-
-static int
-rdata_aaaa_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- int result = 0;
- char str[200];
- if (inet_ntop(AF_INET6, rdata_atom_data(rdata), str, sizeof(str))) {
- buffer_printf(output, "%s", str);
- result = 1;
- }
- return result;
-}
-
-static int
-rdata_ilnp64_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_ilnp64(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- uint8_t* data = rdata_atom_data(rdata);
- uint16_t a1 = read_uint16(data);
- uint16_t a2 = read_uint16(data+2);
- uint16_t a3 = read_uint16(data+4);
- uint16_t a4 = read_uint16(data+6);
+ uint16_t a1, a2, a3, a4;
+ assert(rdlength >= *offset);
+ if (rdlength - *offset < 8)
+ return 0;
+ a1 = read_uint16(rdata + *offset);
+ a2 = read_uint16(rdata + *offset + 2);
+ a3 = read_uint16(rdata + *offset + 4);
+ a4 = read_uint16(rdata + *offset + 6);
buffer_printf(output, "%.4x:%.4x:%.4x:%.4x", a1, a2, a3, a4);
+ *offset += 8;
return 1;
}
+/*
+ * Print certificate type.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_eui48_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint8_t* data = rdata_atom_data(rdata);
- uint8_t a1 = data[0];
- uint8_t a2 = data[1];
- uint8_t a3 = data[2];
- uint8_t a4 = data[3];
- uint8_t a5 = data[4];
- uint8_t a6 = data[5];
-
- buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
- a1, a2, a3, a4, a5, a6);
- return 1;
-}
-
-static int
-rdata_eui64_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint8_t* data = rdata_atom_data(rdata);
- uint8_t a1 = data[0];
- uint8_t a2 = data[1];
- uint8_t a3 = data[2];
- uint8_t a4 = data[3];
- uint8_t a5 = data[4];
- uint8_t a6 = data[5];
- uint8_t a7 = data[6];
- uint8_t a8 = data[7];
-
- buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
- a1, a2, a3, a4, a5, a6, a7, a8);
- return 1;
-}
-
-static int
-rdata_rrtype_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint16_t type = read_uint16(rdata_atom_data(rdata));
- buffer_printf(output, "%s", rrtype_to_string(type));
- return 1;
-}
-
-static int
-rdata_algorithm_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint8_t id = *rdata_atom_data(rdata);
- buffer_printf(output, "%u", (unsigned) id);
- return 1;
-}
-
-static int
-rdata_certificate_type_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_certificate_type(struct buffer *output, size_t rdlength,
+ const uint8_t *rdata, uint16_t *offset)
{
- uint16_t id = read_uint16(rdata_atom_data(rdata));
- lookup_table_type *type
- = lookup_by_id(dns_certificate_types, id);
- if (type) {
+ uint16_t id;
+ lookup_table_type* type;
+ if (rdlength < *offset || rdlength - *offset < 2)
+ return 0;
+ id = read_uint16(rdata + *offset);
+ type = lookup_by_id(dns_certificate_types, id);
+ if (type)
buffer_printf(output, "%s", type->name);
- } else {
+ else
buffer_printf(output, "%u", (unsigned) id);
- }
- return 1;
-}
-
-static int
-rdata_period_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- uint32_t period = read_uint32(rdata_atom_data(rdata));
- buffer_printf(output, "%lu", (unsigned long) period);
+ *offset += 2;
return 1;
}
+/*
+ * Print time field.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_time_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_time(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- int result = 0;
- time_t time = (time_t) read_uint32(rdata_atom_data(rdata));
- struct tm *tm = gmtime(&time);
+ time_t time;
+ struct tm tmbuf;
+ struct tm* tm;
char buf[15];
- if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm)) {
- buffer_printf(output, "%s", buf);
- result = 1;
- }
- return result;
+
+ assert(rdlength >= *offset);
+ if (rdlength - *offset < 4)
+ return 0;
+ time = (time_t)read_uint32(rdata + *offset);
+ tm = gmtime_r(&time, &tmbuf);
+ if (!strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm))
+ return 0;
+ buffer_printf(output, "%s", buf);
+ *offset += 4;
+ return 1;
}
+/*
+ * Print base32 output for a b32 field length uint8_t, like for NSEC3.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_base32_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_base32(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
+ size_t size;
int length;
- size_t size = rdata_atom_size(rdata);
- if(size == 0) {
+ if(rdlength - *offset == 0)
+ return 0;
+ size = rdata[*offset];
+ if (rdlength - ((size_t)*offset) < 1 + size)
+ return 0;
+
+ if (size == 0) {
buffer_write(output, "-", 1);
+ *offset += 1;
return 1;
}
- size -= 1; /* remove length byte from count */
+
buffer_reserve(output, size * 2 + 1);
- length = b32_ntop(rdata_atom_data(rdata)+1, size,
- (char *) buffer_current(output), size * 2);
- if (length > 0) {
- buffer_skip(output, length);
- }
- return length != -1;
+ length = b32_ntop(rdata + *offset + 1, size,
+ (char *)buffer_current(output), size * 2);
+ if (length == -1)
+ return 0;
+ buffer_skip(output, length);
+ *offset += 1 + size;
+ return 1;
}
+/*
+ * Print base64 output for the remainder of rdata.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_base64_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* rr)
+print_base64(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
int length;
- size_t size = rdata_atom_size(rdata);
+ size_t size = rdlength - *offset;
if(size == 0) {
/* single zero represents empty buffer */
- buffer_write(output, (rr->type == TYPE_DOA ? "-" : "0"), 1);
+ buffer_write(output, "0", 1);
return 1;
}
buffer_reserve(output, size * 2 + 1);
- length = __b64_ntop(rdata_atom_data(rdata), size,
+ length = __b64_ntop(rdata + *offset, size,
(char *) buffer_current(output), size * 2);
- if (length > 0) {
- buffer_skip(output, length);
- }
- return length != -1;
+ if (length == -1)
+ return 0;
+ buffer_skip(output, length);
+ *offset += size;
+ return 1;
}
static void
-hex_to_string(buffer_type *output, const uint8_t *data, size_t size)
+buffer_print_hex(buffer_type *output, const uint8_t *data, size_t size)
{
static const char hexdigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
@@ -494,186 +538,123 @@ hex_to_string(buffer_type *output, const
}
}
+/*
+ * Print base16 output for the remainder of rdata, in hex lowercase.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_hex_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_base16(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- if(rdata_atom_size(rdata) == 0) {
+ size_t size = rdlength - *offset;
+ if(size == 0) {
/* single zero represents empty buffer, such as CDS deletes */
- buffer_printf(output, "0");
- } else {
- hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata));
- }
- return 1;
-}
-
-static int
-rdata_hexlen_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- if(rdata_atom_size(rdata) <= 1) {
- /* NSEC3 salt hex can be empty */
- buffer_printf(output, "-");
+ buffer_write(output, "0", 1);
return 1;
+ } else {
+ buffer_print_hex(output, rdata+*offset, size);
}
- hex_to_string(output, rdata_atom_data(rdata)+1, rdata_atom_size(rdata)-1);
- return 1;
-}
-
-static int
-rdata_nsap_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- buffer_printf(output, "0x");
- hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata));
+ *offset += size;
return 1;
}
-static int
-rdata_apl_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- int result = 0;
- buffer_type packet;
-
- buffer_create_from(
- &packet, rdata_atom_data(rdata), rdata_atom_size(rdata));
-
- if (buffer_available(&packet, 4)) {
- uint16_t address_family = buffer_read_u16(&packet);
- uint8_t prefix = buffer_read_u8(&packet);
- uint8_t length = buffer_read_u8(&packet);
- int negated = length & APL_NEGATION_MASK;
- int af = -1;
-
- length &= APL_LENGTH_MASK;
- switch (address_family) {
- case 1: af = AF_INET; break;
- case 2: af = AF_INET6; break;
- }
- if (af != -1 && buffer_available(&packet, length)) {
- char text_address[1000];
- uint8_t address[128];
- memset(address, 0, sizeof(address));
- buffer_read(&packet, address, length);
- if (inet_ntop(af, address, text_address, sizeof(text_address))) {
- buffer_printf(output, "%s%d:%s/%d",
- negated ? "!" : "",
- (int) address_family,
- text_address,
- (int) prefix);
- result = 1;
- }
- }
- }
- return result;
-}
-
/*
- * Print protocol and service numbers rather than names for Well-Know Services
- * (WKS) RRs. WKS RRs are deprecated, though not technically, and should not
- * be used. The parser supports tcp/udp for protocols and a small subset of
- * services because getprotobyname and/or getservbyname are marked MT-Unsafe
- * and locale. getprotobyname_r and getservbyname_r exist on some platforms,
- * but are still marked locale (meaning the locale object is used without
- * synchonization, which is a problem for a library). Failure to load a zone
- * on a primary server because of an unknown protocol or service name is
- * acceptable as the operator can opt to use the numeric value. Failure to
- * load a zone on a secondary server is problematic because "unsupported"
- * protocols and services might be written. Print the numeric value for
- * maximum compatibility.
- *
- * (see simdzone/generic/wks.h for details).
+ * Print salt, for NSEC3, in hex lowercase.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
*/
static int
-rdata_services_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_salt(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- int result = 0;
- buffer_type packet;
-
- buffer_create_from(
- &packet, rdata_atom_data(rdata), rdata_atom_size(rdata));
-
- if (buffer_available(&packet, 1)) {
- uint8_t protocol_number = buffer_read_u8(&packet);
- ssize_t bitmap_size = buffer_remaining(&packet);
- uint8_t *bitmap = buffer_current(&packet);
-
- buffer_printf(output, "%" PRIu8, protocol_number);
-
- for (int i = 0; i < bitmap_size * 8; ++i) {
- if (get_bit(bitmap, i)) {
- buffer_printf(output, " %d", i);
- }
- }
- buffer_skip(&packet, bitmap_size);
- result = 1;
- }
- return result;
-}
+ uint8_t length;
+ assert(rdlength >= *offset);
+ if (rdlength - *offset == 0)
+ return 0;
-static int
-rdata_ipsecgateway_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* rr)
-{
- switch(rdata_atom_data(rr->rdatas[1])[0]) {
- case IPSECKEY_NOGATEWAY:
- buffer_printf(output, ".");
- break;
- case IPSECKEY_IP4:
- return rdata_a_to_string(output, rdata, rr);
- case IPSECKEY_IP6:
- return rdata_aaaa_to_string(output, rdata, rr);
- case IPSECKEY_DNAME:
- return rdata_dns_name_to_string(output, rdata, rr);
- default:
+ length = rdata[*offset];
+ if (rdlength - *offset < 1 + length)
return 0;
- }
+ if (!length)
+ /* NSEC3 salt hex can be empty */
+ buffer_printf(output, "-");
+ else
+ buffer_print_hex(output, rdata + *offset + 1, length);
+ *offset += 1 + (uint16_t)length;
return 1;
}
-static int
-rdata_nxt_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
-{
- size_t i;
- uint8_t *bitmap = rdata_atom_data(rdata);
- size_t bitmap_size = rdata_atom_size(rdata);
-
- for (i = 0; i < bitmap_size * 8; ++i) {
- if (get_bit(bitmap, i)) {
- buffer_printf(output, "%s ", rrtype_to_string(i));
- }
+/* Return length of nsec type bitmap or -1 on wireformat error. offset is
+ * moved +len. rdlength is the length of the rdata, offset is offset in it. */
+static inline int32_t
+skip_nsec(struct buffer* packet, uint16_t rdlength, uint16_t *offset)
+{
+ uint16_t length = 0;
+ uint8_t last_window = 0;
+
+ while (rdlength - *offset - length > 2) {
+ uint8_t window = buffer_read_u8(packet);
+ uint8_t blocks = buffer_read_u8(packet);
+ if (length > 0 && window <= last_window)
+ return -1;
+ if (!blocks || blocks > 32)
+ return -1;
+ if (rdlength - *offset - length < 2 + blocks)
+ return -1;
+ buffer_skip(packet, blocks);
+ length += 2 + blocks;
+ last_window = window;
}
- buffer_skip(output, -1);
+ *offset += length;
+ if (rdlength != *offset)
+ return -1;
- return 1;
+ return length;
}
+/*
+ * Print nsec type bitmap, for the remainder of rdata.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_nsec_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_nsec_bitmap(struct buffer *output, uint16_t rdlength,
+ const uint8_t *rdata, uint16_t *offset)
{
- size_t saved_position = buffer_position(output);
- buffer_type packet;
int insert_space = 0;
- buffer_create_from(
- &packet, rdata_atom_data(rdata), rdata_atom_size(rdata));
-
- while (buffer_available(&packet, 2)) {
- uint8_t window = buffer_read_u8(&packet);
- uint8_t bitmap_size = buffer_read_u8(&packet);
- uint8_t *bitmap = buffer_current(&packet);
+ rdata += *offset;
+ while(rdlength - *offset > 0) {
+ uint8_t window, bitmap_size;
+ const uint8_t* bitmap;
int i;
- if (!buffer_available(&packet, bitmap_size)) {
- buffer_set_position(output, saved_position);
+ if(rdlength - *offset < 2)
+ return 0;
+ window = rdata[0];
+ bitmap_size = rdata[1];
+ *offset += 2;
+
+ if(rdlength - *offset < bitmap_size)
return 0;
- }
- for (i = 0; i < bitmap_size * 8; ++i) {
+ bitmap = rdata + 2;
+ rdata += 2;
+ for(i=0; i<((int)bitmap_size)*8; i++) {
if (get_bit(bitmap, i)) {
buffer_printf(output,
"%s%s",
@@ -683,152 +664,137 @@ rdata_nsec_to_string(buffer_type *output
insert_space = 1;
}
}
- buffer_skip(&packet, bitmap_size);
+ rdata += bitmap_size;
+ *offset += bitmap_size;
}
-
return 1;
}
+/* If an svcparam must have a value */
static int
-rdata_loc_to_string(buffer_type *ATTR_UNUSED(output),
- rdata_atom_type ATTR_UNUSED(rdata),
- rr_type* ATTR_UNUSED(rr))
+svcparam_must_have_value(uint16_t svcparamkey)
{
- /*
- * Returning 0 forces the record to be printed in unknown
- * format.
- */
- return 0;
-}
-
-static void
-buffer_print_svcparamkey(buffer_type *output, uint16_t svcparamkey)
-{
- if (svcparamkey < SVCPARAMKEY_COUNT)
- buffer_printf(output, "%s", svcparamkey_strs[svcparamkey]);
- else
- buffer_printf(output, "key%d", (int)svcparamkey);
+ switch (svcparamkey) {
+ case SVCB_KEY_ALPN:
+ case SVCB_KEY_PORT:
+ case SVCB_KEY_IPV4HINT:
+ case SVCB_KEY_IPV6HINT:
+ case SVCB_KEY_MANDATORY:
+ case SVCB_KEY_DOHPATH:
+ case SVCB_KEY_TLS_SUPPORTED_GROUPS:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
}
+/* If an svcparam must not have a value */
static int
-rdata_svcparam_port_to_string(buffer_type *output, uint16_t val_len,
- uint16_t *data)
+svcparam_must_not_have_value(uint16_t svcparamkey)
{
- if (val_len != 2)
- return 0; /* wireformat error, a short is 2 bytes */
- buffer_printf(output, "=%d", (int)ntohs(data[0]));
+ switch (svcparamkey) {
+ case SVCB_KEY_NO_DEFAULT_ALPN:
+ case SVCB_KEY_OHTTP:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+};
+
+/*
+ * Skip over the svcparams in the packet. Moves position.
+ * @param packet: wire packet, position at rdata fields of svcparams.
+ * @param rdlength: remaining rdata length in the packet.
+ * @return 0 on wireformat error.
+ */
+static inline int
+skip_svcparams(struct buffer *packet, uint16_t rdlength)
+{
+ unsigned pos = 0;
+ uint16_t key, count;
+ while(pos < rdlength) {
+ if(pos+4 > (unsigned)rdlength)
+ return 0;
+ if(!buffer_available(packet, 4))
+ return 0;
+ key = buffer_read_u16(packet);
+ count = buffer_read_u16(packet);
+ if(count == 0 && svcparam_must_have_value(key))
+ return 0;
+ if(count != 0 && svcparam_must_not_have_value(key))
+ return 0;
+ pos += 4;
+ if(pos+count > (unsigned)rdlength)
+ return 0;
+ if(!buffer_available(packet, count))
+ return 0;
+ buffer_skip(packet, count);
+ pos += count;
+ }
return 1;
}
-static int
-rdata_svcparam_ipv4hint_to_string(buffer_type *output, uint16_t val_len,
- uint16_t *data)
+/*
+ * Print svcparamkey name to the buffer, or unknown as key<NUM>.
+ * @param output: printed to string.
+ * @param svcparamkey: the key to print.
+ */
+static void
+buffer_print_svcparamkey(buffer_type *output, uint16_t svcparamkey)
{
- char ip_str[INET_ADDRSTRLEN + 1];
-
- assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
-
- if ((val_len % IP4ADDRLEN) == 0) {
- if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
- return 0; /* wireformat error, incorrect size or inet family */
-
- buffer_printf(output, "=%s", ip_str);
- data += IP4ADDRLEN / sizeof(uint16_t);
-
- while ((val_len -= IP4ADDRLEN) > 0) {
- if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
- return 0; /* wireformat error, incorrect size or inet family */
-
- buffer_printf(output, ",%s", ip_str);
- data += IP4ADDRLEN / sizeof(uint16_t);
- }
- return 1;
- } else
- return 0;
+ if (svcparamkey < sizeof(svcparams)/sizeof(svcparams[0]))
+ buffer_printf(output, "%s", svcparams[svcparamkey].name);
+ else
+ buffer_printf(output, "key%" PRIu16, svcparamkey);
}
static int
-rdata_svcparam_ipv6hint_to_string(buffer_type *output, uint16_t val_len,
- uint16_t *data)
+print_svcparam_no_value(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* ATTR_UNUSED(data), uint16_t ATTR_UNUSED(datalen))
{
- char ip_str[INET6_ADDRSTRLEN + 1];
-
- assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
-
- if ((val_len % IP6ADDRLEN) == 0) {
- if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
- return 0; /* wireformat error, incorrect size or inet family */
-
- buffer_printf(output, "=%s", ip_str);
- data += IP6ADDRLEN / sizeof(uint16_t);
-
- while ((val_len -= IP6ADDRLEN) > 0) {
- if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
- return 0; /* wireformat error, incorrect size or inet family */
-
- buffer_printf(output, ",%s", ip_str);
- data += IP6ADDRLEN / sizeof(uint16_t);
- }
- return 1;
- } else
- return 0;
+ buffer_print_svcparamkey(output, svcparamkey);
+ return 1;
}
static int
-rdata_svcparam_mandatory_to_string(buffer_type *output, uint16_t val_len,
- uint16_t *data)
+print_svcparam_mandatory(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
- assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
+ assert(datalen > 0); /* Guaranteed by svcparam_print */
- if (val_len % sizeof(uint16_t))
+ if (datalen % sizeof(uint16_t))
return 0; /* wireformat error, val_len must be multiple of shorts */
+ buffer_print_svcparamkey(output, svcparamkey);
buffer_write_u8(output, '=');
- buffer_print_svcparamkey(output, ntohs(*data));
- data += 1;
+ buffer_print_svcparamkey(output, read_uint16(data));
+ data += 2;
- while ((val_len -= sizeof(uint16_t))) {
+ while ((datalen -= sizeof(uint16_t))) {
buffer_write_u8(output, ',');
- buffer_print_svcparamkey(output, ntohs(*data));
- data += 1;
+ buffer_print_svcparamkey(output, read_uint16(data));
+ data += 2;
}
return 1;
}
static int
-rdata_svcparam_ech_to_string(buffer_type *output, uint16_t val_len,
- uint16_t *data)
-{
- int length;
-
- assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
-
- buffer_write_u8(output, '=');
-
- buffer_reserve(output, val_len * 2 + 1);
- length = __b64_ntop((uint8_t*) data, val_len,
- (char *) buffer_current(output), val_len * 2);
- if (length > 0) {
- buffer_skip(output, length);
- }
-
- return length != -1;
-}
-
-static int
-rdata_svcparam_alpn_to_string(buffer_type *output, uint16_t val_len,
- uint16_t *data)
+print_svcparam_alpn(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
uint8_t *dp = (void *)data;
- assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
+ assert(datalen > 0); /* Guaranteed by svcparam_print */
+ buffer_print_svcparamkey(output, svcparamkey);
buffer_write_u8(output, '=');
buffer_write_u8(output, '"');
- while (val_len) {
+ while (datalen) {
uint8_t i, str_len = *dp++;
- if (str_len > --val_len)
+ if (str_len > --datalen)
return 0;
for (i = 0; i < str_len; i++) {
@@ -845,7 +811,7 @@ rdata_svcparam_alpn_to_string(buffer_typ
buffer_write_u8(output, dp[i]);
}
dp += str_len;
- if ((val_len -= str_len))
+ if ((datalen -= str_len))
buffer_write_u8(output, ',');
}
buffer_write_u8(output, '"');
@@ -853,507 +819,3423 @@ rdata_svcparam_alpn_to_string(buffer_typ
}
static int
-rdata_svcparam_tls_supported_groups_to_string(buffer_type *output,
- uint16_t val_len, uint16_t *data)
+print_svcparam_port(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
- assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
-
- if ((val_len % sizeof(uint16_t)) == 1)
- return 0; /* A series of uint16_t is an even number of bytes */
-
- buffer_printf(output, "=%d", (int)ntohs(*data++));
- while ((val_len -= sizeof(uint16_t)) > 0)
- buffer_printf(output, ",%d", (int)ntohs(*data++));
+ if (datalen != 2)
+ return 0; /* wireformat error, a short is 2 bytes */
+ buffer_print_svcparamkey(output, svcparamkey);
+ buffer_printf(output, "=%d", (int)read_uint16(data));
return 1;
}
static int
-rdata_svcparam_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_svcparam_ipv4hint(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
- uint16_t size = rdata_atom_size(rdata);
- uint16_t* data = (uint16_t *)rdata_atom_data(rdata);
- uint16_t svcparamkey, val_len;
- uint8_t* dp;
- size_t i;
+ char ip_str[INET_ADDRSTRLEN + 1];
- if (size < 4)
- return 0;
- svcparamkey = ntohs(data[0]);
+ assert(datalen > 0); /* Guaranteed by svcparam_print */
buffer_print_svcparamkey(output, svcparamkey);
- val_len = ntohs(data[1]);
- if (size != val_len + 4)
- return 0; /* wireformat error */
- if (!val_len) {
- /* Some SvcParams MUST have values */
- switch (svcparamkey) {
- case SVCB_KEY_ALPN:
- case SVCB_KEY_PORT:
- case SVCB_KEY_IPV4HINT:
- case SVCB_KEY_IPV6HINT:
- case SVCB_KEY_MANDATORY:
- case SVCB_KEY_DOHPATH:
- case SVCB_KEY_TLS_SUPPORTED_GROUPS:
- return 0;
- default:
- return 1;
- }
- }
- switch (svcparamkey) {
- case SVCB_KEY_PORT:
- return rdata_svcparam_port_to_string(output, val_len, data+2);
- case SVCB_KEY_IPV4HINT:
- return rdata_svcparam_ipv4hint_to_string(output, val_len, data+2);
- case SVCB_KEY_IPV6HINT:
- return rdata_svcparam_ipv6hint_to_string(output, val_len, data+2);
- case SVCB_KEY_MANDATORY:
- return rdata_svcparam_mandatory_to_string(output, val_len, data+2);
- case SVCB_KEY_NO_DEFAULT_ALPN:
- return 0; /* wireformat error, should not have a value */
- case SVCB_KEY_ALPN:
- return rdata_svcparam_alpn_to_string(output, val_len, data+2);
- case SVCB_KEY_ECH:
- return rdata_svcparam_ech_to_string(output, val_len, data+2);
- case SVCB_KEY_OHTTP:
- return 0; /* wireformat error, should not have a value */
- case SVCB_KEY_TLS_SUPPORTED_GROUPS:
- return rdata_svcparam_tls_supported_groups_to_string(output, val_len, data+2);
- case SVCB_KEY_DOHPATH:
- /* fallthrough */
- default:
- buffer_write(output, "=\"", 2);
- dp = (void*) (data + 2);
+ if ((datalen % IP4ADDRLEN) == 0) {
+ if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
+ return 0; /* wireformat error, incorrect size or inet family */
- for (i = 0; i < val_len; i++) {
- if (dp[i] == '"' || dp[i] == '\\')
- buffer_printf(output, "\\%c", dp[i]);
+ buffer_printf(output, "=%s", ip_str);
+ data += IP4ADDRLEN;
- else if (!isprint(dp[i]))
- buffer_printf(output, "\\%03u", (unsigned) dp[i]);
+ while ((datalen -= IP4ADDRLEN) > 0) {
+ if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str))
+ == NULL)
+ return 0; /* wireformat error, incorrect size or inet family */
- else
- buffer_write_u8(output, dp[i]);
+ buffer_printf(output, ",%s", ip_str);
+ data += IP4ADDRLEN;
}
- buffer_write_u8(output, '"');
- break;
+ return 1;
}
- return 1;
+ return 0;
}
static int
-rdata_hip_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_svcparam_ech(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
- uint16_t size = rdata_atom_size(rdata);
- uint8_t hit_length;
- uint16_t pk_length;
- int length = 0;
+ int length;
- if(size < 4)
- return 0;
- hit_length = rdata_atom_data(rdata)[0];
- pk_length = read_uint16(rdata_atom_data(rdata) + 2);
- length = 4 + hit_length + pk_length;
- if(hit_length == 0 || pk_length == 0 || size < length)
- return 0;
- buffer_printf(output, "%u ", (unsigned)rdata_atom_data(rdata)[1]);
- hex_to_string(output, rdata_atom_data(rdata) + 4, hit_length);
- buffer_printf(output, " ");
- buffer_reserve(output, pk_length * 2 + 1);
- length = __b64_ntop(rdata_atom_data(rdata) + 4 + hit_length, pk_length,
- (char *) buffer_current(output), pk_length * 2);
+ buffer_print_svcparamkey(output, svcparamkey);
+ if(datalen == 0)
+ return 1;
+ buffer_write_u8(output, '=');
+
+ buffer_reserve(output, datalen * 2 + 1);
+ length = __b64_ntop(data, datalen, (char*)buffer_current(output),
+ datalen * 2);
if (length > 0) {
buffer_skip(output, length);
}
+
return length != -1;
}
static int
-rdata_atma_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_svcparam_ipv6hint(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
- uint16_t size = rdata_atom_size(rdata), i;
+ char ip_str[INET6_ADDRSTRLEN + 1];
- if(size < 2 || rdata_atom_data(rdata)[0] > 1)
- return 0;
- if(!rdata_atom_data(rdata)[0]) {
- hex_to_string(output, rdata_atom_data(rdata) + 1, size - 1);
+ assert(datalen > 0); /* Guaranteed by svcparam_print */
+
+ buffer_print_svcparamkey(output, svcparamkey);
+ if ((datalen % IP6ADDRLEN) == 0) {
+ if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
+ return 0; /* wireformat error, incorrect size or inet family */
+
+ buffer_printf(output, "=%s", ip_str);
+ data += IP6ADDRLEN;
+
+ while ((datalen -= IP6ADDRLEN) > 0) {
+ if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str))
+ == NULL)
+ return 0; /* wireformat error, incorrect size or inet family */
+
+ buffer_printf(output, ",%s", ip_str);
+ data += IP6ADDRLEN;
+ }
return 1;
}
- for(i = 1; i < size; i++) {
- if(!isdigit(rdata_atom_data(rdata)[i]))
- return 0;
- }
- buffer_write_u8(output, '+');
- buffer_write(output, rdata_atom_data(rdata) + 1, size - 1);
- return 1;
+ return 0;
}
static int
-rdata_amtrelay_d_type_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_svcparam_dohpath(struct buffer *output, uint16_t svcparamkey,
+ const uint8_t* data, uint16_t datalen)
{
- uint8_t data = *rdata_atom_data(rdata);
- buffer_printf(output , "%c %lu", (data & 0x80 ? '1' : '0'),
- ((unsigned long)data & 0x7f));
+ const uint8_t* dp = data;
+ unsigned i;
+
+ buffer_print_svcparamkey(output, svcparamkey);
+ buffer_write(output, "=\"", 2);
+ for (i = 0; i < datalen; i++) {
+ if (dp[i] == '"' || dp[i] == '\\')
+ buffer_printf(output, "\\%c", dp[i]);
+
+ else if (!isprint(dp[i]))
+ buffer_printf(output, "\\%03u", (unsigned) dp[i]);
+
+ else
+ buffer_write_u8(output, dp[i]);
+ }
+ buffer_write_u8(output, '"');
return 1;
}
static int
-rdata_amtrelay_relay_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* rr)
+print_svcparam_tls_supported_groups(struct buffer *output,
+ uint16_t svcparamkey, const uint8_t* data, uint16_t datalen)
{
- switch(rdata_atom_data(rr->rdatas[1])[0] & 0x7f) {
- case AMTRELAY_NOGATEWAY:
- break;
- case AMTRELAY_IP4:
- return rdata_a_to_string(output, rdata, rr);
- case AMTRELAY_IP6:
- return rdata_aaaa_to_string(output, rdata, rr);
- case AMTRELAY_DNAME:
- return rdata_dns_name_to_string(output, rdata, rr);
- default:
- return 0;
+ assert(datalen > 0); /* Guaranteed by svcparam_print */
+
+ if ((datalen % sizeof(uint16_t)) == 1)
+ return 0; /* A series of uint16_t is an even number of bytes */
+
+ buffer_print_svcparamkey(output, svcparamkey);
+ buffer_printf(output, "=%d", (int)read_uint16(data));
+ data += 2;
+ while ((datalen -= sizeof(uint16_t)) > 0) {
+ buffer_printf(output, ",%d", (int)read_uint16(data));
+ data += 2;
}
return 1;
}
+/*
+ * Print svcparam.
+ * @param output: the string is output here.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata. The rdata+*offset is where the field is.
+ * @param offset: the current position on input. The position is updated to
+ * be incremented with the length of rdata that was used.
+ * @return false on failure.
+ */
static int
-rdata_unknown_to_string(buffer_type *output, rdata_atom_type rdata,
- rr_type* ATTR_UNUSED(rr))
+print_svcparam(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
{
- uint16_t size = rdata_atom_size(rdata);
- buffer_printf(output, "\\# %lu ", (unsigned long) size);
- hex_to_string(output, rdata_atom_data(rdata), size);
+ uint16_t key, length;
+ const uint8_t* dp;
+ unsigned i;
+
+ assert(rdlength >= *offset);
+ if (rdlength - *offset < 4)
+ return 0;
+
+ key = read_uint16(rdata + *offset);
+ length = read_uint16(rdata + *offset + 2);
+
+ if (rdlength - *offset < length + 4)
+ return 0; /* wireformat error */
+
+ if(length == 0 && svcparam_must_have_value(key))
+ return 0;
+ if(length != 0 && svcparam_must_not_have_value(key))
+ return 0;
+ if (key < sizeof(svcparams)/sizeof(svcparams[0])) {
+ if(!svcparams[key].print_rdata(output, key, rdata+*offset+4, length))
+ return 0;
+ *offset += length+4;
+ return 1;
+ }
+
+ buffer_printf(output, "key%" PRIu16, key);
+ if (!length) {
+ *offset += 4;
+ return 1;
+ }
+
+ buffer_write(output, "=\"", 2);
+ dp = rdata + *offset + 4;
+
+ for (i = 0; i < length; i++) {
+ if (dp[i] == '"' || dp[i] == '\\')
+ buffer_printf(output, "\\%c", dp[i]);
+
+ else if (!isprint(dp[i]))
+ buffer_printf(output, "\\%03u", (unsigned) dp[i]);
+
+ else
+ buffer_write_u8(output, dp[i]);
+ }
+ buffer_write_u8(output, '"');
+ *offset += length + 4;
return 1;
}
-static rdata_to_string_type rdata_to_string_table[RDATA_ZF_UNKNOWN + 1] = {
- rdata_dname_to_string,
- rdata_dns_name_to_string,
- rdata_text_to_string,
- rdata_texts_to_string,
- rdata_byte_to_string,
- rdata_short_to_string,
- rdata_long_to_string,
- rdata_longlong_to_string,
- rdata_a_to_string,
- rdata_aaaa_to_string,
- rdata_rrtype_to_string,
- rdata_algorithm_to_string,
- rdata_certificate_type_to_string,
- rdata_period_to_string,
- rdata_time_to_string,
- rdata_base64_to_string,
- rdata_base32_to_string,
- rdata_hex_to_string,
- rdata_hexlen_to_string,
- rdata_nsap_to_string,
- rdata_apl_to_string,
- rdata_ipsecgateway_to_string,
- rdata_services_to_string,
- rdata_nxt_to_string,
- rdata_nsec_to_string,
- rdata_loc_to_string,
- rdata_ilnp64_to_string,
- rdata_eui48_to_string,
- rdata_eui64_to_string,
- rdata_long_text_to_string,
- rdata_unquoted_to_string,
- rdata_unquoteds_to_string,
- rdata_tag_to_string,
- rdata_svcparam_to_string,
- rdata_hip_to_string,
- rdata_atma_to_string,
- rdata_amtrelay_d_type_to_string,
- rdata_amtrelay_relay_to_string,
- rdata_unknown_to_string
-};
-
-int
-rdata_atom_to_string(buffer_type *output, rdata_zoneformat_type type,
- rdata_atom_type rdata, rr_type* record)
+static inline int32_t
+read_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
{
- return rdata_to_string_table[type](output, rdata, record);
+ if (buffer_remaining(packet) < rdlength)
+ return MALFORMED;
+ if (!(*rr = region_alloc(domains->region, sizeof(**rr) + rdlength)))
+ return TRUNCATED;
+ if(rdlength != 0)
+ buffer_read(packet, (*rr)->rdata, rdlength);
+ (*rr)->rdlength = rdlength;
+ return rdlength;
}
-ssize_t
-rdata_wireformat_to_rdata_atoms(region_type *region,
- domain_table_type *owners,
- uint16_t rrtype,
- uint16_t data_size,
- buffer_type *packet,
- rdata_atom_type **rdatas)
+int32_t
+read_generic_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
{
- size_t end = buffer_position(packet) + data_size;
- size_t i;
- rdata_atom_type temp_rdatas[MAXRDATALEN];
- rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype);
- region_type *temp_region;
-
- assert(descriptor->maximum <= MAXRDATALEN);
+ return read_rdata(domains, rdlength, packet, rr);
+}
- if (!buffer_available(packet, data_size)) {
- return -1;
- }
+void
+write_generic_rdata(struct query *query, const struct rr *rr)
+{
+ if(rr->rdlength != 0)
+ buffer_write(query->packet, rr->rdata, rr->rdlength);
+}
- temp_region = region_create(xalloc, free);
+int
+print_generic_rdata(struct buffer *output, const struct rr *rr)
+{
+ const nsd_type_descriptor_type* descriptor =
+ nsd_type_descriptor(rr->type);
+ return print_unknown_rdata_field(output, descriptor, rr);
+}
- for (i = 0; i < descriptor->maximum; ++i) {
- int is_domain = 0;
- int is_normalized = 0;
- int is_wirestore = 0;
- size_t length = 0;
- int required = i < descriptor->minimum;
-
- switch (rdata_atom_wireformat_type(rrtype, i)) {
- case RDATA_WF_COMPRESSED_DNAME:
- case RDATA_WF_UNCOMPRESSED_DNAME:
- is_domain = 1;
- is_normalized = 1;
- break;
- case RDATA_WF_LITERAL_DNAME:
- is_domain = 1;
- is_wirestore = 1;
- break;
- case RDATA_WF_BYTE:
- length = sizeof(uint8_t);
- break;
- case RDATA_WF_SHORT:
- length = sizeof(uint16_t);
- break;
- case RDATA_WF_LONG:
- length = sizeof(uint32_t);
- break;
- case RDATA_WF_LONGLONG:
- length = sizeof(uint64_t);
- break;
- case RDATA_WF_TEXTS:
- case RDATA_WF_LONG_TEXT:
- length = end - buffer_position(packet);
- break;
- case RDATA_WF_TEXT:
- case RDATA_WF_BINARYWITHLENGTH:
- /* Length is stored in the first byte. */
- length = 1;
- if (buffer_position(packet) + length <= end) {
- length += buffer_current(packet)[length - 1];
- }
- break;
- case RDATA_WF_A:
- length = sizeof(in_addr_t);
- break;
- case RDATA_WF_AAAA:
- length = IP6ADDRLEN;
- break;
- case RDATA_WF_ILNP64:
- length = IP6ADDRLEN/2;
- break;
- case RDATA_WF_EUI48:
- length = EUI48ADDRLEN;
- break;
- case RDATA_WF_EUI64:
- length = EUI64ADDRLEN;
+int
+lookup_rdata_field_entry(const nsd_type_descriptor_type* descriptor,
+ size_t index, const rr_type* rr, uint16_t offset, uint16_t* field_len,
+ struct domain** domain)
+{
+ const nsd_rdata_descriptor_type* field =
+ &descriptor->rdata.fields[index];
+ if(field->calculate_length) {
+ /* Call field length function. */
+ int32_t l = field->calculate_length(rr->rdlength, rr->rdata,
+ offset, domain);
+ if(l < 0)
+ return 0;
+ *field_len = l;
+ } else if(field->length >= 0) {
+ *field_len = field->length;
+ *domain = NULL;
+ } else {
+ size_t dlen;
+ int32_t flen;
+ if(offset > rr->rdlength)
+ return 0;
+ /* Handle the specialized value cases. */
+ switch(field->length) {
+ case RDATA_COMPRESSED_DNAME:
+ case RDATA_UNCOMPRESSED_DNAME:
+ if(rr->rdlength - offset <
+ (uint16_t)sizeof(void*))
+ return 0;
+ *field_len = sizeof(void*);
+ memcpy(domain, rr->rdata+offset, sizeof(void*));
break;
- case RDATA_WF_BINARY:
- /* Remaining RDATA is binary. */
- length = end - buffer_position(packet);
+ case RDATA_LITERAL_DNAME:
+ dlen = buf_dname_length(rr->rdata+offset,
+ rr->rdlength-offset);
+ if(dlen == 0)
+ return 0;
+ *field_len = dlen;
+ *domain = NULL;
break;
- case RDATA_WF_APL:
- length = (sizeof(uint16_t) /* address family */
- + sizeof(uint8_t) /* prefix */
- + sizeof(uint8_t)); /* length */
- if (buffer_position(packet) + length <= end) {
- /* Mask out negation bit. */
- length += (buffer_current(packet)[length - 1]
- & APL_LENGTH_MASK);
- }
+ case RDATA_STRING:
+ case RDATA_BINARY:
+ if(rr->rdlength - offset < 1)
+ return 0;
+ flen = (rr->rdata+offset)[0];
+ *field_len = flen+1;
+ *domain = NULL;
break;
- case RDATA_WF_IPSECGATEWAY:
- assert(i>1); /* we are past the gateway type */
- switch(rdata_atom_data(temp_rdatas[1])[0]) /* gateway type */ {
- default:
- case IPSECKEY_NOGATEWAY:
- length = 0;
- break;
- case IPSECKEY_IP4:
- length = IP4ADDRLEN;
- break;
- case IPSECKEY_IP6:
- length = IP6ADDRLEN;
- break;
- case IPSECKEY_DNAME:
- is_domain = 1;
- is_normalized = 1;
- is_wirestore = 1;
- break;
- }
+ case RDATA_IPSECGATEWAY:
+ case RDATA_AMTRELAY_RELAY:
+ return 0; /* Has a callback function. */
+ case RDATA_REMAINDER:
+ *field_len = rr->rdlength - offset;
+ *domain = NULL;
break;
- case RDATA_WF_SVCPARAM:
- length = 4;
- if (buffer_position(packet) + 4 <= end) {
- length +=
- read_uint16(buffer_current(packet) + 2);
- }
+ default:
+ /* Unknown specialized value. */
+ return 0;
+ }
+ }
+ if(offset + *field_len > rr->rdlength)
+ return 0; /* The field does not fit in the rdata. */
+ return 1;
+}
+
+int
+lookup_rdata_field_entry_uncompressed_wire(
+ const nsd_type_descriptor_type* descriptor, size_t index,
+ const uint8_t* rdata, uint16_t rdlength, uint16_t offset,
+ uint16_t* field_len, struct domain** domain)
+{
+ const nsd_rdata_descriptor_type* field =
+ &descriptor->rdata.fields[index];
+ if(field->calculate_length) {
+ /* Call field length function. */
+ int32_t l = field->calculate_length_uncompressed_wire(rdlength,
+ rdata, offset, domain);
+ if(l < 0)
+ return 0;
+ *field_len = l;
+ } else if(field->length >= 0) {
+ *field_len = field->length;
+ *domain = NULL;
+ } else {
+ size_t dlen;
+ int32_t flen;
+ if(offset > rdlength)
+ return 0;
+ /* Handle the specialized value cases. */
+ switch(field->length) {
+ case RDATA_COMPRESSED_DNAME:
+ case RDATA_UNCOMPRESSED_DNAME:
+ /* In the case that the field type is of type dname,
+ * since this function deals with uncompressed
+ * wireformat in the rdata buffer, the dname is
+ * going to be there as an uncompressed wireformat
+ * dname, for RDATA_COMPRESSED_DNAME and
+ * RDATA_UNCOMPRESSED_DNAME. */
+ case RDATA_LITERAL_DNAME:
+ dlen = buf_dname_length(rdata+offset, rdlength-offset);
+ if(dlen == 0)
+ return 0;
+ *field_len = dlen;
+ *domain = NULL;
break;
- case RDATA_WF_HIP:
- /* Length is stored in the first byte (HIT length)
- * plus the third and fourth byte (PK length) */
- length = 4;
- if (buffer_position(packet) + length <= end) {
- length += buffer_current(packet)[0];
- length += read_uint16(buffer_current(packet) + 2);
- }
+ case RDATA_STRING:
+ case RDATA_BINARY:
+ if(rdlength - offset < 1)
+ return 0;
+ flen = (rdata+offset)[0];
+ *field_len = flen+1;
+ *domain = NULL;
break;
- case RDATA_WF_AMTRELAY_RELAY:
- assert(i>1);
- switch(rdata_atom_data(temp_rdatas[1])[0] & 0x7f) /* relay type */ {
- default:
- case AMTRELAY_NOGATEWAY:
- length = 0;
- break;
- case AMTRELAY_IP4:
- length = IP4ADDRLEN;
- break;
- case AMTRELAY_IP6:
- length = IP6ADDRLEN;
- break;
- case AMTRELAY_DNAME:
- is_domain = 1;
- is_normalized = 1;
- is_wirestore = 1;
- break;
- }
+ case RDATA_IPSECGATEWAY:
+ case RDATA_AMTRELAY_RELAY:
+ return 0; /* Has a callback function. */
+ case RDATA_REMAINDER:
+ *field_len = rdlength - offset;
+ *domain = NULL;
break;
+ default:
+ /* Unknown specialized value. */
+ return 0;
}
- if (is_domain) {
- const dname_type *dname;
-
- if (!required && buffer_position(packet) == end) {
- break;
- }
-
- dname = dname_make_from_packet(
- temp_region, packet, 1, is_normalized);
- if (!dname || buffer_position(packet) > end) {
- /* Error in domain name. */
- region_destroy(temp_region);
- return -1;
- }
- if(is_wirestore) {
- temp_rdatas[i].data = (uint16_t *) region_alloc(
- region, sizeof(uint16_t) + ((size_t)dname->name_size));
- temp_rdatas[i].data[0] = dname->name_size;
- memcpy(temp_rdatas[i].data+1, dname_name(dname),
- dname->name_size);
- } else {
- temp_rdatas[i].domain
- = domain_table_insert(owners, dname);
- temp_rdatas[i].domain->usage ++;
- }
- } else {
- if (buffer_position(packet) + length > end) {
- if (required) {
- /* Truncated RDATA. */
- region_destroy(temp_region);
- return -1;
- } else {
- break;
- }
- }
- if (!required && buffer_position(packet) == end) {
- break;
- }
-
- temp_rdatas[i].data = (uint16_t *) region_alloc(
- region, sizeof(uint16_t) + length);
- temp_rdatas[i].data[0] = length;
- buffer_read(packet, temp_rdatas[i].data + 1, length);
- }
- }
-
- if (buffer_position(packet) < end) {
- /* Trailing garbage. */
- region_destroy(temp_region);
- return -1;
}
-
- *rdatas = (rdata_atom_type *) region_alloc_array_init(
- region, temp_rdatas, i, sizeof(rdata_atom_type));
- region_destroy(temp_region);
- return (ssize_t)i;
+ if(offset + *field_len > rdlength)
+ return 0; /* The field does not fit in the rdata. */
+ return 1;
}
-size_t
-rdata_maximum_wireformat_size(rrtype_descriptor_type *descriptor,
- size_t rdata_count,
- rdata_atom_type *rdatas)
+int32_t
+rr_calculate_uncompressed_rdata_length(const rr_type* rr)
{
- size_t result = 0;
size_t i;
- for (i = 0; i < rdata_count; ++i) {
- if (rdata_atom_is_domain(descriptor->type, i)) {
- result += domain_dname(rdata_atom_domain(rdatas[i]))->name_size;
+ const nsd_type_descriptor_type* descriptor =
+ nsd_type_descriptor(rr->type);
+ uint16_t offset = 0;
+ int32_t result = 0;
+ if(!descriptor->has_references)
+ return rr->rdlength; /* It does not really validate the
+ fields versus the rdlength. */
+ for(i=0; i < descriptor->rdata.length; i++) {
+ uint16_t field_len;
+ struct domain* domain;
+ if(rr->rdlength == offset &&
+ descriptor->rdata.fields[i].is_optional)
+ break; /* There are no more rdata fields. */
+ if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
+ &field_len, &domain))
+ return -1; /* malformed rdata buffer */
+ if(domain != NULL) {
+ /* Handle RDATA_COMPRESSED_DNAME and
+ * RDATA_UNCOMPRESSED_DNAME fields. */
+ const struct dname* dname = domain_dname(domain);
+ result += dname->name_size;
} else {
- result += rdata_atom_size(rdatas[i]);
+ result += field_len;
}
+ offset += field_len;
}
return result;
}
-int
-rdata_atoms_to_unknown_string(buffer_type *output,
- rrtype_descriptor_type *descriptor,
- size_t rdata_count,
- rdata_atom_type *rdatas)
+void
+rr_write_uncompressed_rdata(const rr_type* rr, uint8_t* buf, size_t len)
{
size_t i;
- size_t size =
- rdata_maximum_wireformat_size(descriptor, rdata_count, rdatas);
- buffer_printf(output, " \\# %lu ", (unsigned long) size);
- for (i = 0; i < rdata_count; ++i) {
- if (rdata_atom_is_domain(descriptor->type, i)) {
- const dname_type *dname =
- domain_dname(rdata_atom_domain(rdatas[i]));
- hex_to_string(
- output, dname_name(dname), dname->name_size);
+ const nsd_type_descriptor_type* descriptor =
+ nsd_type_descriptor(rr->type);
+ uint16_t offset = 0; /* The offset in rr->rdatas. */
+ size_t pos = 0; /* The position in buf. */
+ if(!descriptor->has_references) {
+ /* It does not really validate the fields versus the
+ * rdlength. */
+ if(rr->rdlength > len)
+ return; /* buffer too small */
+ memcpy(buf, rr->rdata, rr->rdlength);
+ return;
+ }
+ for(i=0; i < descriptor->rdata.length; i++) {
+ uint16_t field_len;
+ struct domain* domain;
+ if(rr->rdlength == offset &&
+ descriptor->rdata.fields[i].is_optional)
+ break; /* There are no more rdata fields. */
+ if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
+ &field_len, &domain))
+ return; /* malformed rdata buffer */
+ if(domain != NULL) {
+ /* Handle RDATA_COMPRESSED_DNAME and
+ * RDATA_UNCOMPRESSED_DNAME fields. */
+ const struct dname* dname = domain_dname(domain);
+ if(pos + dname->name_size > len)
+ return; /* buffer too small */
+ memcpy(buf+pos, dname_name(dname), dname->name_size);
+ pos += dname->name_size;
} else {
- hex_to_string(output, rdata_atom_data(rdatas[i]),
- rdata_atom_size(rdatas[i]));
+ if(pos + field_len > len)
+ return; /* buffer too small */
+ memcpy(buf+pos, rr->rdata+offset, field_len);
+ pos += field_len;
}
+ offset += field_len;
}
- return 1;
}
-int
-print_rdata(buffer_type *output, rrtype_descriptor_type *descriptor,
- rr_type *record)
+int print_unknown_rdata_field(buffer_type *output,
+ const nsd_type_descriptor_type *descriptor, const rr_type *rr)
{
size_t i;
- size_t saved_position = buffer_position(output);
+ int32_t size;
+ uint16_t length = 0;
+
+ if(!descriptor->has_references) {
+ /* There are no references to the domain table, the
+ * rdata can be printed literally. */
+ buffer_printf(output, "\\# %lu ", (unsigned long)rr->rdlength);
+ buffer_print_hex(output, rr->rdata, rr->rdlength);
+ return 1;
+ }
+
+ size = rr_calculate_uncompressed_rdata_length(rr);
+ if(size < 0)
+ return 0;
+ buffer_printf(output, "\\# %lu ", (unsigned long) size);
- for (i = 0; i < record->rdata_count; ++i) {
- if (i == 0) {
- buffer_printf(output, "\t");
- } else if (descriptor->type == TYPE_SOA && i == 2) {
- buffer_printf(output, " (\n\t\t");
+ for(i=0; i < descriptor->rdata.length; i++) {
+ uint16_t field_len;
+ struct domain* domain;
+ const uint8_t* to_print;
+ size_t to_print_len;
+ if(rr->rdlength == length &&
+ descriptor->rdata.fields[i].is_optional)
+ break; /* There are no more rdata fields. */
+ if(!lookup_rdata_field_entry(descriptor, i, rr, length,
+ &field_len, &domain))
+ return 0; /* malformed rdata buffer */
+ if(domain != NULL) {
+ /* Handle RDATA_COMPRESSED_DNAME and
+ * RDATA_UNCOMPRESSED_DNAME fields. */
+ const struct dname* dname = domain_dname(domain);
+ to_print = dname_name(dname);
+ to_print_len = dname->name_size;
} else {
- buffer_printf(output, " ");
+ to_print = rr->rdata+length;
+ to_print_len = field_len;
}
- if (!rdata_atom_to_string(
- output,
- (rdata_zoneformat_type) descriptor->zoneformat[i],
- record->rdatas[i], record))
- {
- buffer_set_position(output, saved_position);
+ buffer_print_hex(output, to_print, to_print_len);
+ length += field_len;
+ }
+ return 1;
+}
+
+int print_unknown_rdata(buffer_type *output,
+ const nsd_type_descriptor_type *descriptor, const rr_type *rr)
+{
+ buffer_printf(output, "\t");
+ return print_unknown_rdata_field(output, descriptor, rr);
+}
+
+int32_t
+read_compressed_name_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ if (!dname_make_from_packet_buffered(&dname, packet, 1, 1) ||
+ rdlength != buffer_position(packet) - mark)
+ return MALFORMED;
+ size = sizeof(**rr) + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ memcpy((*rr)->rdata, &domain, sizeof(void*));
+ (*rr)->rdlength = sizeof(void*);
+ return rdlength;
+}
+
+int32_t
+read_uncompressed_name_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ if (!dname_make_from_packet_buffered(&dname, packet,
+ 1 /* Lenient, allows pointers. */, 1) ||
+ rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ memcpy((*rr)->rdata, &domain, sizeof(void*));
+ (*rr)->rdlength = sizeof(void*);
+ return rdlength;
+}
+
+static void
+encode_dname(query_type *q, domain_type *domain)
+{
+ while (domain->parent && query_get_dname_offset(q, domain) == 0) {
+ query_put_dname_offset(q, domain, buffer_position(q->packet));
+ DEBUG(DEBUG_NAME_COMPRESSION, 2,
+ (LOG_INFO, "dname: %s, number: %lu, offset: %u\n",
+ domain_to_string(domain),
+ (unsigned long) domain->number,
+ query_get_dname_offset(q, domain)));
+ buffer_write(q->packet, dname_name(domain_dname(domain)),
+ label_length(dname_name(domain_dname(domain))) + 1U);
+ domain = domain->parent;
+ }
+ if (domain->parent) {
+ DEBUG(DEBUG_NAME_COMPRESSION, 2,
+ (LOG_INFO, "dname: %s, number: %lu, pointer: %u\n",
+ domain_to_string(domain),
+ (unsigned long) domain->number,
+ query_get_dname_offset(q, domain)));
+ assert(query_get_dname_offset(q, domain) <= MAX_COMPRESSION_OFFSET);
+ buffer_write_u16(q->packet,
+ 0xc000 | query_get_dname_offset(q, domain));
+ } else {
+ buffer_write_u8(q->packet, 0);
+ }
+}
+
+void
+write_compressed_name_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ assert(rr->rdlength == sizeof(void*));
+ memcpy(&domain, rr->rdata, sizeof(void*));
+ encode_dname(query, domain);
+}
+
+void
+write_uncompressed_name_rdata(struct query *query, const struct rr *rr)
+{
+ const struct dname *dname;
+ struct domain *domain;
+ assert(rr->rdlength >= sizeof(void*));
+ memcpy(&domain, rr->rdata, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int
+print_name_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ assert(rr->rdlength == sizeof(void*));
+ /* This prints a reference to a name stored as a pointer. */
+ return print_domain(output, rr->rdlength, rr->rdata, &length);
+}
+
+int32_t
+read_a_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_a_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ assert(rr->rdlength == 4);
+ return print_ip4(output, rr->rdlength, rr->rdata, &length);
+}
+
+int32_t
+read_soa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *primary_domain, *mailbox_domain;
+ struct dname_buffer primary, mailbox;
+ size_t size;
+
+ /* domain + domain + uint32 + uint32 + uint32 + uint32 + uint32 */
+ const size_t mark = buffer_position(packet);
+ if (!dname_make_from_packet_buffered(&primary, packet, 1, 1) ||
+ !dname_make_from_packet_buffered(&mailbox, packet, 1, 1) ||
+ rdlength != (buffer_position(packet) - mark) + 20)
+ return MALFORMED;
+
+ size = sizeof(**rr) + 2 * sizeof(void*) + 20;
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ primary_domain = domain_table_insert(domains, (void*)&primary);
+ primary_domain->usage++;
+ mailbox_domain = domain_table_insert(domains, (void*)&mailbox);
+ mailbox_domain->usage++;
+
+ memcpy((*rr)->rdata, &primary_domain, sizeof(void*));
+ memcpy((*rr)->rdata + sizeof(void*), &mailbox_domain, sizeof(void*));
+ buffer_read(packet, (*rr)->rdata + 2 * sizeof(void*), 20);
+ (*rr)->rdlength = 2 * sizeof(void*) + 20;
+ return rdlength;
+}
+
+void
+write_soa_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *primary, *mailbox;
+ /* domain + domain + uint32 + uint32 + uint32 + uint32 + uint32 */
+ assert(rr->rdlength == 2 * sizeof(void*) + 20);
+ memcpy(&primary, rr->rdata, sizeof(void*));
+ memcpy(&mailbox, rr->rdata + sizeof(void*), sizeof(void*));
+ encode_dname(query, primary);
+ encode_dname(query, mailbox);
+ buffer_write(query->packet, rr->rdata + (2 * sizeof(void*)), 20);
+}
+
+int
+print_soa_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ uint32_t serial, refresh, retry, expire, minimum;
+ assert(rr->rdlength == 2 * sizeof(void*) + 20);
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+
+ assert(length == 2 * sizeof(void*));
+ serial = read_uint32(rr->rdata + length);
+ refresh = read_uint32(rr->rdata + length + 4);
+ retry = read_uint32(rr->rdata + length + 8);
+ expire = read_uint32(rr->rdata + length + 12);
+ minimum = read_uint32(rr->rdata + length + 16);
+
+ buffer_printf(
+ output, " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32,
+ serial, refresh, retry, expire, minimum);
+ return 1;
+}
+
+int
+print_soa_rdata_twoline(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ uint32_t serial, refresh, retry, expire, minimum;
+ assert(rr->rdlength == 2 * sizeof(void*) + 20);
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+
+ assert(length == 2 * sizeof(void*));
+ serial = read_uint32(rr->rdata + length);
+ refresh = read_uint32(rr->rdata + length + 4);
+ retry = read_uint32(rr->rdata + length + 8);
+ expire = read_uint32(rr->rdata + length + 12);
+ minimum = read_uint32(rr->rdata + length + 16);
+
+ buffer_printf(
+ output, " (\n\t\t%" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " )",
+ serial, refresh, retry, expire, minimum);
+ return 1;
+}
+
+int32_t
+read_wks_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength < 5)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+/*
+ * Print protocol and service numbers rather than names for Well-Know Services
+ * (WKS) RRs. WKS RRs are deprecated, though not technically, and should not
+ * be used. The parser supports tcp/udp for protocols and a small subset of
+ * services because getprotobyname and/or getservbyname are marked MT-Unsafe
+ * and locale. getprotobyname_r and getservbyname_r exist on some platforms,
+ * but are still marked locale (meaning the locale object is used without
+ * synchonization, which is a problem for a library). Failure to load a zone
+ * on a primary server because of an unknown protocol or service name is
+ * acceptable as the operator can opt to use the numeric value. Failure to
+ * load a zone on a secondary server is problematic because "unsupported"
+ * protocols and services might be written. Print the numeric value for
+ * maximum compatibility.
+ *
+ * (see simdzone/generic/wks.h for details).
+ */
+int
+print_wks_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ uint8_t protocol;
+ int bits;
+ const uint8_t* bitmap;
+
+ if(rr->rdlength < 5)
+ return 0;
+ if (!print_ip4(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+
+ buffer_printf(output, " ");
+ protocol = rr->rdata[4];
+ if(protocol == 6)
+ buffer_printf(output, "tcp");
+ else if(protocol == 17)
+ buffer_printf(output, "udp");
+ else
+ buffer_printf(output, "%" PRIu8, protocol);
+
+ bits = (rr->rdlength - 5) * 8;
+ bitmap = rr->rdata + 5;
+ for (int service = 0; service < bits; service++) {
+ if (get_bit(bitmap, service))
+ buffer_printf(output, " %d", service);
+ }
+ return 1;
+}
+
+int32_t
+read_hinfo_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 0;
+ const size_t mark = buffer_position(packet);
+
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if (skip_string(packet, rdlength, &length) < 0
+ || skip_string(packet, rdlength, &length) < 0
+ || rdlength != length)
+ return MALFORMED;
+ buffer_set_position(packet, mark);
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_hinfo_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_minfo_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *rmailbx_domain, *emailbx_domain;
+ struct dname_buffer rmailbx, emailbx;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ if (buffer_remaining(packet) < rdlength ||
+ !dname_make_from_packet_buffered(&rmailbx, packet, 1, 1) ||
+ !dname_make_from_packet_buffered(&emailbx, packet, 1, 1) ||
+ rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 2 * sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ rmailbx_domain = domain_table_insert(domains, (void*)&rmailbx);
+ rmailbx_domain->usage++;
+ emailbx_domain = domain_table_insert(domains, (void*)&emailbx);
+ emailbx_domain->usage++;
+ memcpy((*rr)->rdata, &rmailbx_domain, sizeof(void*));
+ memcpy((*rr)->rdata + sizeof(void*), &emailbx_domain, sizeof(void*));
+ (*rr)->rdlength = 2 * sizeof(void*);
+ return rdlength;
+}
+
+void
+write_minfo_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *rmailbx, *emailbx;
+ assert(rr->rdlength == 2 * sizeof(void*));
+ memcpy(&rmailbx, rr->rdata, sizeof(void*));
+ memcpy(&emailbx, rr->rdata + sizeof(void*), sizeof(void*));
+ encode_dname(query, rmailbx);
+ encode_dname(query, emailbx);
+}
+
+int
+print_minfo_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ assert(rr->rdlength == 2 * sizeof(void*));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int32_t
+read_mx_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer exchange;
+ size_t size;
+
+ /* short + name */
+ const size_t mark = buffer_position(packet);
+ if (buffer_remaining(packet) < rdlength || rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 2);
+ if (!dname_make_from_packet_buffered(&exchange, packet, 1, 1))
+ return MALFORMED;
+ if (rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 2 + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return -1;
+ domain = domain_table_insert(domains, (void*)&exchange);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
+ (*rr)->rdlength = 2 + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_mx_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ assert(rr->rdlength == 2 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 2, sizeof(void*));
+ buffer_write(query->packet, rr->rdata, 2);
+ encode_dname(query, domain);
+}
+
+int
+print_mx_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+ assert(rr->rdlength > length);
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int32_t
+read_txt_rdata(struct domain_table *owners, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 0;
+ const size_t mark = buffer_position(packet);
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if (skip_strings(packet, rdlength, &length) < 0 || rdlength != length)
+ return MALFORMED;
+ buffer_set_position(packet, mark);
+ return read_rdata(owners, rdlength, packet, rr);
+}
+
+int
+print_txt_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if (length < rr->rdlength) {
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
return 0;
+ while (length < rr->rdlength) {
+ buffer_printf(output, " ");
+ if (!print_string(output, rr->rdlength, rr->rdata,
+ &length))
+ return 0;
}
}
- if (descriptor->type == TYPE_SOA) {
- buffer_printf(output, " )");
+ return 1;
+}
+
+int32_t
+read_rp_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *mbox_domain, *txt_domain;
+ struct dname_buffer mbox, txt;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ if (buffer_remaining(packet) < rdlength ||
+ !dname_make_from_packet_buffered(&mbox, packet, 1 /*lenient*/, 1) ||
+ !dname_make_from_packet_buffered(&txt, packet, 1 /*lenient*/, 1) ||
+ rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 2 * sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ mbox_domain = domain_table_insert(domains, (void*)&mbox);
+ mbox_domain->usage++;
+ txt_domain = domain_table_insert(domains, (void*)&txt);
+ txt_domain->usage++;
+ memcpy((*rr)->rdata, &mbox_domain, sizeof(void*));
+ memcpy((*rr)->rdata + sizeof(void*), &txt_domain, sizeof(void*));
+ (*rr)->rdlength = 2 * sizeof(void*);
+ return rdlength;
+}
+
+void
+write_rp_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *mbox_domain, *txt_domain;
+ const struct dname *mbox, *txt;
+
+ assert(rr->rdlength == 2 * sizeof(void*));
+ memcpy(&mbox_domain, rr->rdata, sizeof(void*));
+ memcpy(&txt_domain, rr->rdata + sizeof(void*), sizeof(void*));
+ mbox = domain_dname(mbox_domain);
+ txt = domain_dname(txt_domain);
+ buffer_write(query->packet, dname_name(mbox), mbox->name_size);
+ buffer_write(query->packet, dname_name(txt), txt->name_size);
+}
+
+int
+print_rp_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if(!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int32_t
+read_afsdb_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer hostname;
+ size_t size;
+ /* short + uncompressed name */
+ const size_t mark = buffer_position(packet);
+
+ if (buffer_remaining(packet) < rdlength || rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 2);
+ if (!dname_make_from_packet_buffered(&hostname, packet,
+ 1 /*lenient*/, 1) ||
+ rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 2 + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&hostname);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
+ (*rr)->rdlength = 2 + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_afsdb_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+
+ assert(rr->rdlength == 2 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 2, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, 2);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int
+print_afsdb_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t subtype, length=2;
+ assert(rr->rdlength == 2 + sizeof(void*));
+ subtype = read_uint16(rr->rdata);
+ buffer_printf(output, "%" PRIu16 " ", subtype);
+ if(!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ return 1;
+}
+
+int32_t
+read_x25_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 0;
+ const size_t mark = buffer_position(packet);
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if (skip_string(packet, rdlength, &length) < 0 || rdlength != length)
+ return MALFORMED;
+ buffer_set_position(packet, mark);
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_x25_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_isdn_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 0;
+ const size_t mark = buffer_position(packet);
+
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if (skip_string(packet, rdlength, &length) < 0)
+ return MALFORMED;
+ if(rdlength > length) {
+ /* Optional subaddress field is present. */
+ if (skip_string(packet, rdlength, &length) < 0
+ || rdlength != length)
+ return MALFORMED;
+ }
+ buffer_set_position(packet, mark);
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_isdn_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength > length) {
+ /* Optional subaddress field is present. */
+ buffer_printf(output, " ");
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ }
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_rt_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if (rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 2);
+ if (!dname_make_from_packet_buffered(&dname, packet, 1 /*lenient*/, 1))
+ return MALFORMED;
+ if (rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 2 + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return -1;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
+ (*rr)->rdlength = 2 + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_rt_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+
+ assert(rr->rdlength == 2 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 2, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, 2);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int
+print_nsap_rdata(struct buffer *output, const struct rr *rr)
+{
+ buffer_printf(output, "0x");
+ buffer_print_hex(output, rr->rdata, rr->rdlength);
+ return 1;
+}
+
+int
+print_nsap_ptr_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_key_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
+ read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_px_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *map822_domain, *mapx400_domain;
+ struct dname_buffer map822, mapx400;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ /* short + uncompressed name + uncompressed name */
+ if (buffer_remaining(packet) < rdlength ||
+ rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 2);
+ if(!dname_make_from_packet_buffered(&map822, packet,
+ 1 /*lenient*/, 1) ||
+ !dname_make_from_packet_buffered(&mapx400, packet,
+ 1 /*lenient*/, 1) ||
+ rdlength != buffer_position(packet) - mark)
+ return MALFORMED;
+
+ size = sizeof(**rr) + 2 + 2*sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ map822_domain = domain_table_insert(domains, (void*)&map822);
+ map822_domain->usage++;
+ mapx400_domain = domain_table_insert(domains, (void*)&mapx400);
+ mapx400_domain->usage++;
+
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata+2, &map822_domain, sizeof(void*));
+ memcpy((*rr)->rdata+2+sizeof(void*), &mapx400_domain, sizeof(void*));
+ (*rr)->rdlength = 2 + 2*sizeof(void*);
+ return rdlength;
+}
+
+void
+write_px_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *map822_domain, *mapx400_domain;
+ const struct dname *map822, *mapx400;
+
+ memcpy(&map822_domain, rr->rdata + 2, sizeof(void*));
+ memcpy(&mapx400_domain, rr->rdata + 2 + sizeof(void*), sizeof(void*));
+ map822 = domain_dname(map822_domain);
+ mapx400 = domain_dname(mapx400_domain);
+ buffer_write(query->packet, rr->rdata, 2);
+ buffer_write(query->packet, dname_name(map822), map822->name_size);
+ buffer_write(query->packet, dname_name(mapx400), mapx400->name_size);
+}
+
+int
+print_px_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+ assert(rr->rdlength > 3);
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int
+print_gpos_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_aaaa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 16)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_aaaa_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ assert(rr->rdlength == 16);
+ return print_ip6(output, rr->rdlength, rr->rdata, &length);
+}
+
+int32_t
+read_loc_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ size_t mark;
+ uint8_t version;
+ uint16_t size_version_0;
+
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ /* version (byte) */
+ if (rdlength < 1)
+ return MALFORMED;
+ /* version (byte) + size (byte)
+ * + horizontal precision (byte) + vertical precision (byte)
+ * + latitude (uint32) + longitude (uint32) + altitude (uint32) */
+ mark = buffer_position(packet);
+ version = buffer_read_u8_at(packet, mark + 0);
+ size_version_0 = 16u;
+ if (version == 0 && rdlength != size_version_0)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+/* Print the cm for LOC. */
+static void
+loc_cm_print(struct buffer* output, uint8_t mantissa, uint8_t exponent)
+{
+ uint8_t i;
+ /* is it 0.<two digits> ? */
+ if(exponent < 2) {
+ if(exponent == 1)
+ mantissa *= 10;
+ buffer_printf(output, "0.%02ld", (long)mantissa);
+ return;
+ }
+ /* always <digit><string of zeros> */
+ buffer_printf(output, "%d", (int)mantissa);
+ for(i=0; i<exponent-2; i++)
+ buffer_printf(output, "0");
+}
+
+int
+print_loc_rdata(struct buffer *output, const struct rr *rr)
+{
+ /* This does not perform checking (ie degrees < 90 etc). */
+ uint8_t version;
+ uint8_t size;
+ uint8_t horizontal_precision;
+ uint8_t vertical_precision;
+ uint32_t longitude;
+ uint32_t latitude;
+ uint32_t altitude;
+ char northerness;
+ char easterness;
+ uint32_t h;
+ uint32_t m;
+ double s;
+ uint32_t equator = (uint32_t)1 << 31; /* 2**31 */
+
+ if(rr->rdlength < 16)
+ return 0;
+ version = rr->rdata[0];
+ if(version != 0)
+ return 0;
+ size = rr->rdata[1];
+ horizontal_precision = rr->rdata[2];
+ vertical_precision = rr->rdata[3];
+
+ latitude = read_uint32(rr->rdata+4);
+ longitude = read_uint32(rr->rdata+8);
+ altitude = read_uint32(rr->rdata+12);
+
+ if (latitude > equator) {
+ northerness = 'N';
+ latitude = latitude - equator;
+ } else {
+ northerness = 'S';
+ latitude = equator - latitude;
+ }
+ h = latitude / (1000 * 60 * 60);
+ latitude = latitude % (1000 * 60 * 60);
+ m = latitude / (1000 * 60);
+ latitude = latitude % (1000 * 60);
+ s = (double) latitude / 1000.0;
+ buffer_printf(output, "%02u %02u %06.3f %c ",
+ h, m, s, northerness);
+
+ if (longitude > equator) {
+ easterness = 'E';
+ longitude = longitude - equator;
+ } else {
+ easterness = 'W';
+ longitude = equator - longitude;
+ }
+ h = longitude / (1000 * 60 * 60);
+ longitude = longitude % (1000 * 60 * 60);
+ m = longitude / (1000 * 60);
+ longitude = longitude % (1000 * 60);
+ s = (double) longitude / (1000.0);
+ buffer_printf(output, "%02u %02u %06.3f %c ",
+ h, m, s, easterness);
+
+ s = ((double) altitude) / 100;
+ s -= 100000;
+
+ if(altitude%100 != 0)
+ buffer_printf(output, "%.2f", s);
+ else
+ buffer_printf(output, "%.0f", s);
+ buffer_printf(output, "m ");
+
+ loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
+ buffer_printf(output, "m ");
+
+ loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
+ horizontal_precision & 0x0f);
+ buffer_printf(output, "m ");
+
+ loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
+ vertical_precision & 0x0f);
+ buffer_printf(output, "m");
+
+ return 1;
+}
+
+int32_t
+read_nxt_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ size_t size;
+ uint16_t bitmap_size;
+ const size_t mark = buffer_position(packet);
+
+ /* name + nxt */
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if (!dname_make_from_packet_buffered(&dname, packet, 1, 1))
+ return MALFORMED;
+ if(rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+ bitmap_size = rdlength - (buffer_position(packet) - mark);
+ size = sizeof(**rr) + sizeof(void*) + bitmap_size;
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ memcpy((*rr)->rdata, &domain, sizeof(void*));
+ if(bitmap_size != 0)
+ buffer_read(packet, (*rr)->rdata + sizeof(void*), bitmap_size);
+ (*rr)->rdlength = sizeof(void*) + bitmap_size;
+ return rdlength;
+}
+
+void
+write_nxt_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+
+ assert(rr->rdlength >= sizeof(void*));
+ memcpy(&domain, rr->rdata, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+ if(rr->rdlength - sizeof(void*) != 0)
+ buffer_write(query->packet, rr->rdata + sizeof(void*),
+ rr->rdlength - sizeof(void*));
+}
+
+int
+print_nxt_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ int bitmap_size;
+ const uint8_t* bitmap;
+
+ assert(rr->rdlength > sizeof(void*));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+
+ bitmap_size = rr->rdlength - length;
+ bitmap = rr->rdata + length;
+ for (int type = 0; type < bitmap_size * 8; type++) {
+ if (get_bit(bitmap, type)) {
+ buffer_printf(output, " %s", rrtype_to_string(type));
+ }
}
return 1;
}
+int
+print_eid_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_nimloc_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_srv_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ /* short + short + short + name */
+ if (buffer_remaining(packet) < rdlength || rdlength < 6)
+ return MALFORMED;
+ buffer_skip(packet, 6);
+ if (!dname_make_from_packet_buffered(&dname, packet,
+ 1 /* lenient */, 1) ||
+ rdlength != buffer_position(packet)-mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 6 + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 6);
+ memcpy((*rr)->rdata + 6, &domain, sizeof(void*));
+ (*rr)->rdlength = 6 + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_srv_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+
+ assert(rr->rdlength == 6 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 6, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, 6);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int
+print_srv_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 6;
+ assert(rr->rdlength > length);
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu16 " %" PRIu16 " ",
+ read_uint16(rr->rdata), read_uint16(rr->rdata+2),
+ read_uint16(rr->rdata+4));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int
+print_atma_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint8_t format;
+ if(rr->rdlength < 1)
+ return 0;
+ format = rr->rdata[0];
+ if(format == 0) {
+ /* AESA format (ATM End System Address). */
+ uint16_t length = 1;
+ if (!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+ } else if(format == 1) {
+ /* E.164 format. */
+ /* '+' and then digits '0'-'9' from the rdata string. */
+ buffer_printf(output, "+");
+ for (size_t i = 1; i < rr->rdlength; i++) {
+ char ch = (char)rr->rdata[i];
+ if(!isdigit((unsigned char)ch))
+ return 0;
+ buffer_printf(output, "%c", ch);
+ }
+ return 1;
+ }
+ /* Unknown format. */
+ return 0;
+}
+
+int32_t
+read_naptr_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ uint16_t length = 4;
+ size_t size;
+ const size_t mark = buffer_position(packet);
+
+ /* short + short + text + text + text + name */
+ if (buffer_remaining(packet) < rdlength ||
+ rdlength < length)
+ return MALFORMED;
+ buffer_skip(packet, 4);
+ if(skip_string(packet, rdlength, &length) < 0 ||
+ skip_string(packet, rdlength, &length) < 0 ||
+ skip_string(packet, rdlength, &length) < 0 ||
+ !dname_make_from_packet_buffered(&dname, packet, 1, 1) ||
+ rdlength != buffer_position(packet) - mark)
+ return MALFORMED;
+
+ size = sizeof(**rr) + length + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, length);
+ memcpy((*rr)->rdata + length, &domain, sizeof(void*));
+ (*rr)->rdlength = length + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_naptr_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+ uint16_t length;
+
+ /* short + short + string + string + string + uncompressed name */
+ assert(rr->rdlength >= 7 + sizeof(void*));
+ length = rr->rdlength - sizeof(void*);
+ memcpy(&domain, rr->rdata + length, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, length);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int
+print_naptr_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ assert(rr->rdlength >= 7 + sizeof(void*));
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu16 " ",
+ read_uint16(rr->rdata), read_uint16(rr->rdata+2));
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int32_t
+read_kx_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer dname;
+ const size_t mark = buffer_position(packet);
+ size_t size;
+
+ /* short + uncompressed name */
+ if(buffer_remaining(packet) < rdlength || rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 2);
+ if(!dname_make_from_packet_buffered(&dname, packet,
+ 1 /* lenient */, 1) ||
+ rdlength != buffer_position(packet) - mark)
+ return MALFORMED;
+
+ size = sizeof(**rr) + 2 + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&dname);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
+ (*rr)->rdlength = 2 + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_kx_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+
+ /* short + uncompressed name */
+ assert(rr->rdlength == 2 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 2, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, 2);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int32_t
+read_cert_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + short + byte + binary */
+ if (rdlength < 5)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_cert_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(rr->rdlength < 5)
+ return 0;
+ if(!print_certificate_type(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " %" PRIu16 " %" PRIu8 " ",
+ read_uint16(rr->rdata+2), rr->rdata[4]);
+ length += 3;
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_sink_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+ if(rr->rdlength < 2)
+ return 0;
+ buffer_printf(output, "%" PRIu8 " %" PRIu8 " ",
+ rr->rdata[0], rr->rdata[1]);
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_apl_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 0;
+ const uint8_t *rdata = buffer_current(packet);
+
+ if (buffer_remaining(packet) < rdlength)
+ return MALFORMED;
+ while (rdlength - length >= 4) {
+ uint8_t afdlength = rdata[length + 3] & APL_LENGTH_MASK;
+ if (rdlength - (length + 4) < afdlength)
+ return MALFORMED;
+ length += 4 + afdlength;
+ }
+
+ if (length != rdlength)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+/*
+ * Print one APL field.
+ * @param output: string is printed to the buffer.
+ * @param rdlength: length of rdata.
+ * @param rdata: the rdata
+ * @param offset: on input the current position, adjusted on output to
+ * increment for the rdata used.
+ * @return false on failure.
+ */
+static int
+print_apl(struct buffer *output, size_t rdlength, const uint8_t *rdata,
+ uint16_t *offset)
+{
+ size_t size = rdlength - *offset;
+ uint16_t address_family;
+ uint8_t prefix, length, negated;
+ int af;
+ char text_address[INET6_ADDRSTRLEN + 1];
+ uint8_t address[16];
+
+ if (size < 4)
+ return 0;
+
+ address_family = read_uint16(rdata + *offset);
+ prefix = rdata[*offset + 2];
+ length = rdata[*offset + 3] & APL_LENGTH_MASK;
+ negated = rdata[*offset + 3] & APL_NEGATION_MASK;
+ af = -1;
+
+ switch (address_family) {
+ case 1: af = AF_INET; break;
+ case 2: af = AF_INET6; break;
+ }
+
+ if (af == -1 || size - 4 < length)
+ return 0;
+
+ memset(address, 0, sizeof(address));
+ memmove(address, rdata + *offset + 4, length);
+
+ if (!inet_ntop(af, address, text_address, sizeof(text_address)))
+ return 0;
+
+ buffer_printf(
+ output, "%s%" PRIu16 ":%s/%" PRIu8,
+ (negated ? "!" : ""), address_family, text_address, prefix);
+ *offset += 4 + length;
+ return 1;
+}
+
+int
+print_apl_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+
+ while (length < rr->rdlength) {
+ if(length != 0)
+ buffer_printf(output, " ");
+ if (!print_apl(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ }
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_ds_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + byte + byte + binary */
+ if (rdlength < 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_ds_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
+ read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
+ if (!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_sshfp_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* byte + byte + binary */
+ if (rdlength < 2)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_sshfp_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+ uint8_t algorithm, ftype;
+
+ if(rr->rdlength < length)
+ return 0;
+ algorithm = rr->rdata[0];
+ ftype = rr->rdata[1];
+
+ buffer_printf(output, "%" PRIu8 " %" PRIu8 " ", algorithm, ftype);
+ if (!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_ipseckey_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct dname_buffer gateway;
+ const uint8_t *gateway_rdata;
+ uint8_t gateway_length = 0;
+ const size_t mark = buffer_position(packet);
+ uint16_t keylen;
+
+ /* byte + byte + byte + gateway + binary */
+ if (buffer_remaining(packet) < rdlength || rdlength < 3)
+ return MALFORMED;
+
+ buffer_skip(packet, 3);
+
+ switch (buffer_read_u8_at(packet, mark + 1)) {
+ case IPSECKEY_NOGATEWAY:
+ gateway_length = 0;
+ gateway_rdata = NULL;
+ break;
+ case IPSECKEY_IP4:
+ gateway_length = 4;
+ gateway_rdata = buffer_current(packet);
+ if (rdlength < 3 + gateway_length)
+ return MALFORMED;
+ buffer_skip(packet, gateway_length);
+ break;
+ case IPSECKEY_IP6:
+ gateway_length = 16;
+ gateway_rdata = buffer_current(packet);
+ if (rdlength < 3 + gateway_length)
+ return MALFORMED;
+ buffer_skip(packet, gateway_length);
+ break;
+ case IPSECKEY_DNAME:
+ /* The dname is stored as literal dname. On the wire
+ * skip possibly compressed format, in the rdata there
+ * is an uncompressed wire format. */
+ if (!dname_make_from_packet_buffered(&gateway, packet,
+ 1 /* lenient */, 0))
+ return MALFORMED;
+ if(rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+ gateway_length = gateway.dname.name_size;
+ gateway_rdata = dname_name((void*)&gateway);
+ break;
+ default:
+ return MALFORMED;
+ }
+ keylen = rdlength - (buffer_position(packet)-mark);
+
+ if (!(*rr = region_alloc(domains->region,
+ sizeof(**rr) + 3 + gateway_length + keylen)))
+ return TRUNCATED;
+
+ buffer_read_at(packet, mark, (*rr)->rdata, 3);
+ if(gateway_rdata)
+ memcpy((*rr)->rdata + 3, gateway_rdata, gateway_length);
+ if(keylen != 0)
+ buffer_read(packet, (*rr)->rdata + 3 + gateway_length, keylen);
+ (*rr)->rdlength = 3 + gateway_length + keylen;
+ return rdlength;
+}
+
+int
+print_ipseckey_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 3;
+ uint8_t gateway_type;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu8 " %" PRIu8 " %" PRIu8 " ",
+ rr->rdata[0], rr->rdata[1], rr->rdata[2]);
+ gateway_type = rr->rdata[1];
+ switch (gateway_type) {
+ case IPSECKEY_NOGATEWAY:
+ buffer_printf(output, ".");
+ break;
+ case IPSECKEY_IP4:
+ if (!print_ip4(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ break;
+ case IPSECKEY_IP6:
+ if (!print_ip6(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ break;
+ case IPSECKEY_DNAME:
+ if (!print_name_literal(output, rr->rdlength, rr->rdata,
+ &length))
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ if(rr->rdlength > length) {
+ /* Print key field in base64. */
+ buffer_printf(output, " ");
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ }
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+ipseckey_gateway_length(uint16_t rdlength, const uint8_t *rdata,
+ uint16_t offset, struct domain** domain)
+{
+ /* The ipseckey gateway length depends only on earlier bytes, so both
+ * the in-memory and uncompressed wireformat refer to the same
+ * earlier bytes. Also the domain name is stored literally, so it
+ * does not need to return a reference. */
+ uint8_t gateway_type;
+ *domain = NULL;
+ /* Calculate the gateway length, based on the gateway type.
+ * That is stored in an earlier field. */
+ if(rdlength < 3 || offset < 3)
+ return -1; /* too short */
+ gateway_type = rdata[1];
+ switch(gateway_type) {
+ case IPSECKEY_NOGATEWAY:
+ return 0;
+ case IPSECKEY_IP4:
+ return 4;
+ case IPSECKEY_IP6:
+ return 16;
+ case IPSECKEY_DNAME:
+ return buf_dname_length(rdata+offset, rdlength-offset);
+ default:
+ /* Unknown gateway type. */
+ break;
+ }
+ return -1;
+}
+
+int32_t
+read_rrsig_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct dname_buffer signer;
+ const size_t mark = buffer_position(packet);
+ uint16_t memrdlen, b64len;
+
+ /* short + byte + byte + uint32 + uint32 + uint32 + short */
+ if (buffer_remaining(packet) < rdlength || rdlength < 18)
+ return MALFORMED;
+ buffer_skip(packet, 18);
+ if (!dname_make_from_packet_buffered(&signer, packet,
+ 1 /* lenient */, 0))
+ return MALFORMED;
+ if (rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+ memrdlen = 18 + signer.dname.name_size;
+ b64len = rdlength - (buffer_position(packet) - mark);
+ if (!(*rr = region_alloc(domains->region, sizeof(**rr) + memrdlen + b64len)))
+ return TRUNCATED;
+ buffer_read_at(packet, mark, (*rr)->rdata, 18);
+ memcpy((*rr)->rdata + 18, dname_name((void*)&signer),
+ signer.dname.name_size);
+ if(b64len != 0)
+ buffer_read(packet, (*rr)->rdata+memrdlen, b64len);
+ (*rr)->rdlength = memrdlen + b64len;
+ return rdlength;
+}
+
+int
+print_rrsig_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 8;
+
+ if(rr->rdlength < 18)
+ return 0;
+ buffer_printf(
+ output, "%s %" PRIu8 " %" PRIu8 " %" PRIu32 " ",
+ rrtype_to_string(read_uint16(rr->rdata)), rr->rdata[2],
+ rr->rdata[3], read_uint32(rr->rdata+4));
+ if (!print_time(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_time(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+
+ buffer_printf(output, " %" PRIu16 " ", read_uint16(rr->rdata+length));
+ length += 2;
+
+ if (!print_name_literal(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_nsec_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct dname_buffer next;
+ uint16_t length, memrdlen, bitmaplen;
+ size_t bitmapmark;
+ const size_t mark = buffer_position(packet);
+
+ /* uncompressed name + nsec */
+ if(buffer_remaining(packet) < rdlength ||
+ !dname_make_from_packet_buffered(&next, packet,
+ 1 /* lenient */, 0 /* The NSEC record can have a non normalized
+ dname as the next owner name. And if so this should be
+ preserved, so that the RRSIG verifies. */ ) ||
+ rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+
+ bitmapmark = buffer_position(packet);
+ length = bitmapmark - mark;
+ if (skip_nsec(packet, rdlength, &length) < 0
+ || rdlength != length)
+ return MALFORMED;
+ bitmaplen = buffer_position(packet) - bitmapmark;
+ memrdlen = next.dname.name_size + bitmaplen;
+ if (!(*rr = region_alloc(domains->region, sizeof(**rr) + memrdlen)))
+ return TRUNCATED;
+ memcpy((*rr)->rdata, dname_name((void*)&next), next.dname.name_size);
+ if(bitmaplen != 0)
+ buffer_read_at(packet, bitmapmark,
+ (*rr)->rdata + next.dname.name_size, bitmaplen);
+ (*rr)->rdlength = memrdlen;
+ return rdlength;
+}
+
+int
+print_nsec_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+
+ if (!print_name_literal(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_dnskey_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + byte + byte + binary of remainder */
+ if (rdlength < 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_dnskey_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
+ read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_dhcid_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + byte + digest */
+ if (rdlength < 3)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_dhcid_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_nsec3_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 4;
+ /* byte + byte + short + string + string + binary */
+ const size_t mark = buffer_position(packet);
+
+ if (buffer_remaining(packet) < rdlength || rdlength < length)
+ return MALFORMED;
+ buffer_skip(packet, length);
+ if (skip_string(packet, rdlength, &length) < 0 ||
+ skip_string(packet, rdlength, &length) < 0 ||
+ skip_nsec(packet, rdlength, &length) < 0 ||
+ rdlength != length)
+ return MALFORMED;
+ buffer_set_position(packet, mark);
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_nsec3_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu8 " %" PRIu8 " %" PRIu16 " ",
+ rr->rdata[0], rr->rdata[1], read_uint16(rr->rdata + 2));
+ if (!print_salt(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_base32(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_nsec3param_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ uint16_t length = 4;
+ /* byte + byte + short + string */
+ const size_t mark = buffer_position(packet);
+
+ if (buffer_remaining(packet) < rdlength || rdlength < length)
+ return MALFORMED;
+ buffer_skip(packet, length);
+ if (skip_string(packet, rdlength, &length) < 0 ||
+ rdlength != length)
+ return MALFORMED;
+ buffer_set_position(packet, mark);
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_nsec3param_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu8 " %" PRIu8 " %" PRIu16 " ",
+ rr->rdata[0], rr->rdata[1], read_uint16(rr->rdata + 2));
+
+ if (!print_salt(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_tlsa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* byte + byte + byte + binary */
+ if (rdlength < 3)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_tlsa_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 3;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu8 " %" PRIu8 " %" PRIu8 " ",
+ rr->rdata[0], rr->rdata[1], rr->rdata[2]);
+
+ if (!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_hip_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* byte (hit length) + byte (PK algorithm) + short (PK length) +
+ * HIT(hex) + pubkey(base64) + rendezvous servers(literal dnames) */
+ if (rdlength < 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_hip_rdata(struct buffer *output, const struct rr *rr)
+{
+ /* byte (hit length) + byte (PK algorithm) + short (PK length) +
+ * HIT(hex) + pubkey(base64) + rendezvous servers(literal dnames) */
+ uint8_t hit_length, pk_algorithm;
+ uint16_t pk_length;
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ hit_length = rr->rdata[0];
+ pk_algorithm = rr->rdata[1];
+ pk_length = read_uint16(rr->rdata+2);
+ buffer_printf(output, "%" PRIu8 " ", pk_algorithm);
+ if(!print_base16(output, length+hit_length, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if(!print_base64(output, length+pk_length, rr->rdata, &length))
+ return 0;
+ while(length < rr->rdlength) {
+ buffer_printf(output, " ");
+ if(!print_name_literal(output, rr->rdlength, rr->rdata,
+ &length))
+ return 0;
+ }
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_rkey_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + byte + byte + binary of remainder */
+ if (rdlength < 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_rkey_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
+ read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_talink_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct dname_buffer prev, next;
+ const size_t mark = buffer_position(packet);
+ if(!buffer_available(packet, rdlength))
+ return MALFORMED;
+ if(!dname_make_from_packet_buffered(&prev, packet,
+ 1 /* lenient */, 0))
+ return MALFORMED;
+ if(buffer_position(packet)-mark > rdlength)
+ return MALFORMED;
+ if(!dname_make_from_packet_buffered(&next, packet,
+ 1 /* lenient */, 0))
+ return MALFORMED;
+ if(buffer_position(packet)-mark != rdlength)
+ return MALFORMED;
+ if (!(*rr = region_alloc(domains->region,
+ sizeof(**rr) + prev.dname.name_size + next.dname.name_size)))
+ return TRUNCATED;
+ memcpy((*rr)->rdata, dname_name((void*)&prev), prev.dname.name_size);
+ memcpy((*rr)->rdata + prev.dname.name_size, dname_name((void*)&next),
+ next.dname.name_size);
+ (*rr)->rdlength = prev.dname.name_size + next.dname.name_size;
+ return rdlength;
+}
+
+int
+print_talink_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_name_literal(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if(!print_name_literal(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_openpgpkey_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+
+ if (!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_csync_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* long + short + binary bitmap in remainder */
+ if (rdlength < 6)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_csync_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 6;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu32 " %" PRIu16 " ",
+ read_uint32(rr->rdata), read_uint16(rr->rdata + 4));
+ if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_zonemd_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* long + byte + byte + binary */
+ if (rdlength < 6)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_zonemd_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 6;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu32 " %" PRIu8 " %" PRIu8 " ",
+ read_uint32(rr->rdata), rr->rdata[4], rr->rdata[5]);
+ if (!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_svcb_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer target;
+ uint16_t length = 2, svcparams_length = 0;
+ uint16_t size;
+ const size_t mark = buffer_position(packet);
+
+ /* short + name + svc_params */
+ if (buffer_remaining(packet) < rdlength || rdlength < length)
+ return MALFORMED;
+ buffer_skip(packet, length);
+ if (!dname_make_from_packet_buffered(&target, packet,
+ 1 /* lenient */, 1))
+ return MALFORMED;
+ if(rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+ length = buffer_position(packet)-mark;
+ /* For secondary, the server should accept the wireformat more
+ * leniently. So this check is skipped. */
+ /*
+ if(!skip_svcparams(packet, rdlength-length))
+ return MALFORMED;
+ if(rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+ */
+ svcparams_length = rdlength - length;
+ buffer_skip(packet, svcparams_length);
+
+ size = sizeof(**rr) + 2 + sizeof(void*) + svcparams_length;
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&target);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
+ if(svcparams_length != 0)
+ buffer_read_at(packet, mark + length,
+ (*rr)->rdata + 2 + sizeof(void*), svcparams_length);
+ (*rr)->rdlength = 2 + sizeof(void*) + svcparams_length;
+ return rdlength;
+}
+
+void
+write_svcb_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *target;
+ uint8_t length;
+
+ assert(rr->rdlength >= 2 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 2, sizeof(void*));
+ target = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, 2);
+ buffer_write(query->packet, dname_name(target), target->name_size);
+ length = 2 + sizeof(void*);
+ if(rr->rdlength > length)
+ buffer_write(query->packet, rr->rdata + length,
+ rr->rdlength - length);
+}
+
+int
+print_svcb_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+
+ assert(rr->rdlength > length); /* It has 2+sizeof(void*) at least. */
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ while (length < rr->rdlength) {
+ buffer_printf(output, " ");
+ if (!print_svcparam(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ }
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_dsync_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct dname_buffer target;
+ uint16_t length = 5;
+ const size_t mark = buffer_position(packet);
+
+ /* type + byte + short + literaldname */
+ if (buffer_remaining(packet) < rdlength || rdlength < length)
+ return MALFORMED;
+ buffer_skip(packet, length);
+ if(!dname_make_from_packet_buffered(&target, packet,
+ 1 /* lenient */, 0) ||
+ rdlength != buffer_position(packet) - mark)
+ return MALFORMED;
+ length += target.dname.name_size;
+
+ if (!(*rr = region_alloc(domains->region, sizeof(**rr)+length)))
+ return TRUNCATED;
+ buffer_read_at(packet, mark, (*rr)->rdata, 5);
+ memcpy((*rr)->rdata + 5, dname_name((void*)&target),
+ target.dname.name_size);
+ (*rr)->rdlength = length;
+ return rdlength;
+}
+
+int
+print_dsync_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 5;
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(output, "%s %" PRIu8 " %" PRIu16 " ",
+ rrtype_to_string(read_uint16(rr->rdata)), rr->rdata[2],
+ read_uint16(rr->rdata+3));
+ if(!print_name_literal(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_nid_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 10)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_nid_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+
+ if(rr->rdlength != 10)
+ return 0;
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_ilnp64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_l32_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 6)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_l32_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+
+ if(rr->rdlength != 6)
+ return 0;
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_ip4(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_l64_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 10)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_l64_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+
+ if(rr->rdlength != 10)
+ return 0;
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_ilnp64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_lp_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct domain *domain;
+ struct dname_buffer target;
+ size_t size;
+ /* short + name */
+ const size_t mark = buffer_position(packet);
+
+ if (buffer_remaining(packet) < rdlength || rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 2);
+ if (!dname_make_from_packet_buffered(&target, packet,
+ 1 /* lenient */, 1) ||
+ rdlength != buffer_position(packet) - mark)
+ return MALFORMED;
+ size = sizeof(**rr) + 2 + sizeof(void*);
+ if (!(*rr = region_alloc(domains->region, size)))
+ return TRUNCATED;
+ domain = domain_table_insert(domains, (void*)&target);
+ domain->usage++;
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
+ (*rr)->rdlength = 2 + sizeof(void*);
+ return rdlength;
+}
+
+void
+write_lp_rdata(struct query *query, const struct rr *rr)
+{
+ struct domain *domain;
+ const struct dname *dname;
+
+ /* short + uncompressed name */
+ assert(rr->rdlength == 2 + sizeof(void*));
+ memcpy(&domain, rr->rdata + 2, sizeof(void*));
+ dname = domain_dname(domain);
+ buffer_write(query->packet, rr->rdata, 2);
+ buffer_write(query->packet, dname_name(dname), dname->name_size);
+}
+
+int
+print_lp_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+
+ assert(rr->rdlength == 2 + sizeof(void*));
+ buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
+ if (!print_domain(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ assert(rr->rdlength == length);
+ return 1;
+}
+
+int32_t
+read_eui48_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 6)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_eui48_rdata(struct buffer *output, const struct rr *rr)
+{
+ const uint8_t *x = rr->rdata;
+ if(rr->rdlength != 6)
+ return 0;
+ buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
+ x[0], x[1], x[2], x[3], x[4], x[5]);
+ return 1;
+}
+
+int32_t
+read_eui64_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ if (rdlength != 8)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_eui64_rdata(struct buffer *output, const struct rr *rr)
+{
+ const uint8_t *x = rr->rdata;
+ if(rr->rdlength != 8)
+ return 0;
+ buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
+ x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
+ return 1;
+}
+
+int32_t
+read_uri_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + short + long string */
+ if (rdlength < 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_uri_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu16 " ",
+ read_uint16(rr->rdata), read_uint16(rr->rdata + 2));
+ if(!print_text(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_resinfo_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 0;
+ if(!print_unquoteds(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_caa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ const size_t mark = buffer_position(packet);
+ uint16_t length = 1;
+
+ /* byte + string + long string */
+ if (buffer_remaining(packet) < rdlength || rdlength < 2)
+ return MALFORMED;
+ buffer_skip(packet, 1);
+ if (skip_string(packet, rdlength, &length) < 0 || rdlength < length)
+ return MALFORMED;
+ buffer_set_position(packet, mark);
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_caa_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 1;
+
+ if(rr->rdlength < 2)
+ return 0;
+ buffer_printf(output, "%" PRIu8 " ", rr->rdata[0]);
+
+ length = 2 + rr->rdata[1];
+ if (rr->rdlength < length)
+ return 0;
+
+ for (uint16_t i = 2; i < length; ++i) {
+ char ch = (char) rr->rdata[i];
+ if (isdigit((unsigned char)ch) || islower((unsigned char)ch))
+ buffer_printf(output, "%c", ch);
+ else return 0;
+ }
+
+ buffer_printf(output, " ");
+ if (!print_text(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_doa_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 9;
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(output, "%" PRIu32 " %" PRIu32 " %" PRIu8 " ",
+ read_uint32(rr->rdata), read_uint32(rr->rdata+4),
+ rr->rdata[8]);
+ if(!print_string(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ buffer_printf(output, " ");
+ if(rr->rdlength == length) {
+ /* The base64 string is empty, and DOA uses '-' for that. */
+ buffer_printf(output, "-");
+ } else {
+ if(!print_base64(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ }
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+read_amtrelay_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ struct dname_buffer relay;
+ const uint8_t *relay_rdata;
+ uint8_t relay_length = 0;
+ const size_t mark = buffer_position(packet);
+
+ /* byte + byte + relay */
+ if (buffer_remaining(packet) < rdlength || rdlength < 2)
+ return MALFORMED;
+
+ buffer_skip(packet, 2);
+
+ switch (buffer_read_u8_at(packet, mark + 1)&AMTRELAY_TYPE_MASK) {
+ case AMTRELAY_NOGATEWAY:
+ relay_length = 0;
+ relay_rdata = NULL;
+ break;
+ case AMTRELAY_IP4:
+ relay_length = 4;
+ relay_rdata = buffer_current(packet);
+ if (rdlength < 2 + relay_length)
+ return MALFORMED;
+ buffer_skip(packet, relay_length);
+ break;
+ case AMTRELAY_IP6:
+ relay_length = 16;
+ relay_rdata = buffer_current(packet);
+ if (rdlength < 2 + relay_length)
+ return MALFORMED;
+ buffer_skip(packet, relay_length);
+ break;
+ case AMTRELAY_DNAME:
+ /* The dname is stored as literal dname. On the wire
+ * skip possibly compressed format, in the rdata there
+ * is an uncompressed wire format. */
+ if(!dname_make_from_packet_buffered(&relay, packet,
+ 1 /* lenient */, 0))
+ return MALFORMED;
+ if(rdlength < buffer_position(packet) - mark)
+ return MALFORMED;
+ relay_length = relay.dname.name_size;
+ relay_rdata = dname_name((void*)&relay);
+ break;
+ default:
+ return MALFORMED;
+ }
+ if(rdlength != buffer_position(packet) - mark)
+ return MALFORMED; /* trailing bytes */
+
+ if (!(*rr = region_alloc(domains->region,
+ sizeof(**rr) + 2 + relay_length)))
+ return TRUNCATED;
+
+ buffer_read_at(packet, mark, (*rr)->rdata, 2);
+ if(relay_rdata)
+ memcpy((*rr)->rdata + 2, relay_rdata, relay_length);
+ (*rr)->rdlength = 2 + relay_length;
+ return rdlength;
+}
+
+int
+print_amtrelay_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 2;
+ uint8_t relay_type;
+
+ if(rr->rdlength < length)
+ return 0;
+ relay_type = rr->rdata[1]&AMTRELAY_TYPE_MASK;
+ buffer_printf(output, "%" PRIu8 " %c %" PRIu8,
+ rr->rdata[0],
+ (rr->rdata[1] & AMTRELAY_DISCOVERY_OPTIONAL_MASK ? '1' : '0'),
+ relay_type);
+ switch(relay_type) {
+ case AMTRELAY_NOGATEWAY:
+ buffer_printf(output, " .");
+ break;
+ case AMTRELAY_IP4:
+ buffer_printf(output, " ");
+ if(!print_ip4(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ break;
+ case AMTRELAY_IP6:
+ buffer_printf(output, " ");
+ if(!print_ip6(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ break;
+ case AMTRELAY_DNAME:
+ buffer_printf(output, " ");
+ if(!print_name_literal(output, rr->rdlength, rr->rdata,
+ &length))
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int32_t
+amtrelay_relay_length(uint16_t rdlength, const uint8_t *rdata, uint16_t offset,
+ struct domain** domain)
+{
+ /* The amtrelay relay length depends only on earlier bytes, so both
+ * the in-memory and uncompressed wireformat refer to the same
+ * earlier bytes. Also the domain name is stored literally, so it
+ * does not need to return a reference. */
+ uint8_t relay_type;
+ *domain = NULL;
+ /* Calculate the relay length, based on the relay type.
+ * That is stored in an earlier field. */
+ if(rdlength < 2 || offset < 2)
+ return -1; /* too short */
+ relay_type = rdata[1]&AMTRELAY_TYPE_MASK;
+ switch(relay_type) {
+ case AMTRELAY_NOGATEWAY:
+ return 0;
+ case AMTRELAY_IP4:
+ return 4;
+ case AMTRELAY_IP6:
+ return 16;
+ case AMTRELAY_DNAME:
+ return buf_dname_length(rdata+offset, rdlength-offset);
+ default:
+ /* Unknown relay type. */
+ break;
+ }
+ return -1;
+}
+
+int
+print_ipn_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint64_t data;
+
+ if(rr->rdlength < sizeof(data))
+ return 0;
+ data = read_uint64(rr->rdata);
+ buffer_printf(output, "%llu", (unsigned long long) data);
+ return 1;
+}
+
+int32_t
+read_dlv_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr)
+{
+ /* short + byte + byte + binary */
+ if (rdlength < 4)
+ return MALFORMED;
+ return read_rdata(domains, rdlength, packet, rr);
+}
+
+int
+print_dlv_rdata(struct buffer *output, const struct rr *rr)
+{
+ uint16_t length = 4;
+
+ if(rr->rdlength < length)
+ return 0;
+ buffer_printf(
+ output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
+ read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
+ if (!print_base16(output, rr->rdlength, rr->rdata, &length))
+ return 0;
+ if(rr->rdlength != length)
+ return 0;
+ return 1;
+}
+
+int
+print_rdata(buffer_type *output, const nsd_type_descriptor_type *descriptor,
+ const rr_type *rr)
+{
+ size_t saved_position = buffer_position(output);
+ /* If print_rdata is going to print "", omit the tab printout. */
+ if(!(rr->type == TYPE_APL && rr->rdlength == 0))
+ buffer_printf(output, "\t");
+ if(!descriptor->print_rdata(output, rr)) {
+ buffer_set_position(output, saved_position);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Compare two wireformat byte strings. In canonical order for this comparison.
+ * Sorts equal as equal, and if there is a prefix match, the shorter one is
+ * before the longer one; so it sorts like normalized domain names,
+ * ab ac acd ace ad ae af. And ab < abc , abc < ac .
+ * @param b1: byte string1.
+ * @param len1: length of b1.
+ * @param b2: byte string2.
+ * @param len2: length of b2
+ * @return comparison, -1, 0, 1.
+ */
+static int
+compare_bytestring(const uint8_t* b1, uint16_t len1, const uint8_t* b2,
+ uint16_t len2)
+{
+ uint16_t blen;
+ int res;
+
+ if(len1 == 0 && len2 == 0)
+ return 0;
+ if(len1 == 0 && len2 != 0)
+ return -1;
+ if(len1 != 0 && len2 == 0)
+ return 1;
+ blen = len1;
+ if(len2 < blen)
+ blen = len2;
+ res = memcmp(b1, b2, blen);
+ if(res != 0)
+ return res;
+ if(len1 < len2)
+ return -1;
+ if(len1 > len2)
+ return 1;
+ /* len1 == len2 and equal. */
+ return 0;
+}
+
+int
+equal_rr_rdata(const nsd_type_descriptor_type *descriptor,
+ const struct rr *rr1, const struct rr *rr2)
+{
+ size_t i;
+ uint16_t offset = 0;
+ int res;
+
+ if(!descriptor->has_references) {
+ /* Compare the wireformat of the rdata. */
+ res = compare_bytestring(rr1->rdata, rr1->rdlength,
+ rr2->rdata, rr2->rdlength);
+ if(res != 0)
+ return 0;
+ return 1;
+ }
+
+ for(i=0; i < descriptor->rdata.length; i++) {
+ uint16_t field_len1, field_len2;
+ struct domain* domain1, *domain2;
+ int malf1 = 0, malf2 = 0;
+ /* The fields are equal up to this point. */
+ if((rr1->rdlength == offset || rr2->rdlength == offset) &&
+ descriptor->rdata.fields[i].is_optional) {
+ /* There are no more rdata fields. */
+ /* Check lengths. */
+ if(rr1->rdlength == rr2->rdlength)
+ return 1;
+ else
+ return 0;
+ }
+ if(!lookup_rdata_field_entry(descriptor, i, rr1, offset,
+ &field_len1, &domain1))
+ malf1 = 1; /* malformed rdata buffer */
+ if(!lookup_rdata_field_entry(descriptor, i, rr2, offset,
+ &field_len2, &domain2))
+ malf2 = 1; /* malformed rdata buffer */
+ if(malf1 || malf2) {
+ /* Malformed entries sort last, and are sorted
+ * equal with other malformed entries. */
+ if(malf1 && malf2)
+ return 1;
+ else
+ return 0;
+ }
+ /* Compare the two fields. */
+ /* If they have a different type field, they are not the
+ * same. */
+ if(domain1 && !domain2)
+ return 0;
+ if(!domain1 && domain2)
+ return 0;
+ if(domain1 && domain2) {
+ /* Handle RDATA_COMPRESSED_DNAME and
+ * RDATA_UNCOMPRESSED_DNAME fields. */
+ res = dname_compare(domain_dname(domain1),
+ domain_dname(domain2));
+ if(res != 0)
+ return 0;
+ } else {
+ res = compare_bytestring(rr1->rdata + offset,
+ field_len1, rr2->rdata + offset, field_len2);
+ if(res != 0)
+ return 0;
+ }
+ /* The fields are equal, field_len1 == field_len2. */
+ offset += field_len1;
+ }
+ return 1;
+}
+
+int
+equal_rr_rdata_uncompressed_wire(const nsd_type_descriptor_type *descriptor,
+ const struct rr *rr1, const uint8_t* rr2_rdata, uint16_t rr2_rdlen)
+{
+ size_t i;
+ uint16_t offset1 = 0, offset2 = 0;
+ int res;
+
+ if(!descriptor->has_references) {
+ /* Compare the wireformat of the rdata. */
+ res = compare_bytestring(rr1->rdata, rr1->rdlength,
+ rr2_rdata, rr2_rdlen);
+ if(res != 0)
+ return 0;
+ return 1;
+ }
+
+ for(i=0; i < descriptor->rdata.length; i++) {
+ uint16_t field_len1, field_len2;
+ struct domain* domain1, *domain2;
+ int malf1 = 0, malf2 = 0;
+ /* The fields are equal up to this point. */
+ if((rr1->rdlength == offset1 || rr2_rdlen == offset2) &&
+ descriptor->rdata.fields[i].is_optional) {
+ /* There are no more rdata fields. */
+ /* Check lengths. */
+ int remain1 = rr1->rdlength - offset1;
+ int remain2 = rr2_rdlen - offset2;
+ if(remain1 < remain2)
+ return 0;
+ if(remain1 > remain2)
+ return 0;
+ /* It is equal. */
+ return 1;
+ }
+ if(!lookup_rdata_field_entry(descriptor, i, rr1, offset1,
+ &field_len1, &domain1))
+ malf1 = 1; /* malformed rdata buffer */
+ if(!lookup_rdata_field_entry_uncompressed_wire(descriptor, i,
+ rr2_rdata, rr2_rdlen, offset2, &field_len2, &domain2))
+ malf2 = 1; /* malformed rdata buffer */
+ if(malf1 || malf2) {
+ /* Malformed entries sort last, and are sorted
+ * equal with other malformed entries. */
+ if(!malf1 && malf2)
+ return 0;
+ if(malf1 && !malf2)
+ return 0;
+ return 1;
+ }
+ /* Compare the two fields. */
+ /* If they have a different type field, they are not the
+ * same. */
+ if(domain1) {
+ if(domain2) {
+ /* Handle RDATA_COMPRESSED_DNAME and
+ * RDATA_UNCOMPRESSED_DNAME fields. */
+ res = dname_compare(domain_dname(domain1),
+ domain_dname(domain2));
+ if(res != 0)
+ return 0;
+ } else {
+ uint16_t dname_len2 = buf_dname_length(
+ rr2_rdata+offset2,
+ rr2_rdlen-offset2);
+ if(domain_dname(domain1)->name_size !=
+ dname_len2) {
+ /* not the same length dnames. */
+ return 0;
+ }
+ if(!dname_equal_nocase(
+ (uint8_t*)dname_name(domain_dname(
+ domain1)),
+ (uint8_t*)rr2_rdata+offset2,
+ dname_len2)) {
+ /* name comparison not equal. */
+ return 0;
+ }
+ }
+ } else {
+ if(domain2) {
+ uint16_t dname_len1 = buf_dname_length(
+ rr1->rdata + offset1,
+ rr1->rdlength-offset1);
+ if(dname_len1 !=
+ domain_dname(domain2)->name_size) {
+ /* not the same length dnames. */
+ return 0;
+ }
+ if(!dname_equal_nocase(
+ (uint8_t*)rr1->rdata+offset1,
+ (uint8_t*)dname_name(domain_dname(
+ domain2)),
+ dname_len1)) {
+ /* name comparison not equal. */
+ return 0;
+ }
+ } else {
+ res = compare_bytestring(rr1->rdata + offset1,
+ field_len1, rr2_rdata + offset2,
+ field_len2);
+ if(res != 0)
+ return 0;
+ }
+ }
+ offset1 += field_len1;
+ offset2 += field_len2;
+ }
+ return 1;
+}
+
+struct domain*
+retrieve_rdata_ref_domain_offset(const struct rr* rr, uint16_t offset)
+{
+ struct domain *domain;
+ if(rr->rdlength < offset+sizeof(void*))
+ return NULL;
+ memcpy(&domain, rr->rdata+offset, sizeof(void*));
+ return domain;
+}
+
+struct domain*
+retrieve_rdata_ref_domain(const struct rr* rr)
+{
+ struct domain *domain;
+ if(rr->rdlength < sizeof(void*))
+ return NULL;
+ memcpy(&domain, rr->rdata, sizeof(void*));
+ return domain;
+}
+
+struct domain*
+retrieve_ns_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_NS);
+ return retrieve_rdata_ref_domain(rr);
+}
+
+struct domain*
+retrieve_cname_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_CNAME);
+ return retrieve_rdata_ref_domain(rr);
+}
+
+struct domain*
+retrieve_dname_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_DNAME);
+ return retrieve_rdata_ref_domain(rr);
+}
+
+struct domain*
+retrieve_mb_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_MB);
+ return retrieve_rdata_ref_domain(rr);
+}
+
+struct domain*
+retrieve_mx_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_MX);
+ return retrieve_rdata_ref_domain_offset(rr, 2);
+}
+
+struct domain*
+retrieve_kx_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_KX);
+ return retrieve_rdata_ref_domain_offset(rr, 2);
+}
+
+struct domain*
+retrieve_rt_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_RT);
+ return retrieve_rdata_ref_domain_offset(rr, 2);
+}
+
+struct domain*
+retrieve_srv_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_SRV);
+ return retrieve_rdata_ref_domain_offset(rr, 6);
+}
+
+struct domain*
+retrieve_ptr_ref_domain(const struct rr* rr)
+{
+ assert(rr->type == TYPE_PTR);
+ return retrieve_rdata_ref_domain(rr);
+}
+
+int
+retrieve_soa_rdata_serial(const struct rr* rr, uint32_t* serial)
+{
+ assert(rr->type == TYPE_SOA);
+ if(rr->rdlength < 20 + 2*sizeof(void*))
+ return 0;
+ /* primary mail serial[4] refresh[4] retry[4] expire[4] minimum[4] */
+ *serial = read_uint32(rr->rdata+2*sizeof(void*));
+ return 1;
+}
+
+int
+retrieve_soa_rdata_minttl(const struct rr* rr, uint32_t* minttl)
+{
+ assert(rr->type == TYPE_SOA);
+ if(rr->rdlength < 20 + 2*sizeof(void*))
+ return 0;
+ /* primary mail serial[4] refresh[4] retry[4] expire[4] minimum[4] */
+ *minttl = read_uint32(rr->rdata+2*sizeof(void*)+16);
+ return 1;
+}
+
+struct dname* retrieve_cname_ref_dname(const struct rr* rr)
+{
+ struct domain* domain;
+ assert(rr->type == TYPE_CNAME);
+ domain = retrieve_rdata_ref_domain(rr);
+ if(!domain)
+ return NULL;
+ return domain_dname(domain);
+}
+
+void
+rr_lower_usage(namedb_type* db, rr_type* rr)
+{
+ const nsd_type_descriptor_type *descriptor =
+ nsd_type_descriptor(rr->type);
+ uint16_t offset = 0;
+ size_t i;
+ for(i=0; i<descriptor->rdata.length; i++) {
+ uint16_t field_len;
+ struct domain* domain;
+ if(rr->rdlength == offset &&
+ descriptor->rdata.fields[i].is_optional)
+ break;
+ if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
+ &field_len, &domain))
+ break;
+ if(domain) {
+ assert(domain->usage > 0);
+ domain->usage --;
+ if(domain->usage == 0)
+ domain_table_deldomain(db,
+ domain);
+ }
+ offset += field_len;
+ }
+}
+
+const char*
+read_rdata_fail_str(int32_t code)
+{
+ switch(code) {
+ case TRUNCATED:
+ return "out of memory";
+ case MALFORMED:
+ return "malformed rdata fields";
+ default:
+ break;
+ }
+ return "failed to read rdata fields";
+}
Index: rdata.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/rdata.h,v
diff -u -p -r1.3 rdata.h
--- rdata.h 29 Jun 2023 19:38:50 -0000 1.3
+++ rdata.h 18 Mar 2026 20:44:03 -0000
@@ -17,45 +17,668 @@
#define APL_NEGATION_MASK 0x80U
#define APL_LENGTH_MASK (~APL_NEGATION_MASK)
+/* High bit of the AMTRELAY Type byte in rdata[1] is the Discovery Optional
+ * flag, the D-bit. */
+#define AMTRELAY_DISCOVERY_OPTIONAL_MASK 0x80U
+#define AMTRELAY_TYPE_MASK 0x7fU
+
extern lookup_table_type dns_certificate_types[];
extern lookup_table_type dns_algorithms[];
-extern const char *svcparamkey_strs[];
-
-int rdata_atom_to_string(buffer_type *output, rdata_zoneformat_type type,
- rdata_atom_type rdata, rr_type *rr);
/*
- * Split the wireformat RDATA into an array of rdata atoms. Domain
- * names are inserted into the OWNERS table. The number of rdata atoms
- * is returned and the array itself is allocated in REGION and stored
- * in RDATAS.
- *
- * Returns -1 on failure.
+ * Function signature for svcparam print. Input offset is at key uint16_t
+ * in rdata.
+ * @param output: the string is printed to the buffer.
+ * @param svcparamkey: the key that is printed.
+ * @param data: the data for the svcparam, from rdata.
+ * @param datalen: length of data in bytes.
+ * @return false on failure.
*/
-ssize_t rdata_wireformat_to_rdata_atoms(region_type *region,
- domain_table_type *owners,
- uint16_t rrtype,
- uint16_t rdata_size,
- buffer_type *packet,
- rdata_atom_type **rdatas);
-
-/*
- * Calculate the maximum size of the rdata assuming domain names are
- * not compressed.
- */
-size_t rdata_maximum_wireformat_size(rrtype_descriptor_type *descriptor,
- size_t rdata_count,
- rdata_atom_type *rdatas);
-
-int rdata_atoms_to_unknown_string(buffer_type *out,
- rrtype_descriptor_type *descriptor,
- size_t rdata_count,
- rdata_atom_type *rdatas);
+typedef int(*nsd_print_svcparam_rdata_type)(
+ struct buffer* output,
+ uint16_t svcparamkey,
+ const uint8_t* data,
+ uint16_t datalen);
+
+typedef struct nsd_svcparam_descriptor nsd_svcparam_descriptor_type;
+
+/* Descriptor for svcparam rdata fields. With type, name and print func. */
+struct nsd_svcparam_descriptor {
+ /* The svc param key */
+ uint16_t key;
+ /* The name of the key */
+ const char *name;
+ /* Print function that prints the key, from rdata. */
+ nsd_print_svcparam_rdata_type print_rdata;
+};
+
+int print_unknown_rdata_field(buffer_type *output,
+ const nsd_type_descriptor_type *descriptor, const rr_type *rr);
+int print_unknown_rdata(buffer_type *output,
+ const nsd_type_descriptor_type *descriptor, const rr_type *rr);
/* print rdata to a text string (as for a zone file) returns 0
on a failure (bufpos is reset to original position).
returns 1 on success, bufpos is moved. */
-int print_rdata(buffer_type *output, rrtype_descriptor_type *descriptor,
- rr_type *record);
+int print_rdata(buffer_type *output, const nsd_type_descriptor_type *descriptor,
+ const rr_type *rr);
+
+/* Read rdata for an unknown RR type. */
+int32_t read_generic_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for an unknown RR type. */
+void write_generic_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for an unknown RR type. */
+int print_generic_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for an RR type with one compressed dname. */
+int32_t read_compressed_name_rdata(struct domain_table *domains,
+ uint16_t rdlength, struct buffer *packet, struct rr **rr);
+
+/* Write rdata for an RR type with one compressed dname. */
+void write_compressed_name_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for an RR type with one compressed or uncompressed dname.
+ * But not a dname type literal. */
+int print_name_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for an RR type with one uncompressed dname. */
+int32_t read_uncompressed_name_rdata(struct domain_table *domains,
+ uint16_t rdlength, struct buffer *packet, struct rr **rr);
+
+/* Write rdata for an RR type with one uncompressed dname. */
+void write_uncompressed_name_rdata(struct query *query, const struct rr *rr);
+
+/* Read rdata for type A. */
+int32_t read_a_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type A. */
+int print_a_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type SOA. */
+int32_t read_soa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type SOA. */
+void write_soa_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type SOA. */
+int print_soa_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type SOA, on two lines, with parentheses. */
+int print_soa_rdata_twoline(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type WKS. */
+int32_t read_wks_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type WKS. */
+int print_wks_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type HINFO. */
+int32_t read_hinfo_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type HINFO. */
+int print_hinfo_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type MINFO. */
+int32_t read_minfo_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type MINFO. */
+void write_minfo_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type MINFO. */
+int print_minfo_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type MX. */
+int32_t read_mx_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type MX. */
+void write_mx_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type MX. */
+int print_mx_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type TXT. */
+int32_t read_txt_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type TXT. */
+int print_txt_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type RP. */
+int32_t read_rp_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type RP. */
+void write_rp_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type RP. */
+int print_rp_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type AFSDB. */
+int32_t read_afsdb_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type AFSDB. */
+void write_afsdb_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type AFSDB. */
+int print_afsdb_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type X25. */
+int32_t read_x25_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type X25. */
+int print_x25_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type ISDN. */
+int32_t read_isdn_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type ISDN. */
+int print_isdn_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type RT. */
+int32_t read_rt_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type RT. */
+void write_rt_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type NSAP. */
+int print_nsap_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type NSAP-PTR. */
+int print_nsap_ptr_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type KEY. */
+int print_key_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type PX. */
+int32_t read_px_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type PX. */
+void write_px_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type PX. */
+int print_px_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type GPOS. */
+int print_gpos_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type AAAA. */
+int32_t read_aaaa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type AAAA. */
+int print_aaaa_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type LOC. */
+int32_t read_loc_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type LOC. */
+int print_loc_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type NXT. */
+int32_t read_nxt_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type NXT. */
+void write_nxt_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type NXT. */
+int print_nxt_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type EID. */
+int print_eid_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type NIMLOC. */
+int print_nimloc_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type SRV. */
+int32_t read_srv_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type SRV. */
+void write_srv_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type SRV. */
+int print_srv_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type ATMA. */
+int print_atma_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type NAPTR. */
+int32_t read_naptr_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type NAPTR. */
+void write_naptr_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type NAPTR. */
+int print_naptr_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type KX. */
+int32_t read_kx_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type KX. */
+void write_kx_rdata(struct query *query, const struct rr *rr);
+
+/* Read rdata for type CERT. */
+int32_t read_cert_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type CERT. */
+int print_cert_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type SINK. */
+int print_sink_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type APL. */
+int32_t read_apl_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type APL. */
+int print_apl_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type DS. */
+int32_t read_ds_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type DS. */
+int print_ds_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type SSHFP. */
+int32_t read_sshfp_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type SSHFP. */
+int print_sshfp_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type IPSECKEY. */
+int32_t read_ipseckey_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type IPSECKEY. */
+int print_ipseckey_rdata(struct buffer *output, const struct rr *rr);
+
+/* Determine length of IPSECKEY gateway field. */
+int32_t ipseckey_gateway_length(uint16_t rdlength, const uint8_t *rdata,
+ uint16_t offset, struct domain** domain);
+
+/* Read rdata for type RRSIG. */
+int32_t read_rrsig_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type RRSIG. */
+int print_rrsig_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type NSEC. */
+int32_t read_nsec_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type NSEC. */
+int print_nsec_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type DNSKEY. */
+int32_t read_dnskey_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type DNSKEY. */
+int print_dnskey_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type DHCID. */
+int32_t read_dhcid_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type DHCID. */
+int print_dhcid_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type NSEC3. */
+int32_t read_nsec3_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type NSEC3. */
+int print_nsec3_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type NSEC3PARAM. */
+int32_t read_nsec3param_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type NSEC3PARAM. */
+int print_nsec3param_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type TLSA. */
+int32_t read_tlsa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type TLSA. */
+int print_tlsa_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type HIP. */
+int32_t read_hip_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type HIP. */
+int print_hip_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type RKEY. */
+int32_t read_rkey_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type RKEY. */
+int print_rkey_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type TALINK. */
+int32_t read_talink_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type TALINK. */
+int print_talink_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type OPENPGPKEY. */
+int print_openpgpkey_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type CSYNC. */
+int32_t read_csync_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type CSYNC. */
+int print_csync_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type ZONEMD. */
+int32_t read_zonemd_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type ZONEMD. */
+int print_zonemd_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type SVCB. */
+int32_t read_svcb_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type SVCB. */
+void write_svcb_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type SVCB. */
+int print_svcb_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type DSYNC. */
+int32_t read_dsync_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type DSYNC. */
+int print_dsync_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type NID. */
+int32_t read_nid_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type NID. */
+int print_nid_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type L32. */
+int32_t read_l32_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type L32. */
+int print_l32_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type L64. */
+int32_t read_l64_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type L64. */
+int print_l64_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type LP. */
+int32_t read_lp_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Write rdata for type LP. */
+void write_lp_rdata(struct query *query, const struct rr *rr);
+
+/* Print rdata for type LP. */
+int print_lp_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type EUI48. */
+int32_t read_eui48_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type EUI48. */
+int print_eui48_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type EUI64. */
+int32_t read_eui64_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type EUI64. */
+int print_eui64_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type URI. */
+int32_t read_uri_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type URI. */
+int print_uri_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type resinfo. */
+int print_resinfo_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type CAA. */
+int32_t read_caa_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type CAA. */
+int print_caa_rdata(struct buffer *output, const struct rr *rr);
+
+/* Print rdata for type DOA. */
+int print_doa_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type AMTRELAY. */
+int32_t read_amtrelay_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type AMTRELAY. */
+int print_amtrelay_rdata(struct buffer *output, const struct rr *rr);
+
+/* Determine length of AMTRELAY relay field. */
+int32_t amtrelay_relay_length(uint16_t rdlength, const uint8_t *rdata,
+ uint16_t offset, struct domain** domain);
+
+/* Print rdata for type IPN. */
+int print_ipn_rdata(struct buffer *output, const struct rr *rr);
+
+/* Read rdata for type DLV. */
+int32_t read_dlv_rdata(struct domain_table *domains, uint16_t rdlength,
+ struct buffer *packet, struct rr **rr);
+
+/* Print rdata for type DLV. */
+int print_dlv_rdata(struct buffer *output, const struct rr *rr);
+
+/*
+ * Look up the uncompressed wireformat length of the rdata.
+ * The pointer references in it are taking up the length of their uncompressed
+ * domain names. The length is without the RR's rdatalength uint16 preceding.
+ * @param rr: the rr, the RR type and rdata are used.
+ * @result -1 on failure, otherwise length in bytes.
+ */
+int32_t rr_calculate_uncompressed_rdata_length(const rr_type* rr);
+
+/*
+ * Write uncompressed wireformat rdata to buffer. The pointer references
+ * and domains are uncompressed wireformat domain names. The uint16 rdlength
+ * is not written before it.
+ * @param rr: the rr, with RR type and rdata.
+ * @param buf: destination.
+ * @param len: length of buffer.
+ */
+void rr_write_uncompressed_rdata(const rr_type* rr, uint8_t* buf, size_t len);
+
+/*
+ * Look up the field length. The field length is returned as a length
+ * in the rdata that is stored. For a reference, the pointer is returned too.
+ * Before calling it check if the field is_optional, and rdlength is
+ * reached by offset, then there are no more rdata fields.
+ * Also if the index has reached the rdata field length count, fields end.
+ * It checks if the field fits in the rdata buffer, failure if not.
+ * Then check for domain ptr or not, and handle the field at rr->rdata+offset.
+ * Continue the loop by incrementing offset with field_len, and index++.
+ *
+ * @param descriptor: type descriptor.
+ * @param index: field index.
+ * @param rr: the rr with the rdata.
+ * @param offset: current position in the rdata.
+ * It is not updated, because the caller has to do that.
+ * @param field_len: the field length is returned.
+ * @param domain: the pointer is returned when the field is a reference.
+ * @return false on failure, when the rdata stored is badly formatted, like
+ * the rdata buffer is too short.
+ */
+int lookup_rdata_field_entry(const nsd_type_descriptor_type* descriptor,
+ size_t index, const rr_type* rr, uint16_t offset, uint16_t* field_len,
+ struct domain** domain);
+
+/* Look up the field length. Same as lookup_rdata_field_entry, but the rdata
+ * is uncompressed wireformat. The length returned skips the field in the
+ * uncompressed wireformat. */
+int lookup_rdata_field_entry_uncompressed_wire(
+ const nsd_type_descriptor_type* descriptor, size_t index,
+ const uint8_t* rdata, uint16_t rdlength, uint16_t offset,
+ uint16_t* field_len, struct domain** domain);
+
+/*
+ * Compare rdata for equality. This is easier than the sorted compare,
+ * it treats field types as a difference too, so a reference instead of
+ * a wireformat field makes for a different RR.
+ * The RRs have to be the same type already.
+ * It iterates over the RR type fields. The RRs and the rdatas are the
+ * namedb format, that is with references stored as pointers.
+ * @param rr1: RR to compare rdata 1. The rdata can contain pointers.
+ * @param rr2: RR to compare rdata 2. The rdata can contain pointers.
+ * @return true if rdata is equal.
+ */
+int equal_rr_rdata(const nsd_type_descriptor_type *descriptor,
+ const struct rr *rr1, const struct rr *rr2);
+
+/*
+ * Compare rdata for equality. Same as equal_rr_rdata, but the second
+ * rdata is passed as uncompressed wireformat, the first has the in-memory
+ * rdata format.
+ */
+int equal_rr_rdata_uncompressed_wire(const nsd_type_descriptor_type *descriptor,
+ const struct rr *rr1, const uint8_t* rr2_rdata, uint16_t rr2_rdlen);
+
+/*
+ * Retrieve domain ref at an offset in the rdata.
+ * @param rr: the RR to retrieve it for.
+ * @param offset: where in the rdata the reference pointer is.
+ * @return domain ptr.
+ */
+struct domain* retrieve_rdata_ref_domain_offset(const struct rr* rr,
+ uint16_t offset);
+
+/*
+ * Retrieve domain ref from rdata. No offset, rdata starts with ref.
+ * @param rr: the RR to retrieve it for.
+ * @return domain ptr.
+ */
+struct domain* retrieve_rdata_ref_domain(const struct rr* rr);
+
+/*
+ * Accessor function to the domain in the rdata of the type.
+ * The RR must be of the type. The type must have references.
+ * @param rr: the rr with rdata
+ * @return domain pointer.
+ */
+typedef struct domain*(*nsd_rdata_ref_domain_type)(
+ const struct rr* rr);
+
+/* Access the domain reference for type NS */
+struct domain* retrieve_ns_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type CNAME */
+struct domain* retrieve_cname_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type DNAME */
+struct domain* retrieve_dname_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type MB */
+struct domain* retrieve_mb_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type MX */
+struct domain* retrieve_mx_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type KX */
+struct domain* retrieve_kx_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type RT */
+struct domain* retrieve_rt_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type SRV */
+struct domain* retrieve_srv_ref_domain(const struct rr* rr);
+
+/* Access the domain reference for type PTR */
+struct domain* retrieve_ptr_ref_domain(const struct rr* rr);
+
+/* Access the serial number for type SOA, false if malformed. */
+int retrieve_soa_rdata_serial(const struct rr* rr, uint32_t* serial);
+
+/* Access the minimum ttl for type SOA, false if malformed. */
+int retrieve_soa_rdata_minttl(const struct rr* rr, uint32_t* minttl);
+
+/* Access the dname reference for type CNAME */
+struct dname* retrieve_cname_ref_dname(const struct rr* rr);
+
+/*
+ * Access the domain name reference, that is stored as COMPRESSED_DNAME,
+ * or UNCOMPRESSED DNAME, at the start of the rdata, or only part of the rdata.
+ * Not for literal DNAMEs. This is similar to a pointer reference,
+ * but it may be stored unaligned.
+ * @param rr: the resource record.
+ * @return domain pointer.
+ */
+static inline struct domain* rdata_domain_ref(const struct rr* rr) {
+ struct domain* domain;
+ assert(rr->rdlength >= (uint16_t)sizeof(void*));
+ memcpy(&domain, rr->rdata, sizeof(void*));
+ return domain;
+}
+
+/*
+ * Access the domain name reference, that is stored as COMPRESSED_DNAME,
+ * or UNCOMPRESSED DNAME, the reference is at an offset in the rdata.
+ * Not for literal DNAMEs. This is similar to a pointer reference,
+ * but it may be stored unaligned.
+ * @param rr: the resource record
+ * @param offset: where the reference is found in the rdata. Pass like 2,
+ * for type MX, or sizeof(void*) to access the second domain pointer
+ * of SOA.
+ * @return domain pointer.
+ */
+static inline struct domain* rdata_domain_ref_offset(const struct rr* rr,
+ uint16_t offset) {
+ struct domain* domain;
+ assert(rr->rdlength >= offset+(uint16_t)sizeof(void*));
+ memcpy(&domain, rr->rdata+offset, sizeof(void*));
+ return domain;
+}
+
+/* fixup usage lower for domain names in the rdata */
+void rr_lower_usage(namedb_type* db, rr_type* rr);
+
+/* return error string for read_rdata return code that is < 0 */
+const char* read_rdata_fail_str(int32_t code);
#endif /* RDATA_H */
Index: remote.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/remote.c,v
diff -u -p -r1.29 remote.c
--- remote.c 6 Sep 2025 17:41:37 -0000 1.29
+++ remote.c 18 Mar 2026 20:44:03 -0000
@@ -81,6 +81,7 @@
#include "difffile.h"
#include "ipc.h"
#include "remote.h"
+#include "rdata.h"
#ifdef USE_METRICS
#include "metrics.h"
@@ -1042,6 +1043,7 @@ print_zonestatus(RES* ssl, xfrd_state_ty
return 0;
}
if(zone_is_catalog_consumer(zo)) {
+ uint32_t serial = 0;
zone_type* zone = namedb_find_zone(xfrd->nsd->db,
(const dname_type*)zo->node.key);
struct xfrd_catalog_consumer_zone* consumer_zone =
@@ -1051,13 +1053,14 @@ print_zonestatus(RES* ssl, xfrd_state_ty
if(!ssl_printf(ssl, " catalog: consumer"))
return 0;
- if(zone && zone->soa_rrset && zone->soa_rrset->rrs
- && zone->soa_rrset->rrs[0].rdata_count > 2
- && rdata_atom_size(zone->soa_rrset->rrs[0].rdatas[2]) ==
- sizeof(uint32_t)) {
+ if(zone && zone->soa_rrset
+#ifndef PACKED_STRUCTS
+ && zone->soa_rrset->rrs
+#endif
+ && retrieve_soa_rdata_serial(zone->soa_rrset->rrs[0],
+ &serial)) {
if(!ssl_printf(ssl, " (serial: %u, # members: %zu)\n",
- read_uint32(rdata_atom_data(
- zone->soa_rrset->rrs[0].rdatas[2])),
+ serial,
consumer_zone
? consumer_zone->member_ids.count : 0))
return 0;
@@ -3423,7 +3426,7 @@ create_local_accept_sock(const char *pat
goto err;
}
- if (listen(s, TCP_BACKLOG) == -1) {
+ if (listen(s, nsd.options->tcp_listen_queue) == -1) {
log_msg(LOG_ERR, "can't listen: %s", strerror(errno));
goto err;
}
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/server.c,v
diff -u -p -r1.55 server.c
--- server.c 6 Sep 2025 17:47:20 -0000 1.55
+++ server.c 18 Mar 2026 20:44:03 -0000
@@ -895,10 +895,14 @@ set_rcvbuf(struct nsd_socket *sock, int
return 1;
}
if(errno == EPERM || errno == ENOBUFS) {
+ if(errno == ENOBUFS) {
+ VERBOSITY(2, (LOG_INFO, "setsockopt(..., SO_RCVBUFFORCE, %d) was not granted: %s",
+ rcv, strerror(errno)));
+ }
return 0;
}
- log_msg(LOG_ERR, "setsockopt(..., SO_RCVBUFFORCE, ...) failed: %s",
- strerror(errno));
+ log_msg(LOG_ERR, "setsockopt(..., SO_RCVBUFFORCE, %d) failed: %s",
+ rcv, strerror(errno));
return -1;
#else /* !SO_RCVBUFFORCE */
if (0 == setsockopt(
@@ -907,10 +911,14 @@ set_rcvbuf(struct nsd_socket *sock, int
return 1;
}
if(errno == ENOSYS || errno == ENOBUFS) {
+ if(errno == ENOBUFS) {
+ VERBOSITY(2, (LOG_INFO, "setsockopt(..., SO_RCVBUF, %d) was not granted: %s",
+ rcv, strerror(errno)));
+ }
return 0;
}
- log_msg(LOG_ERR, "setsockopt(..., SO_RCVBUF, ...) failed: %s",
- strerror(errno));
+ log_msg(LOG_ERR, "setsockopt(..., SO_RCVBUF, %d) failed: %s",
+ rcv, strerror(errno));
return -1;
#endif /* SO_RCVBUFFORCE */
#endif /* SO_RCVBUF */
@@ -929,10 +937,14 @@ set_sndbuf(struct nsd_socket *sock, int
return 1;
}
if(errno == EPERM || errno == ENOBUFS) {
+ if(errno == ENOBUFS) {
+ VERBOSITY(2, (LOG_INFO, "setsockopt(..., SO_SNDBUFFORCE, %d) was not granted: %s",
+ snd, strerror(errno)));
+ }
return 0;
}
- log_msg(LOG_ERR, "setsockopt(..., SO_SNDBUFFORCE, ...) failed: %s",
- strerror(errno));
+ log_msg(LOG_ERR, "setsockopt(..., SO_SNDBUFFORCE, %d) failed: %s",
+ snd, strerror(errno));
return -1;
#else /* !SO_SNDBUFFORCE */
if(0 == setsockopt(
@@ -941,10 +953,14 @@ set_sndbuf(struct nsd_socket *sock, int
return 1;
}
if(errno == ENOSYS || errno == ENOBUFS) {
+ if(errno == ENOBUFS) {
+ VERBOSITY(2, (LOG_INFO, "setsockopt(..., SO_SNDBUF, %d) was not granted: %s",
+ snd, strerror(errno)));
+ }
return 0;
}
- log_msg(LOG_ERR, "setsockopt(..., SO_SNDBUF, ...) failed: %s",
- strerror(errno));
+ log_msg(LOG_ERR, "setsockopt(..., SO_SNDBUF, %d) failed: %s",
+ snd, strerror(errno));
return -1;
#endif /* SO_SNDBUFFORCE */
#endif /* SO_SNDBUF */
@@ -1277,7 +1293,8 @@ set_setfib(struct nsd_socket *sock)
static int
open_udp_socket(struct nsd *nsd, struct nsd_socket *sock, int *reuseport_works)
{
- int rcv = 1*1024*1024, snd = 4*1024*1024;
+ int rcv = nsd->options->receive_buffer_size;
+ int snd = nsd->options->send_buffer_size;
if(-1 == (sock->s = socket(
sock->addr.ai_family, sock->addr.ai_socktype, 0)))
@@ -1301,13 +1318,9 @@ open_udp_socket(struct nsd *nsd, struct
if(nsd->reuseport && reuseport_works && *reuseport_works)
*reuseport_works = (set_reuseport(sock) == 1);
- if(nsd->options->receive_buffer_size > 0)
- rcv = nsd->options->receive_buffer_size;
if(set_rcvbuf(sock, rcv) == -1)
return -1;
- if(nsd->options->send_buffer_size > 0)
- snd = nsd->options->send_buffer_size;
if(set_sndbuf(sock, snd) == -1)
return -1;
#ifdef INET6
@@ -1415,7 +1428,7 @@ open_tcp_socket(struct nsd *nsd, struct
(void)set_tcp_fastopen(sock);
#endif
- if(listen(sock->s, TCP_BACKLOG) == -1) {
+ if(listen(sock->s, nsd->options->tcp_listen_queue) == -1) {
log_msg(LOG_ERR, "can't listen: %s", strerror(errno));
return -1;
}
@@ -3398,13 +3411,14 @@ add_xdp_handler(struct nsd *nsd,
struct xdp_server *xdp,
struct xdp_handler_data *data) {
+ int sock;
struct event *handler = &data->event;
data->nsd = nsd;
data->server = xdp;
memset(handler, 0, sizeof(*handler));
- int sock = xsk_socket__fd(xdp->xsks[xdp->queue_index].xsk);
+ sock = xsk_socket__fd(xdp->xsks[xdp->queue_index].xsk);
if (sock < 0) {
log_msg(LOG_ERR, "xdp: xsk socket file descriptor is invalid: %s",
strerror(errno));
@@ -3704,13 +3718,18 @@ server_child(struct nsd *nsd)
#ifdef USE_XDP
if (nsd->options->xdp_interface) {
/* don't try to bind more sockets than there are queues available */
- if (nsd->xdp.xdp_server.queue_count <= nsd->this_child->child_num) {
+ if ((int)nsd->xdp.xdp_server.queue_count <= nsd->this_child->child_num) {
log_msg(LOG_WARNING,
"xdp: server-count exceeds available queues (%d) on "
"interface %s, skipping xdp in this process",
nsd->xdp.xdp_server.queue_count,
nsd->xdp.xdp_server.interface_name);
} else {
+ struct xdp_handler_data *data;
+ const int scratch_data_len = 1;
+ void *scratch_data = region_alloc_zero(nsd->server_region,
+ scratch_data_len);
+
nsd->xdp.xdp_server.queue_index = nsd->this_child->child_num;
nsd->xdp.xdp_server.queries = xdp_queries;
@@ -3719,13 +3738,9 @@ server_child(struct nsd *nsd)
nsd->xdp.xdp_server.queue_index,
nsd->xdp.xdp_server.interface_name);
- struct xdp_handler_data *data;
data = region_alloc_zero(nsd->server_region, sizeof(*data));
add_xdp_handler(nsd, &nsd->xdp.xdp_server, data);
- const int scratch_data_len = 1;
- void *scratch_data = region_alloc_zero(nsd->server_region,
- scratch_data_len);
for (i = 0; i < XDP_RX_BATCH_SIZE; i++) {
/* Be aware that the buffer is initialized with scratch data
* and will be filled by the xdp handle and receive function
@@ -5710,6 +5725,7 @@ static void handle_xdp(int fd, short eve
if ((event & EV_READ))
xdp_handle_recv_and_send(data->server);
+ (void)fd;
}
#endif
Index: util.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/util.c,v
diff -u -p -r1.31 util.c
--- util.c 6 Sep 2025 17:41:37 -0000 1.31
+++ util.c 18 Mar 2026 20:44:03 -0000
@@ -273,7 +273,7 @@ clear_bit(uint8_t bits[], size_t index)
}
int
-get_bit(uint8_t bits[], size_t index)
+get_bit(const uint8_t bits[], size_t index)
{
/*
* The bits are counted from left to right, so bit #0 is the
@@ -910,8 +910,8 @@ print_rr(FILE *out,
region_type* rr_region,
buffer_type* output)
{
- rrtype_descriptor_type *descriptor
- = rrtype_descriptor_by_type(record->type);
+ const nsd_type_descriptor_type *descriptor =
+ nsd_type_descriptor(record->type);
int result;
const dname_type *owner = domain_dname(record->owner);
buffer_clear(output);
@@ -943,14 +943,18 @@ print_rr(FILE *out,
rrclass_to_string(record->klass),
rrtype_to_string(record->type));
- result = print_rdata(output, descriptor, record);
+ if(record->type == TYPE_SOA) {
+ buffer_printf(output, "\t");
+ result = print_soa_rdata_twoline(output, record);
+ } else {
+ result = print_rdata(output, descriptor, record);
+ }
if (!result) {
/*
* Some RDATA failed to print, so print the record's
* RDATA in unknown format.
*/
- result = rdata_atoms_to_unknown_string(output,
- descriptor, record->rdata_count, record->rdatas);
+ result = print_unknown_rdata(output, descriptor, record);
}
if (result) {
Index: util.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/util.h,v
diff -u -p -r1.23 util.h
--- util.h 6 Sep 2025 17:41:37 -0000 1.23
+++ util.h 18 Mar 2026 20:44:03 -0000
@@ -131,7 +131,7 @@ void clear_bit(uint8_t bits[], size_t in
/*
* Return the value of the INDEXth bit of BITS.
*/
-int get_bit(uint8_t bits[], size_t index);
+int get_bit(const uint8_t bits[], size_t index);
/* A general purpose lookup table */
typedef struct lookup_table lookup_table_type;
Index: xdp-server.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/xdp-server.c,v
diff -u -p -r1.1.1.1 xdp-server.c
--- xdp-server.c 6 Sep 2025 17:38:33 -0000 1.1.1.1
+++ xdp-server.c 18 Mar 2026 20:44:03 -0000
@@ -211,7 +211,7 @@ static uint64_t xsk_umem_free_frames(str
}
static void xsk_free_umem_frame(struct xsk_socket_info *xsk, uint64_t frame) {
- assert(xsk->umem_frame_free < XDP_NUM_FRAMES);
+ assert(xsk->umem->umem_frame_free < XDP_NUM_FRAMES);
xsk->umem->umem_frame_addr[xsk->umem->umem_frame_free++] = frame;
}
@@ -343,19 +343,21 @@ xsk_configure_umem(struct xsk_umem_info
static int
xsk_configure_socket(struct xdp_server *xdp, struct xsk_socket_info *xsk_info,
struct xsk_umem_info *umem, uint32_t queue_index) {
- uint16_t xsk_bind_flags = XDP_USE_NEED_WAKEUP;
- if (xdp->force_copy) {
- xsk_bind_flags |= XDP_COPY;
- }
+ struct xsk_socket_config xsk_cfg;
+ uint32_t idx, reserved;
+ int ret;
+
struct xdp_config cfg = {
.xdp_flags = 0,
- .xsk_bind_flags = xsk_bind_flags,
+ .xsk_bind_flags = 0,
.libxdp_flags = XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD,
};
- struct xsk_socket_config xsk_cfg;
- uint32_t idx, reserved;
- int ret;
+ uint16_t xsk_bind_flags = XDP_USE_NEED_WAKEUP;
+ if (xdp->force_copy) {
+ xsk_bind_flags |= XDP_COPY;
+ }
+ cfg.xsk_bind_flags = xsk_bind_flags;
xsk_info->umem = umem;
xsk_cfg.rx_size = XSK_RING_CONS__NUM_DESCS;
@@ -843,8 +845,8 @@ process_packet(struct xdp_server *xdp, u
swap_udp(udp);
if (ipv4) {
- swap_ipv4(ipv4);
__be16 ipv4_old_len = ipv4->tot_len;
+ swap_ipv4(ipv4);
ipv4->tot_len = htons(sizeof(*ipv4)) + udp->len;
csum16_replace(&ipv4->check, ipv4_old_len, ipv4->tot_len);
udp->check = calc_csum_udp4(udp, ipv4);
@@ -867,6 +869,7 @@ void xdp_handle_recv_and_send(struct xdp
struct xsk_socket_info *xsk = &xdp->xsks[xdp->queue_index];
unsigned int recvd, i, reserved, to_send = 0;
uint32_t idx_rx = 0;
+ uint32_t tx_idx = 0;
int ret;
recvd = xsk_ring_cons__peek(&xsk->rx, XDP_RX_BATCH_SIZE, &idx_rx);
@@ -906,8 +909,6 @@ void xdp_handle_recv_and_send(struct xdp
/* xsk->stats.rx_packets += rcvd; */
/* Process sending packets */
-
- uint32_t tx_idx = 0;
/* TODO: at least send as many packets as slots are available */
reserved = xsk_ring_prod__reserve(&xsk->tx, to_send, &tx_idx);
Index: xfrd-catalog-zones.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/xfrd-catalog-zones.c,v
diff -u -p -r1.3 xfrd-catalog-zones.c
--- xfrd-catalog-zones.c 6 Sep 2025 17:41:37 -0000 1.3
+++ xfrd-catalog-zones.c 18 Mar 2026 20:44:03 -0000
@@ -9,6 +9,7 @@
#include "difffile.h"
#include "nsd.h"
#include "packet.h"
+#include "rdata.h"
#include "xfrd-catalog-zones.h"
#include "xfrd-notify.h"
@@ -545,11 +546,9 @@ xfrd_process_catalog_consumer_zone(
}
version_2_found = 0;
for (i = 0; i < rrset->rr_count; i++) {
- if (rrset->rrs[i].rdata_count != 1)
- continue;
- if (rrset->rrs[i].rdatas[0].data[0] == 2
- && ((uint8_t*)(rrset->rrs[i].rdatas[0].data + 1))[0] == 1
- && ((uint8_t*)(rrset->rrs[i].rdatas[0].data + 1))[1] == '2') {
+ if(rrset->rrs[i]->rdlength == 2 &&
+ rrset->rrs[i]->rdata[0] == 1 /* TXT string length */ &&
+ rrset->rrs[i]->rdata[1] == '2') {
version_2_found = 1;
break;
}
@@ -602,9 +601,9 @@ retry_adding:
return;
}
/* A PTR rr always has 1 rdata element which is a dname */
- if (rrset->rrs[0].rdata_count != 1)
+ member_domain = rdata_domain_ref(rrset->rrs[0]);
+ if(!member_domain)
continue;
- member_domain = rrset->rrs[0].rdatas[0].domain;
domain_to_string_buf(member_domain, member_domain_str);
/* remove trailing dot */
member_domain_str[strlen(member_domain_str) - 1] = 0;
@@ -622,22 +621,20 @@ retry_adding:
char group_value[256];
/* Looking for a single TXT rdata field */
- if (rrset->rrs[i].rdata_count != 1
+ if(rrset->rrs[i]->rdlength < 1
+ || rrset->rrs[i]->rdlength !=
+ ((uint16_t)rrset->rrs[i]->rdata[0])+1
/* rdata field should be at least 1 char */
- || rrset->rrs[i].rdatas[0].data[0] < 2
-
- /* single rdata atom with single TXT rdata field */
- || (uint16_t)(((uint8_t*)(rrset->rrs[i].rdatas[0].data + 1))[0])
- != (uint16_t) (rrset->rrs[i].rdatas[0].data[0]-1))
+ || rrset->rrs[i]->rdata[0] < 1)
continue;
memcpy( group_value
- , (uint8_t*)(rrset->rrs[i].rdatas[0].data+1) + 1
- ,((uint8_t*)(rrset->rrs[i].rdatas[0].data+1))[0]
+ , rrset->rrs[i]->rdata+1
+ , rrset->rrs[i]->rdata[0]
);
group_value[
- ((uint8_t*)(rrset->rrs[i].rdatas[0].data+1))[0]
+ rrset->rrs[i]->rdata[0]
] = 0;
if ((pattern = pattern_options_find(
xfrd->nsd->options, group_value)))
@@ -715,13 +712,14 @@ retry_adding:
member_id_to_delete_str));
catalog_del_consumer_member_zone(
consumer_zone, to_delete);
- if(cursor != RBTREE_NULL)
+ if(cursor != RBTREE_NULL) {
DEBUG(DEBUG_XFRD,1, (LOG_INFO,
"Comparing %s with %s",
member_id_str,
dname_to_string(
cursor_member_id(cursor),
NULL)));
+ }
}
if (cursor != RBTREE_NULL && cmp == 0) {
/* member_id is also in an current catalog
Index: xfrd-disk.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/xfrd-disk.c,v
diff -u -p -r1.16 xfrd-disk.c
--- xfrd-disk.c 12 Apr 2024 15:53:34 -0000 1.16
+++ xfrd-disk.c 18 Mar 2026 20:44:03 -0000
@@ -91,6 +91,7 @@ xfrd_read_state_soa(FILE* in, const char
const char* id, xfrd_soa_type* soa, time_t* soatime)
{
char *p;
+ uint16_t rdata_count = 0;
if(!xfrd_read_check_str(in, id_acquired) ||
!xfrd_read_time_t(in, soatime)) {
@@ -104,7 +105,7 @@ xfrd_read_state_soa(FILE* in, const char
!xfrd_read_i16(in, &soa->type) ||
!xfrd_read_i16(in, &soa->klass) ||
!xfrd_read_i32(in, &soa->ttl) ||
- !xfrd_read_i16(in, &soa->rdata_count))
+ !xfrd_read_i16(in, &rdata_count))
{
return 0;
}
@@ -112,7 +113,6 @@ xfrd_read_state_soa(FILE* in, const char
soa->type = htons(soa->type);
soa->klass = htons(soa->klass);
soa->ttl = htonl(soa->ttl);
- soa->rdata_count = htons(soa->rdata_count);
if(!(p=xfrd_read_token(in)) ||
!(soa->prim_ns[0] = dname_parse_wire(soa->prim_ns+1, p)))
@@ -428,7 +428,11 @@ xfrd_write_state_soa(FILE* out, const ch
fprintf(out, "\t%s: %u %u %u %u", id,
(unsigned)ntohs(soa->type), (unsigned)ntohs(soa->klass),
- (unsigned)ntohl(soa->ttl), (unsigned)ntohs(soa->rdata_count));
+ (unsigned)ntohl(soa->ttl),
+ /* This is the old rdata_count, and is printed for
+ * compatibility. Otherwise, if it is not printed, change
+ * the xfrd state file version number. */
+ (unsigned)7);
fprintf(out, " ");
xfrd_write_dname(out, soa->prim_ns);
fprintf(out, " ");
Index: xfrd.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/xfrd.c,v
diff -u -p -r1.35 xfrd.c
--- xfrd.c 6 Sep 2025 17:41:37 -0000 1.35
+++ xfrd.c 18 Mar 2026 20:44:03 -0000
@@ -627,13 +627,16 @@ apply_xfrs_to_consumer_zone(struct xfrd_
FILE* df;
if(xfr->msg_is_ixfr) {
- uint32_t soa_serial;
+ uint32_t soa_serial=0, after_serial=0;
xfrd_xfr_type* prev;
- if(dbzone->soa_rrset == NULL || dbzone->soa_rrset->rrs == NULL
- || dbzone->soa_rrset->rrs[0].rdata_count <= 2
- || rdata_atom_size(dbzone->soa_rrset->rrs[0].rdatas[2])
- != sizeof(uint32_t)) {
+ if(dbzone->soa_rrset == NULL
+#ifndef PACKED_STRUCTS
+ || dbzone->soa_rrset->rrs == NULL
+#endif
+ || dbzone->soa_rrset->rrs[0]->rdlength < 20+2*sizeof(void*)
+ || !retrieve_soa_rdata_serial(dbzone->soa_rrset->rrs[0],
+ &soa_serial)) {
make_catalog_consumer_invalid(consumer_zone,
"could not apply ixfr on catalog consumer zone "
@@ -641,8 +644,6 @@ apply_xfrs_to_consumer_zone(struct xfrd_
consumer_zone->options->name);
return;
}
- soa_serial = read_uint32(rdata_atom_data(
- dbzone->soa_rrset->rrs[0].rdatas[2]));
if(soa_serial == xfr->msg_old_serial)
goto apply_xfr;
for(prev = xfr->prev; prev; prev = prev->prev) {
@@ -653,8 +654,10 @@ apply_xfrs_to_consumer_zone(struct xfrd_
apply_xfrs_to_consumer_zone(consumer_zone, dbzone, prev);
break;
}
- if(!prev || xfr->msg_old_serial != read_uint32(rdata_atom_data(
- dbzone->soa_rrset->rrs[0].rdatas[2]))){
+ if(!prev
+ || !retrieve_soa_rdata_serial(dbzone->soa_rrset->rrs[0],
+ &after_serial)
+ || xfr->msg_old_serial != after_serial) {
make_catalog_consumer_invalid(consumer_zone,
"could not find and/or apply xfrs for catalog "
"consumer zone \'%s\': to update to serial %u",
@@ -729,7 +732,6 @@ xfrd_process_soa_info_task(struct task_l
soa.klass = htons(CLASS_IN);
memmove(&soa.ttl, p, sizeof(uint32_t));
p += sizeof(uint32_t);
- soa.rdata_count = htons(7);
memmove(soa.prim_ns, p, sizeof(uint8_t));
p += sizeof(uint8_t);
memmove(soa.prim_ns+1, p, soa.prim_ns[0]);
@@ -1377,22 +1379,24 @@ xfrd_time()
void
xfrd_copy_soa(xfrd_soa_type* soa, rr_type* rr)
{
- const uint8_t* rr_ns_wire = dname_name(domain_dname(rdata_atom_domain(rr->rdatas[0])));
- uint8_t rr_ns_len = domain_dname(rdata_atom_domain(rr->rdatas[0]))->name_size;
- const uint8_t* rr_em_wire = dname_name(domain_dname(rdata_atom_domain(rr->rdatas[1])));
- uint8_t rr_em_len = domain_dname(rdata_atom_domain(rr->rdatas[1]))->name_size;
+ const uint8_t* rr_ns_wire = dname_name(domain_dname(rdata_domain_ref(rr)));
+ uint8_t rr_ns_len = domain_dname(rdata_domain_ref(rr))->name_size;
+ const uint8_t* rr_em_wire = dname_name(domain_dname(
+ rdata_domain_ref_offset(rr, sizeof(void*))));
+ uint8_t rr_em_len = domain_dname(rdata_domain_ref_offset(rr,
+ sizeof(void*)))->name_size;
+ uint8_t* p;
- if(rr->type != TYPE_SOA || rr->rdata_count != 7) {
+ if(rr->type != TYPE_SOA || rr->rdlength != 20+2*sizeof(void*)) {
log_msg(LOG_ERR, "xfrd: copy_soa called with bad rr, type %d rrs %u.",
- rr->type, rr->rdata_count);
+ rr->type, (unsigned)rr->rdlength);
return;
}
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: copy_soa rr, type %d rrs %u, ttl %u.",
- (int)rr->type, (unsigned)rr->rdata_count, (unsigned)rr->ttl));
+ (int)rr->type, (unsigned)rr->rdlength, (unsigned)rr->ttl));
soa->type = htons(rr->type);
soa->klass = htons(rr->klass);
soa->ttl = htonl(rr->ttl);
- soa->rdata_count = htons(rr->rdata_count);
/* copy dnames */
soa->prim_ns[0] = rr_ns_len;
@@ -1401,11 +1405,12 @@ xfrd_copy_soa(xfrd_soa_type* soa, rr_typ
memcpy(soa->email+1, rr_em_wire, rr_em_len);
/* already in network format */
- memcpy(&soa->serial, rdata_atom_data(rr->rdatas[2]), sizeof(uint32_t));
- memcpy(&soa->refresh, rdata_atom_data(rr->rdatas[3]), sizeof(uint32_t));
- memcpy(&soa->retry, rdata_atom_data(rr->rdatas[4]), sizeof(uint32_t));
- memcpy(&soa->expire, rdata_atom_data(rr->rdatas[5]), sizeof(uint32_t));
- memcpy(&soa->minimum, rdata_atom_data(rr->rdatas[6]), sizeof(uint32_t));
+ p = rr->rdata + 2*sizeof(void*);
+ memcpy(&soa->serial, p, sizeof(uint32_t));
+ memcpy(&soa->refresh, p+4, sizeof(uint32_t));
+ memcpy(&soa->retry, p+8, sizeof(uint32_t));
+ memcpy(&soa->expire, p+12, sizeof(uint32_t));
+ memcpy(&soa->minimum, p+16, sizeof(uint32_t));
DEBUG(DEBUG_XFRD,1, (LOG_INFO,
"xfrd: copy_soa rr, serial %u refresh %u retry %u expire %u",
(unsigned)ntohl(soa->serial), (unsigned)ntohl(soa->refresh),
@@ -1979,7 +1984,6 @@ static int xfrd_parse_soa_info(buffer_ty
{
return 0;
}
- soa->rdata_count = 7; /* rdata in SOA */
soa->serial = htonl(buffer_read_u32(packet));
soa->refresh = htonl(buffer_read_u32(packet));
soa->retry = htonl(buffer_read_u32(packet));
@@ -2002,12 +2006,14 @@ xfrd_xfr_check_rrs(xfrd_zone_type* zone,
int *done, xfrd_soa_type* soa, region_type* temp)
{
/* first RR has already been checked */
+ const struct nsd_type_descriptor *descriptor;
uint32_t tmp_serial = 0;
uint16_t type, rrlen;
size_t i, soapos, mempos;
const dname_type* dname;
+ struct rr* rr;
+ int32_t code;
domain_table_type* owners;
- rdata_atom_type* rdatas;
for(i=0; i<count; ++i,++zone->latest_xfr->msg_rr_count)
{
@@ -2041,10 +2047,15 @@ xfrd_xfr_check_rrs(xfrd_zone_type* zone,
return 0;
}
mempos = buffer_position(packet);
- if(rdata_wireformat_to_rdata_atoms(temp, owners, type, rrlen,
- packet, &rdatas) == -1) {
+
+ descriptor = nsd_type_descriptor(type);
+ code = descriptor->read_rdata(owners, rrlen, packet, &rr);
+ if(code < 0) {
DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr unable "
- "to parse rdata", zone->apex_str));
+ "to parse rdata %s %s %s", zone->apex_str,
+ dname_to_string(dname,0),
+ rrtype_to_string(type),
+ read_rdata_fail_str(code)));
return 0;
}
if(type == TYPE_SOA) {
@@ -3005,9 +3016,14 @@ void xfrd_process_task_result(xfrd_state
void xfrd_set_reload_now(xfrd_state_type* xfrd)
{
-#ifdef HAVE_SYSTEMD
- sd_notify(0, "RELOADING=1");
-#endif
+ /* systemd kills after a timer, but a large zone can take time.
+ * so there is no,
+ * #ifdef HAVE_SYSTEMD
+ * sd_notify(0, "RELOADING=1");
+ * #endif
+ * message.
+ * Also, NSD stays responsive during that time, due to the forked
+ * operation. */
xfrd->need_to_send_reload = 1;
if(!(xfrd->ipc_handler_flags&EV_WRITE)) {
ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
Index: xfrd.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/xfrd.h,v
diff -u -p -r1.14 xfrd.h
--- xfrd.h 3 Sep 2025 18:46:48 -0000 1.14
+++ xfrd.h 18 Mar 2026 20:44:03 -0000
@@ -137,7 +137,6 @@ struct xfrd_soa {
uint16_t type; /* = TYPE_SOA */
uint16_t klass; /* = CLASS_IN */
uint32_t ttl;
- uint16_t rdata_count; /* = 7 */
/* format is 1 octet length, + wireformat dname.
one more octet since parse_dname_wire_from_packet needs it.
maximum size is allocated to avoid memory alloc/free. */
Index: zonec.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/zonec.c,v
diff -u -p -r1.32 zonec.c
--- zonec.c 3 Sep 2025 18:46:48 -0000 1.32
+++ zonec.c 18 Mar 2026 20:44:03 -0000
@@ -45,60 +45,6 @@
#include "zone.h"
/*
- * Compares two rdata arrays.
- *
- * Returns:
- *
- * zero if they are equal
- * non-zero if not
- *
- */
-static int
-zrdatacmp(uint16_t type, const union rdata_atom *rdatas, size_t rdata_count, rr_type *b)
-{
- assert(rdatas);
- assert(b);
-
- /* One is shorter than another */
- if (rdata_count != b->rdata_count)
- return 1;
-
- /* Compare element by element */
- for (size_t i = 0; i < rdata_count; ++i) {
- if (rdata_atom_is_domain(type, i)) {
- if (rdata_atom_domain(rdatas[i])
- != rdata_atom_domain(b->rdatas[i]))
- {
- return 1;
- }
- } else if(rdata_atom_is_literal_domain(type, i)) {
- if (rdata_atom_size(rdatas[i])
- != rdata_atom_size(b->rdatas[i]))
- return 1;
- if (!dname_equal_nocase(rdata_atom_data(rdatas[i]),
- rdata_atom_data(b->rdatas[i]),
- rdata_atom_size(rdatas[i])))
- return 1;
- } else {
- if (rdata_atom_size(rdatas[i])
- != rdata_atom_size(b->rdatas[i]))
- {
- return 1;
- }
- if (memcmp(rdata_atom_data(rdatas[i]),
- rdata_atom_data(b->rdatas[i]),
- rdata_atom_size(rdatas[i])) != 0)
- {
- return 1;
- }
- }
- }
-
- /* Otherwise they are equal */
- return 0;
-}
-
-/*
* Find rrset type for any zone
*/
static rrset_type*
@@ -162,13 +108,99 @@ has_soa(domain_type* domain)
struct zonec_state {
struct namedb *database;
struct domain_table *domains;
- struct region *rr_region;
struct zone *zone;
- struct domain *domain;
size_t errors;
size_t records;
+
+ struct collect_rrs c;
};
+static void zonec_commit_rrset(zone_parser_t *parser, struct zonec_state *state)
+{
+ struct rrset *rrset;
+ int priority = parser->options.secondary ? ZONE_WARNING : ZONE_ERROR;
+
+ if(!state->c.domain || state->c.rr_count == 0)
+ return;
+ if (!state->c.rrset) {
+ rrset = region_alloc(state->database->region, sizeof(*rrset)
+#ifdef PACKED_STRUCTS
+ + sizeof(rr_type*) * state->c.rr_count /* Add space for RRs. */
+#endif
+ );
+ rrset->zone = state->zone;
+ rrset->rr_count = state->c.rr_count;
+#ifndef PACKED_STRUCTS
+ rrset->rrs = region_alloc(state->database->region,
+ sizeof(rr_type*) * state->c.rr_count);
+#endif
+ memcpy(rrset->rrs, state->c.rrs, state->c.rr_count * sizeof(rr_type*));
+ switch (state->c.type) {
+ case TYPE_CNAME:
+ if (!domain_find_non_cname_rrset(state->c.domain, state->zone))
+ break;
+ zone_log(parser, priority, "CNAME and other data at the same name");
+ break;
+ case TYPE_RRSIG:
+ case TYPE_NXT:
+ case TYPE_SIG:
+ case TYPE_NSEC:
+ case TYPE_NSEC3:
+ break;
+ default:
+ if (!domain_find_rrset(state->c.domain, state->zone, TYPE_CNAME))
+ break;
+ zone_log(parser, priority, "CNAME and other data at the same name");
+ break;
+ }
+ /* Add it */
+ domain_add_rrset(state->c.domain, rrset);
+ } else {
+#ifndef PACKED_STRUCTS
+ struct rr **rrs;
+#else
+ struct rrset *rrset_orig;
+#endif
+ /* Add it... */
+ rrset = state->c.rrset;
+#ifndef PACKED_STRUCTS
+ rrs = rrset->rrs;
+ rrset->rrs = region_alloc_array(
+ state->database->region, rrset->rr_count + state->c.rr_count, sizeof(*rrs));
+ memcpy(rrset->rrs, rrs, rrset->rr_count * sizeof(*rrs));
+ region_recycle(state->database->region, rrs, rrset->rr_count * sizeof(*rrs));
+#else
+ rrset_orig = rrset;
+ rrset = region_alloc(state->database->region,
+ sizeof(rrset_type) +
+ (rrset_orig->rr_count+state->c.rr_count)*sizeof(rr_type*));
+ memcpy(rrset, rrset_orig,
+ sizeof(rrset_type) +
+ rrset_orig->rr_count*sizeof(rr_type*));
+ if(state->c.rrset_prev)
+ state->c.rrset_prev->next = rrset;
+ else state->c.domain->rrsets = rrset;
+ region_recycle(state->database->region, rrset_orig,
+ sizeof(rrset_type) +
+ rrset_orig->rr_count*sizeof(rr_type*));
+#endif /* PACKED_STRUCTS */
+ memcpy(rrset->rrs + rrset->rr_count, state->c.rrs, state->c.rr_count * sizeof(rr_type*));
+ rrset->rr_count += state->c.rr_count;
+ }
+ state->records += state->c.rr_count;;
+ /* Check we have SOA */
+ if (state->c.rrs[0]->owner == state->zone->apex)
+ apex_rrset_checks(state->database, rrset, state->c.rrs[0]->owner);
+
+ state->c.domain = NULL;
+ state->c.type = -1;
+ state->c.rrset = NULL;
+#ifdef PACKED_STRUCTS
+ state->c.rrset_prev = NULL;
+#endif
+ state->c.rr_count = 0;
+}
+
int32_t zonec_accept(
zone_parser_t *parser,
const zone_name_t *owner,
@@ -180,36 +212,53 @@ int32_t zonec_accept(
void *user_data)
{
struct rr *rr;
- struct rrset *rrset;
- const struct dname *dname;
+ struct dname_buffer dname;
struct domain *domain;
struct buffer buffer;
int priority;
- union rdata_atom *rdatas;
- ssize_t rdata_count;
+ int32_t code;
+ const struct nsd_type_descriptor *descriptor;
struct zonec_state *state = (struct zonec_state *)user_data;
-
assert(state);
- // emulate packet buffer to leverage rdata_wireformat_to_rdata_atoms
buffer_create_from(&buffer, rdata, rdlength);
priority = parser->options.secondary ? ZONE_WARNING : ZONE_ERROR;
- // limit to IN class
+ /* limit to IN class */
if (class != CLASS_IN)
zone_log(parser, priority, "only class IN is supported");
- dname = dname_make(state->rr_region, owner->octets, 1);
- assert(dname);
- domain = domain_table_insert(state->domains, dname);
+ if(!dname_make_buffered(&dname, (uint8_t*)owner->octets, 1)) {
+ zone_log(parser, ZONE_ERROR, "the owner cannot be converted");
+ return ZONE_BAD_PARAMETER;
+ }
+ domain = domain_table_insert(state->domains, (void*)&dname);
assert(domain);
-
- rdatas = NULL;
- rdata_count = rdata_wireformat_to_rdata_atoms(
- state->database->region, state->domains, type, rdlength, &buffer, &rdatas);
- // number of atoms must not exceed maximum of 65535 (all empty strings)
- assert(rdata_count >= 0);
- assert(rdata_count <= MAX_RDLENGTH);
+ if (domain != state->c.domain || type != state->c.type
+ || state->c.rr_count >= (int)(sizeof(state->c.rrs) / sizeof(*state->c.rrs))){
+ zonec_commit_rrset(parser, state);
+ state->c.domain = domain;
+ state->c.type = type;
+ state->c.rrset = NULL;
+#ifdef PACKED_STRUCTS
+ state->c.rrset_prev = NULL;
+#endif
+ }
+ descriptor = nsd_type_descriptor(type);
+ code = descriptor->read_rdata(state->domains, rdlength, &buffer, &rr);
+ if(code < 0) {
+ zone_log(parser, ZONE_ERROR, "the RR rdata fields are wrong for the type, %s %s %s",
+ dname_to_string((void*)&dname,0),
+ rrtype_to_string(type),
+ read_rdata_fail_str(code));
+ if(code == TRUNCATED)
+ return ZONE_OUT_OF_MEMORY;
+ return ZONE_BAD_PARAMETER;
+ }
+ rr->owner = domain;
+ rr->type = type;
+ rr->klass = class;
+ rr->ttl = ttl;
/* we have the zone already */
if (type == TYPE_SOA) {
@@ -230,97 +279,67 @@ int32_t zonec_accept(
zone_log(parser, priority, "out of zone data: %s is outside the zone for fqdn %s",
s, domain_to_string(domain));
if (!parser->options.secondary) {
- region_free_all(state->rr_region);
return ZONE_SEMANTIC_ERROR;
}
}
-
- /* Do we have this type of rrset already? */
- rrset = domain_find_rrset(domain, state->zone, type);
- if (!rrset) {
- rrset = region_alloc(state->database->region, sizeof(*rrset));
- rrset->zone = state->zone;
- rrset->rr_count = 0;
- rrset->rrs = region_alloc(state->database->region, sizeof(*rr));
-
+ /* With the first RR for a RRset in this position in the zone file,
+ * find the RRset */
+ if (state->c.rr_count == 0) {
+#ifndef PACKED_STRUCTS
+ state->c.rrset = domain_find_rrset(state->c.domain, state->zone, state->c.type);
+#else
+ state->c.rrset = domain_find_rrset_and_prev(state->c.domain, state->zone, state->c.type, &state->c.rrset_prev);
+#endif
+ }
+ if (type == TYPE_RRSIG)
+ ; /* pass */
+ else if (state->c.rrset && ttl != state->c.rrset->rrs[0]->ttl) {
+ zone_log(parser, ZONE_WARNING,
+ "%s TTL %"PRIu32" does not match TTL %u of %s RRset",
+ domain_to_string(domain), ttl,
+ state->c.rrset->rrs[0]->ttl, rrtype_to_string(type));
+
+ } else if (state->c.rr_count && ttl != state->c.rrs[0]->ttl) {
+ zone_log(parser, ZONE_WARNING,
+ "%s TTL %"PRIu32" does not match TTL %u of %s RRset",
+ domain_to_string(domain), ttl,
+ state->c.rrs[0]->ttl, rrtype_to_string(type));
+ }
+ if (state->c.rrset || state->c.rr_count) {
switch (type) {
case TYPE_CNAME:
- if (!domain_find_non_cname_rrset(domain, state->zone))
- break;
- zone_log(parser, priority, "CNAME and other data at the same name");
+ zone_log(parser, priority, "multiple CNAMEs at the same name");
break;
- case TYPE_RRSIG:
- case TYPE_NXT:
- case TYPE_SIG:
- case TYPE_NSEC:
- case TYPE_NSEC3:
+ case TYPE_DNAME:
+ zone_log(parser, priority, "multiple DNAMEs at the same name");
break;
default:
- if (!domain_find_rrset(domain, state->zone, TYPE_CNAME))
- break;
- zone_log(parser, priority, "CNAME and other data at the same name");
break;
}
-
- /* Add it */
- domain_add_rrset(domain, rrset);
- } else {
- struct rr *rrs;
- if (type != TYPE_RRSIG && ttl != rrset->rrs[0].ttl) {
- zone_log(parser, ZONE_WARNING, "%s TTL %"PRIu32" does not match TTL %u of %s RRset",
- domain_to_string(domain), ttl, rrset->rrs[0].ttl,
- rrtype_to_string(type));
- }
-
- /* Search for possible duplicates... */
- for (int i = 0; i < rrset->rr_count; i++) {
- if (zrdatacmp(type, rdatas, rdata_count, &rrset->rrs[i]) != 0)
+ }
+ if (state->c.rrset) {
+ /* Search for possible duplicates in existing RRset */
+ for (int i = 0; i < state->c.rrset->rr_count; i++) {
+ if (!equal_rr_rdata(descriptor, rr, state->c.rrset->rrs[i]))
continue;
/* Discard the duplicates... */
- for (size_t j = 0; j < (size_t)rdata_count; j++) {
- size_t size;
- if (rdata_atom_is_domain(type, j))
- continue;
- size = rdata_atom_size(rdatas[j]) + sizeof(uint16_t);
- region_recycle(state->database->region, rdatas[j].data, size);
- }
- region_recycle(state->database->region, rdatas, sizeof(*rdatas) * rdata_count);
- region_free_all(state->rr_region);
+ /* Lower the usage counter for domains in the rdata. */
+ rr_lower_usage(state->database, rr);
+ region_recycle(state->database->region, rr, sizeof(*rr) + rr->rdlength);
return 0;
}
-
- switch (type) {
- case TYPE_CNAME:
- zone_log(parser, priority, "multiple CNAMEs at the same name");
- break;
- case TYPE_DNAME:
- zone_log(parser, priority, "multiple DNAMEs at the same name");
- break;
- default:
- break;
- }
-
- /* Add it... */
- rrs = rrset->rrs;
- rrset->rrs = region_alloc_array(state->database->region, rrset->rr_count + 1, sizeof(*rr));
- memcpy(rrset->rrs, rrs, rrset->rr_count * sizeof(*rr));
- region_recycle(state->database->region, rrs, rrset->rr_count * sizeof(*rr));
}
-
- rr = &rrset->rrs[rrset->rr_count++];
- rr->owner = domain;
- rr->rdatas = rdatas;
- rr->ttl = ttl;
- rr->type = type;
- rr->klass = class;
- rr->rdata_count = rdata_count;
-
- /* Check we have SOA */
- if (rr->owner == state->zone->apex)
- apex_rrset_checks(state->database, rrset, rr->owner);
-
- state->records++;
- region_free_all(state->rr_region);
+ /* Search for possible duplicates in already batched RRs */
+ for (int i = 0; i < state->c.rr_count; i++) {
+ if (!equal_rr_rdata(descriptor, rr, state->c.rrs[i]))
+ continue;
+ /* Discard the duplicates... */
+ /* Lower the usage counter for domains in the rdata. */
+ rr_lower_usage(state->database, rr);
+ region_recycle(state->database->region, rr, sizeof(*rr) + rr->rdlength);
+ return 0;
+ }
+ state->c.rrs[state->c.rr_count++] = rr;
return 0;
}
@@ -416,12 +435,17 @@ zonec_read(
state.database = database;
state.domains = domains;
- state.rr_region = region_create(xalloc, free);
state.zone = zone;
- state.domain = NULL;
state.errors = 0;
state.records = 0;
+ state.c.domain = NULL;
+ state.c.type = -1;
+ state.c.rrset = NULL;
+#ifdef PACKED_STRUCTS
+ state.c.rrset_prev = NULL;
+#endif
+ state.c.rr_count = 0;
origin = domain_dname(zone->apex);
memset(&options, 0, sizeof(options));
options.origin.octets = dname_name(origin);
@@ -436,9 +460,19 @@ zonec_read(
/* Parse and process all RRs. */
if (zone_parse(&parser, &options, &buffers, zonefile, &state) != 0) {
- region_destroy(state.rr_region);
+ /* With all socked up RRs,
+ * lower the usage counter for domains in the rdata.
+ */
+ for (int i = 0; i < state.c.rr_count; i++) {
+ /* Lower the usage counter for domains in the rdata. */
+ rr_lower_usage(database, state.c.rrs[i]);
+ region_recycle( database->region, state.c.rrs[i]
+ , sizeof(*state.c.rrs[i])
+ + state.c.rrs[i]->rdlength);
+ }
return state.errors;
}
+ zonec_commit_rrset(&parser, &state);
/* Check if zone file contained a correct SOA record */
if (!zone) {
@@ -447,23 +481,22 @@ zonec_read(
} else if (!zone->soa_rrset || zone->soa_rrset->rr_count == 0) {
log_msg(LOG_ERR, "zone configured as '%s' has no SOA record", name);
state.errors++;
- } else if (dname_compare(domain_dname(zone->soa_rrset->rrs[0].owner), origin) != 0) {
+ } else if (dname_compare(domain_dname(zone->soa_rrset->rrs[0]->owner), origin) != 0) {
log_msg(LOG_ERR, "zone configured as '%s', but SOA has owner '%s'",
- name, domain_to_string(zone->soa_rrset->rrs[0].owner));
+ name, domain_to_string(zone->soa_rrset->rrs[0]->owner));
state.errors++;
}
if(!zone_is_slave(zone->opts) && !check_dname(zone))
state.errors++;
- region_destroy(state.rr_region);
return state.errors;
}
void
apex_rrset_checks(namedb_type* db, rrset_type* rrset, domain_type* domain)
{
- uint32_t soa_minimum;
+ uint32_t soa_minimum = 0;
unsigned i;
zone_type* zone = rrset->zone;
assert(domain == zone->apex);
@@ -474,26 +507,34 @@ apex_rrset_checks(namedb_type* db, rrset
/* BUG #103 add another soa with a tweaked ttl */
if(zone->soa_nx_rrset == 0) {
zone->soa_nx_rrset = region_alloc(db->region,
- sizeof(rrset_type));
+ sizeof(rrset_type)
+#ifdef PACKED_STRUCTS
+ + sizeof(rr_type*)
+#endif
+ );
zone->soa_nx_rrset->rr_count = 1;
zone->soa_nx_rrset->next = 0;
zone->soa_nx_rrset->zone = zone;
+#ifndef PACKED_STRUCTS
zone->soa_nx_rrset->rrs = region_alloc(db->region,
- sizeof(rr_type));
+ sizeof(rr_type*));
+#endif
+ zone->soa_nx_rrset->rrs[0] = region_alloc(db->region,
+ sizeof(rr_type)+rrset->rrs[0]->rdlength);
}
- memcpy(zone->soa_nx_rrset->rrs, rrset->rrs, sizeof(rr_type));
+ memcpy(zone->soa_nx_rrset->rrs[0], rrset->rrs[0],
+ sizeof(rr_type)+rrset->rrs[0]->rdlength);
/* check the ttl and MINIMUM value and set accordingly */
- memcpy(&soa_minimum, rdata_atom_data(rrset->rrs->rdatas[6]),
- rdata_atom_size(rrset->rrs->rdatas[6]));
- if (rrset->rrs->ttl > ntohl(soa_minimum)) {
- zone->soa_nx_rrset->rrs[0].ttl = ntohl(soa_minimum);
+ retrieve_soa_rdata_minttl(rrset->rrs[0], &soa_minimum);
+ if (rrset->rrs[0]->ttl > soa_minimum) {
+ zone->soa_nx_rrset->rrs[0]->ttl = soa_minimum;
}
} else if (rrset_rrtype(rrset) == TYPE_NS) {
zone->ns_rrset = rrset;
} else if (rrset_rrtype(rrset) == TYPE_RRSIG) {
for (i = 0; i < rrset->rr_count; ++i) {
- if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY){
+ if(rr_rrsig_type_covered(rrset->rrs[i])==TYPE_DNSKEY){
zone->is_secure = 1;
break;
}
Index: zonec.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/zonec.h,v
diff -u -p -r1.15 zonec.h
--- zonec.h 6 Sep 2025 17:41:37 -0000 1.15
+++ zonec.h 18 Mar 2026 20:44:03 -0000
@@ -30,6 +30,26 @@
#define DEFAULT_TTL 3600
+/* Some zones, such as DNS-SD zones, have RRsets with many RRs in them.
+ * By minimizing the need to reallocate the list of RRs in an RRset,
+ * we reduce memory fragmentation significantly for such zones.
+ * To this end, `domain`, `type`, `rrset`, `rrset_prev`, `rr_count` and
+ * `rrs` are used to commit the RRs within an RRset, that are grouped
+ * together in a zone file, to the database in batches.
+ */
+struct collect_rrs {
+ struct domain *domain;
+ int type;
+ struct rrset *rrset;
+#ifdef PACKED_STRUCTS
+ struct rrset *rrset_prev;
+#endif
+ int rr_count;
+ /* When the RRset is more than 256 RRs, the set will be committed in
+ * batches of 256 RRs (and resized if needed) */
+ struct rr* rrs[256];
+};
+
/* parse a zone into memory. name is origin. zonefile is file to read.
* returns number of errors; failure may have read a partial zone */
unsigned int zonec_read(
Index: compat/cpuset.h
===================================================================
RCS file: compat/cpuset.h
diff -N compat/cpuset.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ compat/cpuset.h 18 Mar 2026 20:44:03 -0000
@@ -0,0 +1,79 @@
+/*
+ * cpuset.h -- CPU affinity.
+ *
+ * Copyright (c) 2020, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ */
+#ifndef CPUSET_H
+#define CPUSET_H
+
+#ifdef HAVE_SCHED_H
+# include <sched.h>
+#endif
+
+#ifdef HAVE_SYS_CPUSET_H
+# include <sys/cpuset.h>
+#endif
+
+/*
+ * CPU affinity is currently only supported on Linux and FreeBSD. Other
+ * operating systems may be supported in the future, but not all operating
+ * systems offer the same functionality. OpenBSD for example does not support
+ * any kind of CPU affinity, while Solaris offers specifying a set of
+ * processors, but a processor can only be part of a single set.
+ *
+ * NOTE: On macOS Mojave, processor_set_create returned KERN_FAILURE which
+ * indicates processor allocation is not supported by the operating
+ * system.
+ */
+
+#ifndef HAVE_CPUSET_T
+#ifdef HAVE_CPU_SET_T
+#define HAVE_CPUSET_T 1
+typedef cpu_set_t cpuset_t;
+#endif
+#endif
+
+#ifndef HAVE_CPUID_T
+#ifdef __linux__
+typedef int cpuid_t;
+#elif defined(__FreeBSD__) || defined(__gnu_hurd__) || defined(__DragonFly__)
+typedef size_t cpuid_t;
+#else
+typedef size_t cpuid_t;
+#endif
+#endif
+
+#ifndef HAVE_CPUSET_CREATE
+cpuset_t *cpuset_create(void);
+#endif
+
+#ifndef HAVE_CPUSET_DESTROY
+void cpuset_destroy(cpuset_t *set);
+#endif
+
+#ifndef HAVE_CPUSET_ZERO
+void cpuset_zero(cpuset_t *set);
+#endif
+
+#ifndef HAVE_CPUSET_SET
+int cpuset_set(cpuid_t cpu, cpuset_t *set);
+#endif
+
+#ifndef HAVE_CPUSET_CLR
+int cpuset_clr(cpuid_t cpu, cpuset_t *set);
+#endif
+
+#ifndef HAVE_CPUSET_ISSET
+int cpuset_isset(cpuid_t cpu, const cpuset_t *set);
+#endif
+
+#ifndef HAVE_CPUSET_SIZE
+size_t cpuset_size(const cpuset_t *set);
+#endif
+
+void cpuset_or(cpuset_t *destset, const cpuset_t *srcset);
+
+#endif /* CPUSET_H */
Index: dnstap/dnstap.m4
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/dnstap/dnstap.m4,v
diff -u -p -r1.5 dnstap.m4
--- dnstap/dnstap.m4 6 Sep 2025 17:41:37 -0000 1.5
+++ dnstap/dnstap.m4 18 Mar 2026 20:44:03 -0000
@@ -78,6 +78,8 @@ EOF
])
AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [],
AC_MSG_ERROR([[The fstrm library was not found. It is needed for dnstap, use --disable-dnstap, or install fstrm-devel]]))
+ AC_CHECK_FUNCS([fstrm_tcp_writer_options_init], [],
+ AC_MSG_ERROR([[The fstrm library >= 0.4 was not found. It is needed for dnstap, use --disable-dnstap, or install fstrm-devel]]))
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
AC_MSG_ERROR([[The protobuf-c library was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c]]))
$2
Index: doc/ChangeLog
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/doc/ChangeLog,v
diff -u -p -r1.20 ChangeLog
--- doc/ChangeLog 6 Sep 2025 17:41:37 -0000 1.20
+++ doc/ChangeLog 18 Mar 2026 20:44:03 -0000
@@ -1,5 +1,107 @@
+23 February 2026: Wouter
+ - Fix systemd signalling so that it does not reload for too long.
+ The reload is not signalled to systemd, so that long operations
+ can complete, without systemd acting on a timer to stop them.
+
+20 February 2026: Wouter
+ - Fix man page for ip-address, add text about process numbers,
+ bindtodevice and setfib.
+
+16 February 2026: Willem
+ - Merge #472: Reduce memory usage with zones with RRsets
+ consisting of many RRs.
+
+13 February 2026: Wouter
+ - Fix to escape slashes when they appear in the zone name for a
+ pattern zonefile that is created. Also for per zone statistics.
+
+2 February 2026: Wouter
+ - Fix metrics to clear server variable after close and log error
+ on allocation failure.
+
+15 January 2026: Wouter
+ - Fix #475 info: axfr for domain from not-verified.
+
+7 January 2026: Wouter
+ - Fix that non normalized NSEC next owner names are preserved.
+ - Fix to preserve case in literal dnames in RR types RRSIG,
+ IPSECKEY, TALINK, DSYNC and AMTRELAY.
+ - Fix for #474: Fix metrics name for zone statistics for
+ the queries_total to have disallowed characters changed
+ to underscores.
+ - Fix to silence restricted userns check in test script.
+
+6 January 2026: Wouter
+ - Fix #474: metrics output with zone statistics to change
+ disallowed characters in metric names to underscores.
+
+21 December 2025: Willem
+ - Fix rr-test.tdir so AMTRELAY relay field is "." with type 0
+ - Fix checkconf.tdir test to anticipate default values for
+ send-buffer-size and receive-buffer-size when configured with 0
+ - skip dns-cookies.tdir test with restricted unpriviledged userns
+
+1 December 2025: Jannik
+ - The master branch continues with version 4.14.1 in development
+ - Merge #469 from jschlyter: Add container build files
+ - Merge #470 from jschlyter: Update path to default container
+ configuration and entrypoint
+
+1 December 2025: Wouter
+ - Fix to note DSYNC RFC9859 reference.
+ - Fix to note reference for NXNAME in comment.
+
+27 November 2025: Jannik
+ - Merge #444: Refactor RDATA storage to reduce memory footprint
+
+12 November 2025: Willem
+ - Merge #466: Do not delete nodes from non-existent zone's NSEC3 hash
+ trees
+
+6 November 2025: Wouter
+ - Update acx_nlnetlabs.m4 to version 51, with nonstring unknown
+ attribute warning fix.
+
+3 November 2025: Wouter
+ - For #137: Change default for the listen TCP backlog to -1 on
+ BSDs and Linux.
+
+2 October 2025: Wouter
+ - Fix #137: Adds tcp-listen-queue: number config option to set
+ the TCP backlog.
+
+29 September 2025: Wouter
+ - Update in acx_nlnetlabs.m4 to version 49.
+ - Update in acx_nlnetlabs.m4 to version 50, with cache value for
+ malloc function check.
+
+17 September 2025: Wouter
+ - Fix to log more details when send-buffer-size or receive-buffer-size
+ is not granted, on verbosity level 2.
+
+15 September 2025: Jannik
+ - Fix confusing report for default send and receive buffer-size by
+ nsd-checkconf
+
+11 September 2025: Jannik
+ - Merge #460: Add XDP_OBJ fixing link errors for XDP.
+ - Fix XDP build error with --enable-checking
+ - Resolve warnings about mixed declaration and code and unused variable
+
+11 September 2025: Wouter
+ - Merge #459: Check for libfstrm version >= 0.4.
+ - For #459: Add configure check for fstrm_tcp_writer_options_init
+ in addition to the check for fstrm_iothr_init.
+
+8 September 2025: Wouter
+ - Fix empty debug statement body in catalog consumer zone process.
+
03 September 2025: Jannik
- Fix zonestatfd check
+ - The main branch continues with version 4.13.1 in development.
+
+3 September 2025: Wouter
+ - Set code repository configure for version 4.13.1 in development.
18 August 2025: Willem
- Merge #455: --with-dbdir option for configure to set the base
Index: doc/README
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/doc/README,v
diff -u -p -r1.10 README
--- doc/README 6 Sep 2025 17:41:37 -0000 1.10
+++ doc/README 18 Mar 2026 20:44:03 -0000
@@ -21,7 +21,7 @@
1.0 Introduction
-This is NSD Name Server Daemon (NSD) version 4.13.0.
+This is NSD Name Server Daemon (NSD) version 4.14.1.
The NLnet Labs Name Server Daemon (NSD) is an authoritative RFC compliant
DNS nameserver. It was first conceived to allow for more genetic
@@ -57,7 +57,7 @@ and uses a simple configuration file 'ns
1.2 Quick build and install
-Step 1: Unpack the source with gtar -xzvf nsd-4.13.0.tar.gz
+Step 1: Unpack the source with gtar -xzvf nsd-4.14.1.tar.gz
Step 2: Create user nsd or any other unprivileged user of your
choice. In case of later make sure to use
@@ -111,9 +111,9 @@ Step 11: If desired add 'nsd-control wri
Use your favorite combination of tar and gnu zip to unpack the source,
for example
-$ gtar -xzvf nsd-4.13.0.tar.gz
+$ gtar -xzvf nsd-4.14.1.tar.gz
-will unpack the source into the ./nsd-4.13.0 directory...
+will unpack the source into the ./nsd-4.14.1 directory...
2.2 Configuring NSD
Index: doc/RELNOTES
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/doc/RELNOTES,v
diff -u -p -r1.18 RELNOTES
--- doc/RELNOTES 6 Sep 2025 17:41:37 -0000 1.18
+++ doc/RELNOTES 18 Mar 2026 20:44:03 -0000
@@ -1,5 +1,67 @@
NSD RELEASE NOTES
+4.14.1
+================
+FEATURES:
+ - Merge #469 from jschlyter: Add container build files
+BUG FIXES:
+ - Fix to note DSYNC RFC9859 reference.
+ - Fix to note reference for NXNAME in comment.
+ - Merge #470 from jschlyter: Update path to default container
+ configuration and entrypoint
+ - Fix rr-test.tdir so AMTRELAY relay field is "." with type 0
+ - Fix checkconf.tdir test to anticipate default values for
+ send-buffer-size and receive-buffer-size when configured with 0
+ - skip dns-cookies.tdir test with restricted unpriviledged userns
+ - Fix #474: metrics output with zone statistics to change
+ disallowed characters in metric names to underscores.
+ - Fix that non normalized NSEC next owner names are preserved.
+ - Fix to preserve case in literal dnames in RR types RRSIG,
+ IPSECKEY, TALINK, DSYNC and AMTRELAY.
+ - Fix for #474: Fix metrics name for zone statistics for
+ the queries_total to have disallowed characters changed
+ to underscores.
+ - Fix to silence restricted userns check in test script.
+ - Fix #475 info: axfr for domain from not-verified.
+ - Fix metrics to clear server variable after close and log error
+ on allocation failure.
+ - Fix to escape slashes when they appear in the zone name for a
+ pattern zonefile that is created. Also for per zone statistics.
+ - Merge #472: Reduce memory usage with zones with RRsets
+ consisting of many RRs.
+ - Fix man page for ip-address, add text about process numbers,
+ bindtodevice and setfib.
+ - Fix systemd signalling so that it does not reload for too long.
+ The reload is not signalled to systemd, so that long operations
+ can complete, without systemd acting on a timer to stop them.
+
+4.14.0
+================
+FEATURES:
+ - Fix #137: Adds tcp-listen-queue: number config option to set
+ the TCP backlog. And the default for the listen TCP backlog is
+ set to -1 on BSDs and Linux.
+ - Merge #444: Refactor RDATA storage to reduce memory footprint
+BUG FIXES:
+ - Fix empty debug statement body in catalog consumer zone process.
+ - Merge #459: Check for libfstrm version >= 0.4.
+ - For #459: Add configure check for fstrm_tcp_writer_options_init
+ in addition to the check for fstrm_iothr_init.
+ - Merge #460: Add XDP_OBJ fixing link errors for XDP.
+ - Fix XDP build error with --enable-checking
+ - Resolve warnings about mixed declaration and code and unused variable
+ - Fix confusing report for default send and receive buffer-size by
+ nsd-checkconf
+ - Fix to log more details when send-buffer-size or receive-buffer-size
+ is not granted, on verbosity level 2.
+ - Update in acx_nlnetlabs.m4 to version 49.
+ - Update in acx_nlnetlabs.m4 to version 50, with cache value for
+ malloc function check.
+ - Update acx_nlnetlabs.m4 to version 51, with nonstring unknown
+ attribute warning fix.
+ - Merge #466: Do not delete nodes from non-existent zone's NSEC3 hash
+ trees
+
4.13.0
================
FEATURES:
@@ -68,6 +130,9 @@ BUG FIXES:
- Update simdzone with support for --enable-pie.
- Merge #454 from jaredmauch: handle rare case but seen in
production where data->query is NULL.
+ - Fix zonestatfd check
+ - Fix code analyzer warning, and bail out of handle_tcp_writing
+ and handle_tls_writing early when data->query is NULL.
4.12.0
================
Index: simdzone/CHANGELOG.md
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/CHANGELOG.md,v
diff -u -p -r1.1.1.2 CHANGELOG.md
--- simdzone/CHANGELOG.md 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/CHANGELOG.md 18 Mar 2026 20:44:03 -0000
@@ -5,6 +5,17 @@ All notable changes to simdzone will be
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.2.4] - 2025-12-04
+
+### Added
+
+### Fixed
+
+- Correct lengths for GOST R 34.10-2012 and SM3 delegation signer (DS) digest
+ algorithms
+- Require the AMTRELAY relay field to be `.` for the no gateway relay type as
+ specified by RFC 8777 (#257)
+
## [0.2.3] - 2025-09-03
### Added
Index: simdzone/config.guess
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/config.guess,v
diff -u -p -r1.1.1.2 config.guess
--- simdzone/config.guess 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/config.guess 18 Mar 2026 20:44:03 -0000
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2023 Free Software Foundation, Inc.
+# Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2023-08-22'
+timestamp='2022-01-09'
# This file 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,7 @@ me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
-Output the configuration name of the system '$me' is run on.
+Output the configuration name of the system \`$me' is run on.
Options:
-h, --help print this help, then exit
@@ -60,13 +60,13 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try '$me --help' for more information."
+Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -102,8 +102,8 @@ GUESS=
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
-# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
-# use 'HOST_CC' if defined, but it is deprecated.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
@@ -155,9 +155,6 @@ Linux|GNU|GNU/*)
set_cc_for_build
cat <<-EOF > "$dummy.c"
- #if defined(__ANDROID__)
- LIBC=android
- #else
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -172,7 +169,6 @@ Linux|GNU|GNU/*)
LIBC=musl
#endif
#endif
- #endif
EOF
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
eval "$cc_set_libc"
@@ -463,7 +459,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME
UNAME_RELEASE=`uname -v`
;;
esac
- # Japanese Language versions have a version number like '4.1.3-JL'.
+ # Japanese Language versions have a version number like `4.1.3-JL'.
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
GUESS=sparc-sun-sunos$SUN_REL
;;
@@ -908,7 +904,7 @@ EOF
fi
;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=`uname -p`
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
@@ -970,37 +966,11 @@ EOF
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
;;
- x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
- GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
- ;;
- *:[Mm]anagarm:*:*)
- GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
- ;;
*:Minix:*:*)
GUESS=$UNAME_MACHINE-unknown-minix
;;
aarch64:Linux:*:*)
- set_cc_for_build
- CPU=$UNAME_MACHINE
- LIBCABI=$LIBC
- if test "$CC_FOR_BUILD" != no_compiler_found; then
- ABI=64
- sed 's/^ //' << EOF > "$dummy.c"
- #ifdef __ARM_EABI__
- #ifdef __ARM_PCS_VFP
- ABI=eabihf
- #else
- ABI=eabi
- #endif
- #endif
-EOF
- cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
- eval "$cc_set_abi"
- case $ABI in
- eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
- esac
- fi
- GUESS=$CPU-unknown-linux-$LIBCABI
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
@@ -1066,16 +1036,7 @@ EOF
k1om:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
- kvx:Linux:*:*)
- GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
- ;;
- kvx:cos:*:*)
- GUESS=$UNAME_MACHINE-unknown-cos
- ;;
- kvx:mbr:*:*)
- GUESS=$UNAME_MACHINE-unknown-mbr
- ;;
- loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+ loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
m32r*:Linux:*:*)
@@ -1190,27 +1151,16 @@ EOF
;;
x86_64:Linux:*:*)
set_cc_for_build
- CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
- ABI=64
- sed 's/^ //' << EOF > "$dummy.c"
- #ifdef __i386__
- ABI=x86
- #else
- #ifdef __ILP32__
- ABI=x32
- #endif
- #endif
-EOF
- cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
- eval "$cc_set_abi"
- case $ABI in
- x86) CPU=i686 ;;
- x32) LIBCABI=${LIBC}x32 ;;
- esac
+ if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_X32 >/dev/null
+ then
+ LIBCABI=${LIBC}x32
+ fi
fi
- GUESS=$CPU-pc-linux-$LIBCABI
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
;;
xtensa*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
@@ -1230,7 +1180,7 @@ EOF
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
;;
i*86:OS/2:*:*)
- # If we were able to find 'uname', then EMX Unix compatibility
+ # If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
GUESS=$UNAME_MACHINE-pc-os2-emx
;;
@@ -1371,7 +1321,7 @@ EOF
GUESS=ns32k-sni-sysv
fi
;;
- PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
GUESS=i586-unisys-sysv4
;;
@@ -1417,11 +1367,8 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
GUESS=i586-pc-haiku
;;
- ppc:Haiku:*:*) # Haiku running on Apple PowerPC
- GUESS=powerpc-apple-haiku
- ;;
- *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
- GUESS=$UNAME_MACHINE-unknown-haiku
+ x86_64:Haiku:*:*)
+ GUESS=x86_64-unknown-haiku
;;
SX-4:SUPER-UX:*:*)
GUESS=sx4-nec-superux$UNAME_RELEASE
Index: simdzone/config.h.in
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/config.h.in,v
diff -u -p -r1.1.1.2 config.h.in
--- simdzone/config.h.in 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/config.h.in 18 Mar 2026 20:44:03 -0000
@@ -1,14 +1,14 @@
/* config.h.in. Generated from configure.ac by autoheader. */
-/* Define to 1 if you have the declaration of 'bswap16', and to 0 if you
+/* Define to 1 if you have the declaration of `bswap16', and to 0 if you
don't. */
#undef HAVE_DECL_BSWAP16
-/* Define to 1 if you have the declaration of 'bswap32', and to 0 if you
+/* Define to 1 if you have the declaration of `bswap32', and to 0 if you
don't. */
#undef HAVE_DECL_BSWAP32
-/* Define to 1 if you have the declaration of 'bswap64', and to 0 if you
+/* Define to 1 if you have the declaration of `bswap64', and to 0 if you
don't. */
#undef HAVE_DECL_BSWAP64
@@ -21,7 +21,7 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* Define to 1 if you have the 'realpath' function. */
+/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
/* Define to 1 if you have the <stdint.h> header file. */
@@ -72,7 +72,7 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* Define to 1 if all of the C89 standard headers exist (not just the ones
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
Index: simdzone/config.sub
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/config.sub,v
diff -u -p -r1.1.1.2 config.sub
--- simdzone/config.sub 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/config.sub 18 Mar 2026 20:44:03 -0000
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2023 Free Software Foundation, Inc.
+# Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2023-09-19'
+timestamp='2022-01-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -76,13 +76,13 @@ Report bugs and patches to <config-patch
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
-Try '$me --help' for more information."
+Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -130,7 +130,7 @@ IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
*-*-*-*-*)
- echo "Invalid configuration '$1': more than four components" >&2
+ echo Invalid configuration \`"$1"\': more than four components >&2
exit 1
;;
*-*-*-*)
@@ -145,8 +145,7 @@ case $1 in
nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
- | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \
- | windows-* )
+ | storm-chaos* | os2-emx* | rtmk-nova*)
basic_machine=$field1
basic_os=$maybe_os
;;
@@ -944,7 +943,7 @@ $basic_machine
EOF
IFS=$saved_IFS
;;
- # We use 'pc' rather than 'unknown'
+ # We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
@@ -1076,7 +1075,7 @@ case $cpu-$vendor in
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
cpu=i586
;;
- pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
cpu=i686
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
@@ -1181,7 +1180,7 @@ case $cpu-$vendor in
case $cpu in
1750a | 580 \
| a29k \
- | aarch64 | aarch64_be | aarch64c | arm64ec \
+ | aarch64 | aarch64_be \
| abacus \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
@@ -1200,23 +1199,45 @@ case $cpu-$vendor in
| d10v | d30v | dlx | dsp16xx \
| e2k | elxsi | epiphany \
| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
- | javascript \
| h8300 | h8500 \
| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i*86 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
- | kvx \
| le32 | le64 \
| lm32 \
- | loongarch32 | loongarch64 \
+ | loongarch32 | loongarch64 | loongarchx32 \
| m32c | m32r | m32rle \
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
| m88110 | m88k | maxq | mb | mcore | mep | metag \
| microblaze | microblazeel \
- | mips* \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64eb | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r3 | mipsisa32r3el \
+ | mipsisa32r5 | mipsisa32r5el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r3 | mipsisa64r3el \
+ | mipsisa64r5 | mipsisa64r5el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
| mmix \
| mn10200 | mn10300 \
| moxie \
@@ -1264,7 +1285,7 @@ case $cpu-$vendor in
;;
*)
- echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
+ echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
exit 1
;;
esac
@@ -1285,12 +1306,11 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if test x"$basic_os" != x
+if test x$basic_os != x
then
# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
# set os.
-obj=
case $basic_os in
gnu/linux*)
kernel=linux
@@ -1321,10 +1341,6 @@ EOF
kernel=linux
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
;;
- managarm*)
- kernel=managarm
- os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
- ;;
*)
kernel=
os=$basic_os
@@ -1490,16 +1506,10 @@ case $os in
os=eabi
;;
*)
- os=
- obj=elf
+ os=elf
;;
esac
;;
- aout* | coff* | elf* | pe*)
- # These are machine code file formats, not OSes
- obj=$os
- os=
- ;;
*)
# No normalization, but not necessarily accepted, that comes below.
;;
@@ -1518,15 +1528,12 @@ else
# system, and we'll never get to this point.
kernel=
-obj=
case $cpu-$vendor in
score-*)
- os=
- obj=elf
+ os=elf
;;
spu-*)
- os=
- obj=elf
+ os=elf
;;
*-acorn)
os=riscix1.2
@@ -1536,35 +1543,28 @@ case $cpu-$vendor in
os=gnu
;;
arm*-semi)
- os=
- obj=aout
+ os=aout
;;
c4x-* | tic4x-*)
- os=
- obj=coff
+ os=coff
;;
c8051-*)
- os=
- obj=elf
+ os=elf
;;
clipper-intergraph)
os=clix
;;
hexagon-*)
- os=
- obj=elf
+ os=elf
;;
tic54x-*)
- os=
- obj=coff
+ os=coff
;;
tic55x-*)
- os=
- obj=coff
+ os=coff
;;
tic6x-*)
- os=
- obj=coff
+ os=coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1586,24 +1586,19 @@ case $cpu-$vendor in
os=sunos3
;;
m68*-cisco)
- os=
- obj=aout
+ os=aout
;;
mep-*)
- os=
- obj=elf
+ os=elf
;;
mips*-cisco)
- os=
- obj=elf
+ os=elf
;;
mips*-*)
- os=
- obj=elf
+ os=elf
;;
or32-*)
- os=
- obj=coff
+ os=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=sysv3
@@ -1612,8 +1607,7 @@ case $cpu-$vendor in
os=sunos4.1.1
;;
pru-*)
- os=
- obj=elf
+ os=elf
;;
*-be)
os=beos
@@ -1694,12 +1688,10 @@ case $cpu-$vendor in
os=uxpv
;;
*-rom68k)
- os=
- obj=coff
+ os=coff
;;
*-*bug)
- os=
- obj=coff
+ os=coff
;;
*-apple)
os=macos
@@ -1717,8 +1709,7 @@ esac
fi
-# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
-
+# Now, validate our (potentially fixed-up) OS.
case $os in
# Sometimes we do "kernel-libc", so those need to count as OSes.
musl* | newlib* | relibc* | uclibc*)
@@ -1729,9 +1720,6 @@ case $os in
# VxWorks passes extra cpu info in the 4th filed.
simlinux | simwindows | spe)
;;
- # See `case $cpu-$os` validation below
- ghcjs)
- ;;
# Now accept the basic system types.
# The portable systems comes first.
# Each alternative MUST end in a * to match a version number.
@@ -1740,7 +1728,7 @@ case $os in
| hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
| sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
| hiux* | abug | nacl* | netware* | windows* \
- | os9* | macos* | osx* | ios* | tvos* | watchos* \
+ | os9* | macos* | osx* | ios* \
| mpw* | magic* | mmixware* | mon960* | lnews* \
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
| aos* | aros* | cloudabi* | sortix* | twizzler* \
@@ -1749,11 +1737,11 @@ case $os in
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
| bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
- | bosx* | nextstep* | cxux* | oabi* \
- | ptx* | ecoff* | winnt* | domain* | vsta* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
| udi* | lites* | ieee* | go32* | aux* | hcos* \
| chorusrdb* | cegcc* | glidix* | serenity* \
- | cygwin* | msys* | moss* | proelf* | rtems* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
| midipix* | mingw32* | mingw64* | mint* \
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
| interix* | uwin* | mks* | rhapsody* | darwin* \
@@ -1766,7 +1754,7 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* | cos* | mbr* )
+ | fiwix* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1774,99 +1762,41 @@ case $os in
;;
none)
;;
- kernel* | msvc* )
- # Restricted further below
- ;;
- '')
- if test x"$obj" = x
- then
- echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
- fi
- ;;
- *)
- echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
- exit 1
- ;;
-esac
-
-case $obj in
- aout* | coff* | elf* | pe*)
- ;;
- '')
- # empty is fine
- ;;
*)
- echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
- exit 1
- ;;
-esac
-
-# Here we handle the constraint that a (synthetic) cpu and os are
-# valid only in combination with each other and nowhere else.
-case $cpu-$os in
- # The "javascript-unknown-ghcjs" triple is used by GHC; we
- # accept it here in order to tolerate that, but reject any
- # variations.
- javascript-ghcjs)
- ;;
- javascript-* | *-ghcjs)
- echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
+ echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
exit 1
;;
esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
-case $kernel-$os-$obj in
- linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
- | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
- ;;
- uclinux-uclibc*- )
- ;;
- managarm-mlibc*- | managarm-kernel*- )
+case $kernel-$os in
+ linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+ | linux-musl* | linux-relibc* | linux-uclibc* )
;;
- windows*-msvc*-)
+ uclinux-uclibc* )
;;
- -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
+ -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
- echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
- exit 1
- ;;
- -kernel*- )
- echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
- exit 1
- ;;
- *-kernel*- )
- echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
+ echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
exit 1
;;
- *-msvc*- )
- echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
- exit 1
- ;;
- kfreebsd*-gnu*- | kopensolaris*-gnu*-)
+ kfreebsd*-gnu* | kopensolaris*-gnu*)
;;
- vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
+ vxworks-simlinux | vxworks-simwindows | vxworks-spe)
;;
- nto-qnx*-)
- ;;
- os2-emx-)
+ nto-qnx*)
;;
- *-eabi*- | *-gnueabi*-)
+ os2-emx)
;;
- none--*)
- # None (no kernel, i.e. freestanding / bare metal),
- # can be paired with an machine code file format
+ *-eabi* | *-gnueabi*)
;;
- -*-)
+ -*)
# Blank kernel with real OS is always fine.
;;
- --*)
- # Blank kernel and OS with real machine code file format is always fine.
- ;;
- *-*-*)
- echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
+ *-*)
+ echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
exit 1
;;
esac
@@ -1949,7 +1879,7 @@ case $vendor in
;;
esac
-echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
exit
# Local variables:
Index: simdzone/configure
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/configure,v
diff -u -p -r1.1.1.2 configure
--- simdzone/configure 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/configure 18 Mar 2026 20:44:03 -0000
@@ -1,11 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for simdzone 0.2.3.
+# Generated by GNU Autoconf 2.71 for simdzone 0.2.4.
#
# Report bugs to <https://github.com/NLnetLabs/simdzone/issues>.
#
#
-# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
# Inc.
#
#
@@ -17,6 +17,7 @@
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
then :
emulate sh
@@ -25,13 +26,12 @@ then :
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
-else case e in #(
- e) case `(set -o) 2>/dev/null` in #(
+else $as_nop
+ case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
-esac ;;
esac
fi
@@ -103,7 +103,7 @@ IFS=$as_save_IFS
;;
esac
-# We did not find ourselves, most probably we were run as 'sh COMMAND'
+# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
@@ -133,14 +133,15 @@ case $- in # ((((
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed 'exec'.
+# out after a failed `exec'.
printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi
# We don't want this to propagate to other subprocesses.
{ _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+ as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
then :
emulate sh
NULLCMD=:
@@ -148,13 +149,12 @@ then :
# is contrary to our usage. Disable this feature.
alias -g '\${1+\"\$@\"}'='\"\$@\"'
setopt NO_GLOB_SUBST
-else case e in #(
- e) case \`(set -o) 2>/dev/null\` in #(
+else \$as_nop
+ case \`(set -o) 2>/dev/null\` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
-esac ;;
esac
fi
"
@@ -172,9 +172,8 @@ as_fn_ret_failure && { exitcode=1; echo
if ( set x; as_fn_ret_success y && test x = \"\$1\" )
then :
-else case e in #(
- e) exitcode=1; echo positional parameters were not saved. ;;
-esac
+else \$as_nop
+ exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
blah=\$(echo \$(echo blah))
@@ -187,15 +186,14 @@ test -x / || exit 1"
if (eval "$as_required") 2>/dev/null
then :
as_have_required=yes
-else case e in #(
- e) as_have_required=no ;;
-esac
+else $as_nop
+ as_have_required=no
fi
if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
then :
-else case e in #(
- e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+else $as_nop
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
@@ -228,13 +226,12 @@ IFS=$as_save_IFS
if $as_found
then :
-else case e in #(
- e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+else $as_nop
+ if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
then :
CONFIG_SHELL=$SHELL as_have_required=yes
-fi ;;
-esac
+fi
fi
@@ -256,7 +253,7 @@ case $- in # ((((
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed 'exec'.
+# out after a failed `exec'.
printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi
@@ -276,8 +273,7 @@ $0: message. Then install a modern shell
$0: the script under such a shell if you do have one."
fi
exit 1
-fi ;;
-esac
+fi
fi
fi
SHELL=${CONFIG_SHELL-/bin/sh}
@@ -316,6 +312,14 @@ as_fn_exit ()
as_fn_set_status $1
exit $1
} # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+ return $?
+}
+as_nop=as_fn_nop
# as_fn_mkdir_p
# -------------
@@ -384,12 +388,11 @@ then :
{
eval $1+=\$2
}'
-else case e in #(
- e) as_fn_append ()
+else $as_nop
+ as_fn_append ()
{
eval $1=\$$1\$2
- } ;;
-esac
+ }
fi # as_fn_append
# as_fn_arith ARG...
@@ -403,14 +406,21 @@ then :
{
as_val=$(( $* ))
}'
-else case e in #(
- e) as_fn_arith ()
+else $as_nop
+ as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
- } ;;
-esac
+ }
fi # as_fn_arith
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+ return $?
+}
+as_nop=as_fn_nop
# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
@@ -484,8 +494,6 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
/[$]LINENO/=
' <$as_myself |
sed '
- t clear
- :clear
s/[$]LINENO.*/&-/
t lineno
b
@@ -534,6 +542,7 @@ esac
as_echo='printf %s\n'
as_echo_n='printf %s'
+
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
@@ -545,9 +554,9 @@ if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
- # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
- # In both cases, we have to default to 'cp -pR'.
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
@@ -572,12 +581,10 @@ as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
-as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
-as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
-as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
-as_tr_sh="eval sed '$as_sed_sh'" # deprecated
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
test -n "$DJDIR" || exec 7<&0 </dev/null
@@ -603,8 +610,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='simdzone'
PACKAGE_TARNAME='simdzone'
-PACKAGE_VERSION='0.2.3'
-PACKAGE_STRING='simdzone 0.2.3'
+PACKAGE_VERSION='0.2.4'
+PACKAGE_STRING='simdzone 0.2.4'
PACKAGE_BUGREPORT='https://github.com/NLnetLabs/simdzone/issues'
PACKAGE_URL=''
@@ -827,7 +834,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: '$ac_useropt'"
+ as_fn_error $? "invalid feature name: \`$ac_useropt'"
ac_useropt_orig=$ac_useropt
ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -853,7 +860,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: '$ac_useropt'"
+ as_fn_error $? "invalid feature name: \`$ac_useropt'"
ac_useropt_orig=$ac_useropt
ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1066,7 +1073,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: '$ac_useropt'"
+ as_fn_error $? "invalid package name: \`$ac_useropt'"
ac_useropt_orig=$ac_useropt
ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1082,7 +1089,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: '$ac_useropt'"
+ as_fn_error $? "invalid package name: \`$ac_useropt'"
ac_useropt_orig=$ac_useropt
ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1112,8 +1119,8 @@ do
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) as_fn_error $? "unrecognized option: '$ac_option'
-Try '$0 --help' for more information"
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
;;
*=*)
@@ -1121,7 +1128,7 @@ Try '$0 --help' for more information"
# Reject names that are not valid shell variable names.
case $ac_envvar in #(
'' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error $? "invalid variable name: '$ac_envvar'" ;;
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
esac
eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
@@ -1171,7 +1178,7 @@ do
as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done
-# There might be people who depend on the old broken behavior: '$host'
+# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
@@ -1239,7 +1246,7 @@ if test ! -r "$srcdir/$ac_unique_file";
test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
-ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work"
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
pwd)`
@@ -1267,7 +1274,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-'configure' configures simdzone 0.2.3 to adapt to many kinds of systems.
+\`configure' configures simdzone 0.2.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1281,11 +1288,11 @@ Configuration:
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
- -q, --quiet, --silent do not print 'checking ...' messages
+ -q, --quiet, --silent do not print \`checking ...' messages
--cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for '--cache-file=config.cache'
+ -C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or '..']
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
@@ -1293,10 +1300,10 @@ Installation directories:
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
-By default, 'make install' will install all the files in
-'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than '$ac_default_prefix' using '--prefix',
-for instance '--prefix=\$HOME'.
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
For better control, use the options below.
@@ -1334,7 +1341,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of simdzone 0.2.3:";;
+ short | recursive ) echo "Configuration of simdzone 0.2.4:";;
esac
cat <<\_ACEOF
@@ -1356,7 +1363,7 @@ Some influential environment variables:
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
-Use these variables to override the choices made by 'configure' or to help
+Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to <https://github.com/NLnetLabs/simdzone/issues>.
@@ -1423,10 +1430,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-simdzone configure 0.2.3
-generated by GNU Autoconf 2.72
+simdzone configure 0.2.4
+generated by GNU Autoconf 2.71
-Copyright (C) 2023 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1465,12 +1472,11 @@ printf "%s\n" "$ac_try_echo"; } >&5
} && test -s conftest.$ac_objext
then :
ac_retval=0
-else case e in #(
- e) printf "%s\n" "$as_me: failed program was:" >&5
+else $as_nop
+ printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- ac_retval=1 ;;
-esac
+ ac_retval=1
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
@@ -1508,12 +1514,11 @@ printf "%s\n" "$ac_try_echo"; } >&5
}
then :
ac_retval=0
-else case e in #(
- e) printf "%s\n" "$as_me: failed program was:" >&5
+else $as_nop
+ printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- ac_retval=1 ;;
-esac
+ ac_retval=1
fi
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
@@ -1537,8 +1542,8 @@ printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
#include <$2>
@@ -1546,12 +1551,10 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
eval "$3=yes"
-else case e in #(
- e) eval "$3=no" ;;
-esac
+else $as_nop
+ eval "$3=no"
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
-esac
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
@@ -1573,8 +1576,8 @@ printf %s "checking whether $as_decl_nam
if eval test \${$3+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+else $as_nop
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
eval ac_save_FLAGS=\$$6
as_fn_append $6 " $5"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1598,14 +1601,12 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
eval "$3=yes"
-else case e in #(
- e) eval "$3=no" ;;
-esac
+else $as_nop
+ eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
eval $6=\$ac_save_FLAGS
- ;;
-esac
+
fi
eval ac_res=\$$3
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
@@ -1625,15 +1626,15 @@ printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $2 innocuous_$2
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (void); below. */
+ which can conflict with char $2 (); below. */
#include <limits.h>
#undef $2
@@ -1644,7 +1645,7 @@ else case e in #(
#ifdef __cplusplus
extern "C"
#endif
-char $2 (void);
+char $2 ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
@@ -1663,13 +1664,11 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"
then :
eval "$3=yes"
-else case e in #(
- e) eval "$3=no" ;;
-esac
+else $as_nop
+ eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext ;;
-esac
+ conftest$ac_exeext conftest.$ac_ext
fi
eval ac_res=\$$3
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
@@ -1701,8 +1700,8 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by simdzone $as_me 0.2.3, which was
-generated by GNU Autoconf 2.72. Invocation command line was
+It was created by simdzone $as_me 0.2.4, which was
+generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -1948,10 +1947,10 @@ esac
printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file" \
- || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
-See 'config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
done
@@ -1987,7 +1986,9 @@ struct stat;
/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */
struct buf { int x; };
struct buf * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (char **p, int i)
+static char *e (p, i)
+ char **p;
+ int i;
{
return p[i];
}
@@ -2001,21 +2002,6 @@ static char *f (char * (*g) (char **, in
return s;
}
-/* C89 style stringification. */
-#define noexpand_stringify(a) #a
-const char *stringified = noexpand_stringify(arbitrary+token=sequence);
-
-/* C89 style token pasting. Exercises some of the corner cases that
- e.g. old MSVC gets wrong, but not very hard. */
-#define noexpand_concat(a,b) a##b
-#define expand_concat(a,b) noexpand_concat(a,b)
-extern int vA;
-extern int vbee;
-#define aye A
-#define bee B
-int *pvA = &expand_concat(v,aye);
-int *pvbee = &noexpand_concat(v,bee);
-
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
function prototypes and stuff, but not \xHH hex character constants.
These do not provoke an error unfortunately, instead are silently treated
@@ -2043,19 +2029,16 @@ ok |= (argc == 0 || f (e, argv, 0) != ar
# Test code for whether the C compiler supports C99 (global declarations)
ac_c_conftest_c99_globals='
-/* Does the compiler advertise C99 conformance? */
+// Does the compiler advertise C99 conformance?
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
# error "Compiler does not advertise C99 conformance"
#endif
-// See if C++-style comments work.
-
#include <stdbool.h>
extern int puts (const char *);
extern int printf (const char *, ...);
extern int dprintf (int, const char *, ...);
extern void *malloc (size_t);
-extern void free (void *);
// Check varargs macros. These examples are taken from C99 6.10.3.5.
// dprintf is used instead of fprintf to avoid needing to declare
@@ -2105,6 +2088,7 @@ typedef const char *ccp;
static inline int
test_restrict (ccp restrict text)
{
+ // See if C++-style comments work.
// Iterate through items via the restricted pointer.
// Also check for declarations in for loops.
for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
@@ -2170,8 +2154,6 @@ ac_c_conftest_c99_main='
ia->datasize = 10;
for (int i = 0; i < ia->datasize; ++i)
ia->data[i] = i * 1.234;
- // Work around memory leak warnings.
- free (ia);
// Check named initializers.
struct named_init ni = {
@@ -2193,7 +2175,7 @@ ac_c_conftest_c99_main='
# Test code for whether the C compiler supports C11 (global declarations)
ac_c_conftest_c11_globals='
-/* Does the compiler advertise C11 conformance? */
+// Does the compiler advertise C11 conformance?
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
# error "Compiler does not advertise C11 conformance"
#endif
@@ -2385,9 +2367,8 @@ IFS=$as_save_IFS
if $as_found
then :
-else case e in #(
- e) as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 ;;
-esac
+else $as_nop
+ as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
fi
@@ -2415,12 +2396,12 @@ for ac_var in $ac_precious_vars; do
eval ac_new_val=\$ac_env_${ac_var}_value
case $ac_old_set,$ac_new_set in
set,)
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5
-printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
ac_cache_corrupted=: ;;
,set)
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5
-printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
ac_cache_corrupted=: ;;
,);;
*)
@@ -2429,18 +2410,18 @@ printf "%s\n" "$as_me: error: '$ac_var'
ac_old_val_w=`echo x $ac_old_val`
ac_new_val_w=`echo x $ac_new_val`
if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5
-printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
ac_cache_corrupted=:
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5
-printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
eval $ac_var=\$ac_old_val
fi
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5
-printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;}
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5
-printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;}
fi;;
esac
# Pass precious variables to config.status.
@@ -2456,11 +2437,11 @@ printf "%s\n" "$as_me: current value:
fi
done
if $ac_cache_corrupted; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file'
+ as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
and start over" "$LINENO" 5
fi
## -------------------- ##
@@ -2773,8 +2754,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$CC"; then
+else $as_nop
+ if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2796,8 +2777,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
@@ -2819,8 +2799,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_ac_ct_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$ac_ct_CC"; then
+else $as_nop
+ if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2842,8 +2822,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
@@ -2878,8 +2857,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$CC"; then
+else $as_nop
+ if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2901,8 +2880,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
@@ -2924,8 +2902,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$CC"; then
+else $as_nop
+ if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
ac_prog_rejected=no
@@ -2964,8 +2942,7 @@ if test $ac_prog_rejected = yes; then
ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
fi
fi
-fi ;;
-esac
+fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
@@ -2989,8 +2966,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$CC"; then
+else $as_nop
+ if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3012,8 +2989,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
@@ -3039,8 +3015,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_ac_ct_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$ac_ct_CC"; then
+else $as_nop
+ if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3062,8 +3038,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
@@ -3101,8 +3076,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$CC"; then
+else $as_nop
+ if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3124,8 +3099,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
@@ -3147,8 +3121,8 @@ printf %s "checking for $ac_word... " >&
if test ${ac_cv_prog_ac_ct_CC+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test -n "$ac_ct_CC"; then
+else $as_nop
+ if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3170,8 +3144,7 @@ done
done
IFS=$as_save_IFS
-fi ;;
-esac
+fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
@@ -3200,10 +3173,10 @@ fi
fi
-test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
-See 'config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -3275,8 +3248,8 @@ printf "%s\n" "$ac_try_echo"; } >&5
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'.
-# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no'
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile. We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
@@ -3296,7 +3269,7 @@ do
ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
fi
# We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an '-o'
+ # safe: cross compilers may not add the suffix if given an `-o'
# argument, so we may need to know it at that point already.
# Even if this section looks crufty: it has the advantage of
# actually working.
@@ -3307,9 +3280,8 @@ do
done
test "$ac_cv_exeext" = no && ac_cv_exeext=
-else case e in #(
- e) ac_file='' ;;
-esac
+else $as_nop
+ ac_file=''
fi
if test -z "$ac_file"
then :
@@ -3318,14 +3290,13 @@ printf "%s\n" "no" >&6; }
printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
-See 'config.log' for more details" "$LINENO" 5; }
-else case e in #(
- e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; } ;;
-esac
+See \`config.log' for more details" "$LINENO" 5; }
+else $as_nop
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
printf %s "checking for C compiler default output file name... " >&6; }
@@ -3349,10 +3320,10 @@ printf "%s\n" "$ac_try_echo"; } >&5
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
then :
- # If both 'conftest.exe' and 'conftest' are 'present' (well, observable)
-# catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will
-# work properly (i.e., refer to 'conftest.exe'), while it won't with
-# 'rm'.
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
test -f "$ac_file" || continue
case $ac_file in
@@ -3362,12 +3333,11 @@ for ac_file in conftest.exe conftest con
* ) break;;
esac
done
-else case e in #(
- e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+else $as_nop
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See 'config.log' for more details" "$LINENO" 5; } ;;
-esac
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -3383,8 +3353,6 @@ int
main (void)
{
FILE *f = fopen ("conftest.out", "w");
- if (!f)
- return 1;
return ferror (f) || fclose (f) != 0;
;
@@ -3424,27 +3392,26 @@ printf "%s\n" "$ac_try_echo"; } >&5
if test "$cross_compiling" = maybe; then
cross_compiling=yes
else
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot run C compiled programs.
-If you meant to cross compile, use '--host'.
-See 'config.log' for more details" "$LINENO" 5; }
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
printf "%s\n" "$cross_compiling" >&6; }
-rm -f conftest.$ac_ext conftest$ac_cv_exeext \
- conftest.o conftest.obj conftest.out
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
printf %s "checking for suffix of object files... " >&6; }
if test ${ac_cv_objext+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -3476,18 +3443,16 @@ then :
break;;
esac
done
-else case e in #(
- e) printf "%s\n" "$as_me: failed program was:" >&5
+else $as_nop
+ printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
-See 'config.log' for more details" "$LINENO" 5; } ;;
-esac
+See \`config.log' for more details" "$LINENO" 5; }
fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext ;;
-esac
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
printf "%s\n" "$ac_cv_objext" >&6; }
@@ -3498,8 +3463,8 @@ printf %s "checking whether the compiler
if test ${ac_cv_c_compiler_gnu+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -3516,14 +3481,12 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_compiler_gnu=yes
-else case e in #(
- e) ac_compiler_gnu=no ;;
-esac
+else $as_nop
+ ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
- ;;
-esac
+
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
@@ -3541,8 +3504,8 @@ printf %s "checking whether $CC accepts
if test ${ac_cv_prog_cc_g+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) ac_save_c_werror_flag=$ac_c_werror_flag
+else $as_nop
+ ac_save_c_werror_flag=$ac_c_werror_flag
ac_c_werror_flag=yes
ac_cv_prog_cc_g=no
CFLAGS="-g"
@@ -3560,8 +3523,8 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_prog_cc_g=yes
-else case e in #(
- e) CFLAGS=""
+else $as_nop
+ CFLAGS=""
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -3576,8 +3539,8 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
-else case e in #(
- e) ac_c_werror_flag=$ac_save_c_werror_flag
+else $as_nop
+ ac_c_werror_flag=$ac_save_c_werror_flag
CFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -3594,15 +3557,12 @@ if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_prog_cc_g=yes
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
-esac
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
-esac
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag ;;
-esac
+ ac_c_werror_flag=$ac_save_c_werror_flag
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
@@ -3629,8 +3589,8 @@ printf %s "checking for $CC option to en
if test ${ac_cv_prog_cc_c11+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) ac_cv_prog_cc_c11=no
+else $as_nop
+ ac_cv_prog_cc_c11=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -3647,28 +3607,25 @@ rm -f core conftest.err conftest.$ac_obj
test "x$ac_cv_prog_cc_c11" != "xno" && break
done
rm -f conftest.$ac_ext
-CC=$ac_save_CC ;;
-esac
+CC=$ac_save_CC
fi
if test "x$ac_cv_prog_cc_c11" = xno
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
-else case e in #(
- e) if test "x$ac_cv_prog_cc_c11" = x
+else $as_nop
+ if test "x$ac_cv_prog_cc_c11" = x
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
-else case e in #(
- e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+else $as_nop
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
- CC="$CC $ac_cv_prog_cc_c11" ;;
-esac
+ CC="$CC $ac_cv_prog_cc_c11"
fi
ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
- ac_prog_cc_stdc=c11 ;;
-esac
+ ac_prog_cc_stdc=c11
fi
fi
if test x$ac_prog_cc_stdc = xno
@@ -3678,8 +3635,8 @@ printf %s "checking for $CC option to en
if test ${ac_cv_prog_cc_c99+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) ac_cv_prog_cc_c99=no
+else $as_nop
+ ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -3696,28 +3653,25 @@ rm -f core conftest.err conftest.$ac_obj
test "x$ac_cv_prog_cc_c99" != "xno" && break
done
rm -f conftest.$ac_ext
-CC=$ac_save_CC ;;
-esac
+CC=$ac_save_CC
fi
if test "x$ac_cv_prog_cc_c99" = xno
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
-else case e in #(
- e) if test "x$ac_cv_prog_cc_c99" = x
+else $as_nop
+ if test "x$ac_cv_prog_cc_c99" = x
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
-else case e in #(
- e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+else $as_nop
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
- CC="$CC $ac_cv_prog_cc_c99" ;;
-esac
+ CC="$CC $ac_cv_prog_cc_c99"
fi
ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
- ac_prog_cc_stdc=c99 ;;
-esac
+ ac_prog_cc_stdc=c99
fi
fi
if test x$ac_prog_cc_stdc = xno
@@ -3727,8 +3681,8 @@ printf %s "checking for $CC option to en
if test ${ac_cv_prog_cc_c89+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) ac_cv_prog_cc_c89=no
+else $as_nop
+ ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -3745,28 +3699,25 @@ rm -f core conftest.err conftest.$ac_obj
test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
-CC=$ac_save_CC ;;
-esac
+CC=$ac_save_CC
fi
if test "x$ac_cv_prog_cc_c89" = xno
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
-else case e in #(
- e) if test "x$ac_cv_prog_cc_c89" = x
+else $as_nop
+ if test "x$ac_cv_prog_cc_c89" = x
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
-else case e in #(
- e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+else $as_nop
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
- CC="$CC $ac_cv_prog_cc_c89" ;;
-esac
+ CC="$CC $ac_cv_prog_cc_c89"
fi
ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
- ac_prog_cc_stdc=c89 ;;
-esac
+ ac_prog_cc_stdc=c89
fi
fi
@@ -3787,8 +3738,8 @@ cache=`echo g | sed 'y%.=/+-%___p_%'`
if eval test \${cv_prog_cc_flag_$cache+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e)
+else $as_nop
+
echo 'void f(void){}' >conftest.c
if test -z "`$CC $CPPFLAGS $CFLAGS -g -c conftest.c 2>&1`"; then
eval "cv_prog_cc_flag_$cache=yes"
@@ -3796,8 +3747,7 @@ else
eval "cv_prog_cc_flag_$cache=no"
fi
rm -f conftest conftest.o conftest.c
- ;;
-esac
+
fi
if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then
@@ -3820,8 +3770,8 @@ cache=`echo O2 | sed 'y%.=/+-%___p_%'`
if eval test \${cv_prog_cc_flag_$cache+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e)
+else $as_nop
+
echo 'void f(void){}' >conftest.c
if test -z "`$CC $CPPFLAGS $CFLAGS -O2 -c conftest.c 2>&1`"; then
eval "cv_prog_cc_flag_$cache=yes"
@@ -3829,8 +3779,7 @@ else
eval "cv_prog_cc_flag_$cache=no"
fi
rm -f conftest conftest.o conftest.c
- ;;
-esac
+
fi
if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then
@@ -3886,10 +3835,9 @@ printf "%s\n" "yes" >&6; }
fi
rm -f conftest conftest.c conftest.o
-else case e in #(
- e) LDFLAGS="$BAKLDFLAGS" ; CFLAGS="$BAKCFLAGS" ; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; } ;;
-esac
+else $as_nop
+ LDFLAGS="$BAKLDFLAGS" ; CFLAGS="$BAKCFLAGS" ; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
@@ -3947,8 +3895,8 @@ printf %s "checking for $CC options need
if test ${ac_cv_c_undeclared_builtin_options+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) ac_save_CFLAGS=$CFLAGS
+else $as_nop
+ ac_save_CFLAGS=$CFLAGS
ac_cv_c_undeclared_builtin_options='cannot detect'
for ac_arg in '' -fno-builtin; do
CFLAGS="$ac_save_CFLAGS $ac_arg"
@@ -3967,8 +3915,8 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
-else case e in #(
- e) # This test program should compile successfully.
+else $as_nop
+ # This test program should compile successfully.
# No library function is consistently available on
# freestanding implementations, so test against a dummy
# declaration. Include always-available headers on the
@@ -3996,29 +3944,26 @@ then :
if test x"$ac_arg" = x
then :
ac_cv_c_undeclared_builtin_options='none needed'
-else case e in #(
- e) ac_cv_c_undeclared_builtin_options=$ac_arg ;;
-esac
+else $as_nop
+ ac_cv_c_undeclared_builtin_options=$ac_arg
fi
break
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
-esac
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
done
CFLAGS=$ac_save_CFLAGS
- ;;
-esac
+
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5
printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; }
case $ac_cv_c_undeclared_builtin_options in #(
'cannot detect') :
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot make $CC report undeclared builtins
-See 'config.log' for more details" "$LINENO" 5; } ;; #(
+See \`config.log' for more details" "$LINENO" 5; } ;; #(
'none needed') :
ac_c_undeclared_builtin_options='' ;; #(
*) :
@@ -4038,9 +3983,8 @@ $ac_includes_default
if test "x$ac_cv_have_decl_bswap16" = xyes
then :
ac_have_decl=1
-else case e in #(
- e) ac_have_decl=0 ;;
-esac
+else $as_nop
+ ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_BSWAP16 $ac_have_decl" >>confdefs.h
ac_fn_check_decl "$LINENO" "bswap32" "ac_cv_have_decl_bswap32" "
@@ -4056,9 +4000,8 @@ $ac_includes_default
if test "x$ac_cv_have_decl_bswap32" = xyes
then :
ac_have_decl=1
-else case e in #(
- e) ac_have_decl=0 ;;
-esac
+else $as_nop
+ ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_BSWAP32 $ac_have_decl" >>confdefs.h
ac_fn_check_decl "$LINENO" "bswap64" "ac_cv_have_decl_bswap64" "
@@ -4074,9 +4017,8 @@ $ac_includes_default
if test "x$ac_cv_have_decl_bswap64" = xyes
then :
ac_have_decl=1
-else case e in #(
- e) ac_have_decl=0 ;;
-esac
+else $as_nop
+ ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_BSWAP64 $ac_have_decl" >>confdefs.h
@@ -4109,8 +4051,8 @@ printf %s "checking whether C compiler a
if test ${ax_cv_check_cflags___MMD+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e)
+else $as_nop
+
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -MMD"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4127,22 +4069,19 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags___MMD=yes
-else case e in #(
- e) ax_cv_check_cflags___MMD=no ;;
-esac
+else $as_nop
+ ax_cv_check_cflags___MMD=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
- CFLAGS=$ax_check_save_flags ;;
-esac
+ CFLAGS=$ax_check_save_flags
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___MMD" >&5
printf "%s\n" "$ax_cv_check_cflags___MMD" >&6; }
if test "x$ax_cv_check_cflags___MMD" = xyes
then :
DEPFLAGS="-MMD -MP"
-else case e in #(
- e) : ;;
-esac
+else $as_nop
+ :
fi
# Oracle Developer Studio (no -MP)
@@ -4151,8 +4090,8 @@ printf %s "checking whether C compiler a
if test ${ax_cv_check_cflags___xMMD+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e)
+else $as_nop
+
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -xMMD"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4169,22 +4108,19 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags___xMMD=yes
-else case e in #(
- e) ax_cv_check_cflags___xMMD=no ;;
-esac
+else $as_nop
+ ax_cv_check_cflags___xMMD=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
- CFLAGS=$ax_check_save_flags ;;
-esac
+ CFLAGS=$ax_check_save_flags
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___xMMD" >&5
printf "%s\n" "$ax_cv_check_cflags___xMMD" >&6; }
if test "x$ax_cv_check_cflags___xMMD" = xyes
then :
DEPFLAGS="-xMMD"
-else case e in #(
- e) : ;;
-esac
+else $as_nop
+ :
fi
@@ -4203,16 +4139,15 @@ printf %s "checking build system type...
if test ${ac_cv_build+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) ac_build_alias=$build_alias
+else $as_nop
+ ac_build_alias=$build_alias
test "x$ac_build_alias" = x &&
ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"`
test "x$ac_build_alias" = x &&
as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` ||
as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5
- ;;
-esac
+
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
printf "%s\n" "$ac_cv_build" >&6; }
@@ -4239,15 +4174,14 @@ printf %s "checking host system type...
if test ${ac_cv_host+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test "x$host_alias" = x; then
+else $as_nop
+ if test "x$host_alias" = x; then
ac_cv_host=$ac_cv_build
else
ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` ||
as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5
fi
- ;;
-esac
+
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
printf "%s\n" "$ac_cv_host" >&6; }
@@ -4274,15 +4208,14 @@ printf %s "checking target system type..
if test ${ac_cv_target+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e) if test "x$target_alias" = x; then
+else $as_nop
+ if test "x$target_alias" = x; then
ac_cv_target=$ac_cv_host
else
ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` ||
as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5
fi
- ;;
-esac
+
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
printf "%s\n" "$ac_cv_target" >&6; }
@@ -4336,8 +4269,8 @@ printf %s "checking whether C compiler a
if test ${ax_cv_check_cflags__Werror__march_westmere+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e)
+else $as_nop
+
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -Werror -march=westmere"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4354,22 +4287,19 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags__Werror__march_westmere=yes
-else case e in #(
- e) ax_cv_check_cflags__Werror__march_westmere=no ;;
-esac
+else $as_nop
+ ax_cv_check_cflags__Werror__march_westmere=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
- CFLAGS=$ax_check_save_flags ;;
-esac
+ CFLAGS=$ax_check_save_flags
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__march_westmere" >&5
printf "%s\n" "$ax_cv_check_cflags__Werror__march_westmere" >&6; }
if test "x$ax_cv_check_cflags__Werror__march_westmere" = xyes
then :
:
-else case e in #(
- e) : ;;
-esac
+else $as_nop
+ :
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -march=haswell" >&5
@@ -4377,8 +4307,8 @@ printf %s "checking whether C compiler a
if test ${ax_cv_check_cflags__Werror__march_haswell+y}
then :
printf %s "(cached) " >&6
-else case e in #(
- e)
+else $as_nop
+
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -Werror -march=haswell"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4395,22 +4325,19 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags__Werror__march_haswell=yes
-else case e in #(
- e) ax_cv_check_cflags__Werror__march_haswell=no ;;
-esac
+else $as_nop
+ ax_cv_check_cflags__Werror__march_haswell=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
- CFLAGS=$ax_check_save_flags ;;
-esac
+ CFLAGS=$ax_check_save_flags
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror__march_haswell" >&5
printf "%s\n" "$ax_cv_check_cflags__Werror__march_haswell" >&6; }
if test "x$ax_cv_check_cflags__Werror__march_haswell" = xyes
then :
:
-else case e in #(
- e) : ;;
-esac
+else $as_nop
+ :
fi
@@ -4449,12 +4376,11 @@ printf "%s\n" "#define HAVE_WESTMERE 1"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
-else case e in #(
- e)
+else $as_nop
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
- ;;
-esac
+
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="$BAKCFLAGS"
@@ -4495,12 +4421,11 @@ printf "%s\n" "#define HAVE_HASWELL 1" >
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
-else case e in #(
- e)
+else $as_nop
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
- ;;
-esac
+
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="$BAKCFLAGS"
@@ -4515,9 +4440,8 @@ if test "x$ac_cv_func_realpath" = xyes
then :
printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h
-else case e in #(
- e) as_fn_error $? "realpath is not available" "$LINENO" 5 ;;
-esac
+else $as_nop
+ as_fn_error $? "realpath is not available" "$LINENO" 5
fi
done
@@ -4538,8 +4462,8 @@ cat >confcache <<\_ACEOF
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
-# 'ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* 'ac_cv_foo' will be assigned the
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.
_ACEOF
@@ -4569,14 +4493,14 @@ printf "%s\n" "$as_me: WARNING: cache va
(set) 2>&1 |
case $as_nl`(ac_space=' '; set) 2>&1` in #(
*${as_nl}ac_space=\ *)
- # 'set' does not quote correctly, so add quotes: double-quote
+ # `set' does not quote correctly, so add quotes: double-quote
# substitution turns \\\\ into \\, and sed turns \\ into \.
sed -n \
"s/'/'\\\\''/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
;; #(
*)
- # 'set' quotes correctly as required by POSIX, so do not add quotes.
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
esac |
@@ -4666,6 +4590,7 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_wri
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
then :
emulate sh
@@ -4674,13 +4599,12 @@ then :
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
-else case e in #(
- e) case `(set -o) 2>/dev/null` in #(
+else $as_nop
+ case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
-esac ;;
esac
fi
@@ -4752,7 +4676,7 @@ IFS=$as_save_IFS
;;
esac
-# We did not find ourselves, most probably we were run as 'sh COMMAND'
+# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
@@ -4781,6 +4705,7 @@ as_fn_error ()
} # as_fn_error
+
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
@@ -4820,12 +4745,11 @@ then :
{
eval $1+=\$2
}'
-else case e in #(
- e) as_fn_append ()
+else $as_nop
+ as_fn_append ()
{
eval $1=\$$1\$2
- } ;;
-esac
+ }
fi # as_fn_append
# as_fn_arith ARG...
@@ -4839,12 +4763,11 @@ then :
{
as_val=$(( $* ))
}'
-else case e in #(
- e) as_fn_arith ()
+else $as_nop
+ as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
- } ;;
-esac
+ }
fi # as_fn_arith
@@ -4927,9 +4850,9 @@ if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
- # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
- # In both cases, we have to default to 'cp -pR'.
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
@@ -5010,12 +4933,10 @@ as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
-as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
-as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
-as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
-as_tr_sh="eval sed '$as_sed_sh'" # deprecated
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
exec 6>&1
@@ -5030,8 +4951,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by simdzone $as_me 0.2.3, which was
-generated by GNU Autoconf 2.72. Invocation command line was
+This file was extended by simdzone $as_me 0.2.4, which was
+generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -5062,7 +4983,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
-'$as_me' instantiates files and other configuration actions
+\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration. Unless the files
and actions are specified as TAGs, all are instantiated by default.
@@ -5094,11 +5015,11 @@ ac_cs_config_escaped=`printf "%s\n" "$ac
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-simdzone config.status 0.2.3
-configured by $0, generated by GNU Autoconf 2.72,
+simdzone config.status 0.2.4
+configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2023 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -5157,8 +5078,8 @@ do
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
- as_fn_error $? "ambiguous option: '$1'
-Try '$0 --help' for more information.";;
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
--help | --hel | -h )
printf "%s\n" "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
@@ -5166,8 +5087,8 @@ Try '$0 --help' for more information.";;
ac_cs_silent=: ;;
# This is an error.
- -*) as_fn_error $? "unrecognized option: '$1'
-Try '$0 --help' for more information." ;;
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
ac_need_defaults=false ;;
@@ -5218,7 +5139,7 @@ do
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -5237,7 +5158,7 @@ fi
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to '$tmp'.
+# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
tmp= ac_tmp=
@@ -5261,7 +5182,7 @@ ac_tmp=$tmp
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with './config.status config.h'.
+# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then
@@ -5419,13 +5340,13 @@ fi # test -n "$CONFIG_FILES"
# Set up the scripts for CONFIG_HEADERS section.
# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with './config.status Makefile'.
+# This happens for instance with `./config.status Makefile'.
if test -n "$CONFIG_HEADERS"; then
cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
BEGIN {
_ACEOF
-# Transform confdefs.h into an awk script 'defines.awk', embedded as
+# Transform confdefs.h into an awk script `defines.awk', embedded as
# here-document in config.status, that substitutes the proper values into
# config.h.in to produce config.h.
@@ -5535,7 +5456,7 @@ do
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -5557,19 +5478,19 @@ do
-) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain ':'.
+ # because $ac_f cannot contain `:'.
test -f "$ac_f" ||
case $ac_f in
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
done
- # Let's still pretend it is 'configure' which instantiates (i.e., don't
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
configure_input='Generated from '`
@@ -5693,7 +5614,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_writ
esac
_ACEOF
-# Neutralize VPATH when '$srcdir' = '.'.
+# Neutralize VPATH when `$srcdir' = `.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
@@ -5722,9 +5643,9 @@ test -z "$ac_datarootdir_hack$ac_dataroo
{ ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
"$ac_tmp/out"`; test -z "$ac_out"; } &&
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir'
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&5
-printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir'
+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&2;}
rm -f "$ac_tmp/stdin"
Index: simdzone/configure.ac
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/configure.ac,v
diff -u -p -r1.1.1.2 configure.ac
--- simdzone/configure.ac 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/configure.ac 18 Mar 2026 20:44:03 -0000
@@ -10,7 +10,7 @@
# platform not supported by NSD here is undesirable. Builds for standalone use
# or development/testing are required to use CMake.
-AC_INIT([simdzone],[0.2.3],[https://github.com/NLnetLabs/simdzone/issues])
+AC_INIT([simdzone],[0.2.4],[https://github.com/NLnetLabs/simdzone/issues])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
Index: simdzone/src/generic/types.h
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/generic/types.h,v
diff -u -p -r1.1.1.2 types.h
--- simdzone/src/generic/types.h 6 Sep 2025 17:38:34 -0000 1.1.1.2
+++ simdzone/src/generic/types.h 18 Mar 2026 20:44:03 -0000
@@ -1385,8 +1385,8 @@ static int32_t check_ds_rr(
32, // 2: SHA-256
32, // 3: GOST R 34.11-94
48, // 4: SHA-384
- 48, // 5: GOST R 34.10-2012
- 48, // 6: SM3
+ 32, // 5: GOST R 34.10-2012
+ 32, // 6: SM3
0 // 7: Unassigned
};
@@ -1435,8 +1435,8 @@ static int32_t parse_ds_rdata(
32, // 2: SHA-256
32, // 3: GOST R 34.11-94
48, // 4: SHA-384
- 48, // 5: GOST R 34.10-2012
- 48, // 6: SM3
+ 32, // 5: GOST R 34.10-2012
+ 32, // 6: SM3
0 // 7: Unassigned
};
@@ -2752,29 +2752,33 @@ static int32_t parse_amtrelay_rdata(
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
return code;
- if (octets[1]) {
- if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
- return code;
- switch (octets[1]) {
- case 1: /* IPv4 address */
- type = (const type_info_t *)amtrelay_ipv4;
- fields = type->rdata.fields;
- if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0)
- return code;
- break;
- case 2: /* IPv6 address */
- type = (const type_info_t *)amtrelay_ipv6;
- fields = type->rdata.fields;
- if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0)
- return code;
- break;
- case 3: /* domain name */
- if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
- return code;
- break;
- default:
- SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
- }
+ if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
+ return code;
+ switch (octets[1]) {
+ case 0:
+ /* no gateway requires a '.' as the relay in presentation format
+ * without parsing it into wireformat rdata */
+ if (!(token->length == 1 && *token->data == '.'))
+ SYNTAX_ERROR(parser, "Invalid %s in %s, the no gateway type (type 0) of AMTRELAY requires the relay field to have '.' in it", NAME(&fields[3]), NAME(type));
+ break;
+ case 1: /* IPv4 address */
+ type = (const type_info_t *)amtrelay_ipv4;
+ fields = type->rdata.fields;
+ if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0)
+ return code;
+ break;
+ case 2: /* IPv6 address */
+ type = (const type_info_t *)amtrelay_ipv6;
+ fields = type->rdata.fields;
+ if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0)
+ return code;
+ break;
+ case 3: /* domain name */
+ if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
+ return code;
+ break;
+ default:
+ SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[3]), NAME(type));
}
octets[1] |= D;
if ((code = take_delimiter(parser, type, token)) < 0)
nsd 4.14.1 update