From: Stuart Henderson Subject: Re: NSD update To: tech Date: Wed, 3 Sep 2025 20:49:06 +0100 On 2025/09/03 14:59, Stuart Henderson wrote: > Looking at updating NSD - I've polished up an old diff I had, taking > us to NSD 4.11.0. > > I'll look at updating again afterwards, but there have been enough > changes in 4.11.0 that I'd like to do that as a separate stage (not > least to simplify the CVS-wrangling). Turns out that was a good move because a bunch of merging was required in Makefile.in. More churn for things that are very unlikely to be relevant to us. Built on amd64 aarch64. Only very lightly tested so far. (We could also move nsd to ports if people are starting to get uneasy about keeping it in base. But, if it is in base, I'd like not to diverge much further from upstream, it is already a pain fiddling with compat and b64top parts). Not touched yet: - Disable TLSv1.2 if TLSv1.3 is available. I plan to undo that change - Change default for send-buffer-size to 4m Possibly needs checking as 4m seems fairly large for us; send-buffer-size: Set the send buffer size for query-servicing sockets. Set to 0 to use the default settings. It needs some space to be able to deal with packets that wait for local address resolution, from like ARP and NDP discovery, before they are sent out, hence it is elevated above the system default by default. The default is 4194304 bytes (4m). Index: Makefile.bsd-wrapper =================================================================== RCS file: /cvs/src/usr.sbin/nsd/Makefile.bsd-wrapper,v diff -u -p -r1.21 Makefile.bsd-wrapper --- Makefile.bsd-wrapper 1 Apr 2024 14:24:30 -0000 1.21 +++ Makefile.bsd-wrapper 3 Sep 2025 19:38:49 -0000 @@ -21,7 +21,7 @@ CONFIGURE_OPTS= --prefix=/usr \ --with-xfrdir=${CHROOTDIR}/run/xfr \ --with-xfrdfile=${CHROOTDIR}/run/xfrd.state \ --with-libevent=/usr \ - --enable-ratelimit + --disable-dnstap PROG= nsd nsd-checkconf nsd-checkzone nsd-control Index: Makefile.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/Makefile.in,v diff -u -p -r1.39 Makefile.in --- Makefile.in 3 Sep 2025 18:46:48 -0000 1.39 +++ Makefile.in 3 Sep 2025 19:38:49 -0000 @@ -31,6 +31,7 @@ chrootdir= @chrootdir@ user = @user@ DNSTAP_SRC=@DNSTAP_SRC@ DNSTAP_OBJ=@DNSTAP_OBJ@ +sharedfilesdir = @sharedfilesdir@ # override $U variable which is used by autotools for deansification (for # K&R C compilers), but causes problems if $U is defined in the env). @@ -55,10 +56,15 @@ YACC = @YACC@ LEX = @LEX@ PROTOC_C = @PROTOC_C@ -DATE != date +'%b %e, %y' +DATE = `date +'%b %e, %y'` PROJECT = @PACKAGE_NAME@ VERSION = @PACKAGE_VERSION@ +# BPF/XDP settings +CLANG = @CLANG@ +LLC = @LLC@ +BPF_CFLAGS = @BPF_CFLAGS@ + COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) EDIT = $(SED) \ @@ -82,19 +88,22 @@ EDIT = $(SED) \ -e 's,@user\@,$(user),g' \ -e 's/@project\@/$(PROJECT)/g' \ -e 's/@version\@/$(VERSION)/g' \ - -e 's/@date\@/$(DATE)/g' + -e 's,@sharedfilesdir\@,$(sharedfilesdir),g' \ + -e "s/@date\@/$(DATE)/g" -TARGETS=nsd nsd-checkconf nsd-checkzone nsd-control nsd.conf.sample nsd-control-setup.sh +XDP_TARGETS=@xdp_targets@ +TARGETS=nsd nsd-checkconf nsd-checkzone nsd-control nsd.conf.sample nsd-control-setup.sh $(XDP_TARGETS) MANUALS=nsd.8 nsd-checkconf.8 nsd-checkzone.8 nsd-control.8 nsd.conf.5 COMMON_OBJ=answer.o axfr.o ixfr.o ixfrcreate.o buffer.o configlexer.o configparser.o dname.o dns.o edns.o iterated_hash.o lookup3.o namedb.o nsec3.o options.o packet.o query.o rbtree.o radtree.o rdata.o region-allocator.o rrl.o siphash.o tsig.o tsig-openssl.o udb.o util.o bitset.o popen3.o proxy_protocol.o -XFRD_OBJ=xfrd-catalog-zones.o xfrd-disk.o xfrd-notify.o xfrd-tcp.o xfrd.o remote.o $(DNSTAP_OBJ) -NSD_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) difffile.o ipc.o mini_event.o netio.o nsd.o server.o dbaccess.o dbcreate.o zonec.o verify.o +XFRD_OBJ=xfrd-catalog-zones.o xfrd-disk.o xfrd-notify.o xfrd-tcp.o xfrd.o remote.o metrics.o $(DNSTAP_OBJ) +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_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_bitset.o cutest_popen3.o cutest_iter.o cutest_event.o cutest.o qtest.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 .PHONY: all html @@ -137,10 +146,10 @@ nsd-control-setup.sh: $(srcdir)/nsd-cont nsd.conf.sample: $(srcdir)/nsd.conf.sample.in config.h rm -f nsd.conf.sample - $(EDIT) $(srcdir)/nsd.conf.sample.in | $(AWK) '/RRLconfig'@ratelimit@'/ { while($$0 !~ /.*RRLend.*/) { getline; } getline; } {print} ' > nsd.conf.sample + $(EDIT) $(srcdir)/nsd.conf.sample.in > nsd.conf.sample nsd.conf.5: $(srcdir)/nsd.conf.5.in config.h - $(EDIT) $(srcdir)/nsd.conf.5.in | $(AWK) '/rrlstart'@ratelimit@'/ { while($$0 !~ /.*rrlend.*/) { getline; } getline; } {print} ' > $@ + $(EDIT) $(srcdir)/nsd.conf.5.in > $@ nsd.8: $(srcdir)/nsd.8.in config.h $(EDIT) $(srcdir)/nsd.8.in > $@ @@ -178,6 +187,8 @@ orig-install: all $(INSTALL_DATA) nsd-control.8 $(DESTDIR)$(mandir)/man8/nsd-control.8 $(INSTALL_DATA) nsd.conf.5 $(DESTDIR)$(mandir)/man5/nsd.conf.5 $(INSTALL_DATA) nsd.conf.sample $(DESTDIR)$(nsdconfigfile).sample + if test -n "@xdp@"; then $(INSTALL_DATA) xdp-dns-redirect_kern.o $(DESTDIR)$(sharedfilesdir)/xdp-dns-redirect_kern.o; fi + if test -n "@xdp@"; then $(INSTALL_DATA) xdp-dns-redirect_kern_pinned.o $(DESTDIR)$(sharedfilesdir)/xdp-dns-redirect_kern_pinned.o; fi uninstall: @echo @@ -185,6 +196,8 @@ uninstall: rm -f -- $(DESTDIR)$(mandir)/man8/nsd.8 $(DESTDIR)$(mandir)/man5/nsd.conf.5 rm -f -- $(DESTDIR)$(mandir)/man8/nsd-checkconf.8 $(DESTDIR)$(mandir)/man8/nsd-checkzone.8 $(DESTDIR)$(mandir)/man8/nsd-control.8 rm -f -- $(DESTDIR)$(pidfile) + rm -f -- $(DESTDIR)$(sharedfilesdir)/xdp-dns-redirect_kern.o + rm -f -- $(DESTDIR)$(sharedfilesdir)/xdp-dns-redirect_kern_pinned.o @echo @echo "You still need to remove $(DESTDIR)$(configdir), $(DESTDIR)$(piddir), $(DESTDIR)$(xfrdfile), $(DESTDIR)$(zonelistfile) $(DESTDIR)$(cookiesecretsfile) directory by hand." @@ -193,6 +206,8 @@ test: simdzone/libzone.a: $(MAKE) -C simdzone +simdzone/include/zone/export.h: simdzone/libzone.a + nsd: simdzone/libzone.a $(NSD_OBJ) $(LIBOBJS) $(LINK) -o $@ $(NSD_OBJ) $(LIBOBJS) simdzone/libzone.a $(SSL_LIBS) $(LIBS) @@ -229,7 +244,7 @@ audit: nsd nsd-checkconf nsd-checkzone n ./checksec --file=nsd-mem .clean: - rm -f *.o $(TARGETS) $(MANUALS) cutest popen3_echo xfr-inspect nsd-mem + rm -f *.o *.ll $(TARGETS) $(MANUALS) cutest popen3_echo xfr-inspect nsd-mem rm -f doc/manual/conf.py doc/manual/manpages/nsd.conf.5.html doc/manual/manpages/nsd.8.html doc/manual/manpages/nsd-checkconf.8.html doc/manual/manpages/nsd-checkzone.8.html doc/manual/manpages/nsd-control.8.html rm -rf doc/manual/doctrees doc/manual/html @@ -239,6 +254,7 @@ audit: nsd nsd-checkconf nsd-checkzone n .realclean: .distclean rm -rf autom4te* rm -f configlexer.c configparser.h configparser.c configparser.stamp + rm -f xdp-dns-redirect_kern_pinned.c clean: .clean $(MAKE) -C simdzone clean @@ -358,6 +374,9 @@ cutest_udbrad.o: $(srcdir)/tpkg/cutest/c cutest_util.o: $(srcdir)/tpkg/cutest/cutest_util.c $(COMPILE) -c $(srcdir)/tpkg/cutest/cutest_util.c +cutest_xfrd_tcp.o: $(srcdir)/tpkg/cutest/cutest_xfrd_tcp.c + $(COMPILE) -c $(srcdir)/tpkg/cutest/cutest_xfrd_tcp.c + cutest_bitset.o: $(srcdir)/tpkg/cutest/cutest_bitset.c $(COMPILE) -c $(srcdir)/tpkg/cutest/cutest_bitset.c @@ -400,6 +419,7 @@ configparser.o: configparser.c config.h options.o: $(srcdir)/options.c config.h configparser.h dns.o: $(srcdir)/dns.c config.h zonec.o: $(srcdir)/zonec.c config.h +metrics.o: $(srcdir)/metrics.c config.h # dnstap dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \ @@ -413,9 +433,23 @@ dnstap_collector.o: $(srcdir)/dnstap/dns $(srcdir)/buffer.h $(srcdir)/namedb.h $(srcdir)/dname.h \ $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \ $(srcdir)/options.h $(srcdir)/remote.h -dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto +# Builds both dnstap/dnstap.pb-c.c and dnstap/dnstap.pb-c.h. +# To avoid double-building we split one target out. +dnstap/dnstap.pb-c.c: $(srcdir)/dnstap/dnstap.proto @-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi $(PROTOC_C) --c_out=. --proto_path=$(srcdir) $(srcdir)/dnstap/dnstap.proto +dnstap/dnstap.pb-c.h: dnstap/dnstap.pb-c.c + touch $@ + +# eBPF XDP program +xdp-dns-redirect_kern.o: $(srcdir)/xdp-dns-redirect_kern.c + $(CLANG) -S -target bpf $(BPF_CFLAGS) -O2 -emit-llvm -g -o ${@:.o=.ll} $< + $(LLC) -march=bpf -filetype=obj -o $@ ${@:.o=.ll} + +xdp-dns-redirect_kern_pinned.o: $(srcdir)/xdp-dns-redirect_kern.c + sed -E '/\/\/ SEDUNCOMMENTTHIS/s_(/\*|\*/)__g' < $< > ${@:.o=.c} + $(CLANG) -S -target bpf $(BPF_CFLAGS) -O2 -emit-llvm -g -o ${@:.o=.ll} ${@:.o=.c} + $(LLC) -march=bpf -filetype=obj -o $@ ${@:.o=.ll} # autoconf rules config.h.in: configure.ac @@ -442,6 +476,7 @@ depend: -e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.c?dnstap/dnstap.pb-c.c?g' \ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.h?dnstap/dnstap.pb-c.h?g' \ + -e 's?$$(srcdir)/simdzone/include/zone/export.h?simdzone/include/zone/export.h?g' \ > $(DEPEND_TMP) cp $(DEPEND_TARGET) $(DEPEND_TMP2) head -`$(EGREP) -n "# Dependencies" $(DEPEND_TARGET) | tail -1 | $(SED) -e 's/:.*$$//'` $(DEPEND_TMP2) > $(DEPEND_TARGET) @@ -459,143 +494,153 @@ proxy_protocol.o: $(srcdir)/util/proxy_p # Dependencies answer.o: $(srcdir)/answer.c config.h $(srcdir)/answer.h $(srcdir)/dns.h $(srcdir)/namedb.h \ - $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h \ - $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/tsig.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 \ $(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 \ - $(srcdir)/util.h + $(srcdir)/util.h $(srcdir)/bitset.h configlexer.o: configlexer.c config.h $(srcdir)/options.h \ $(srcdir)/region-allocator.h $(srcdir)/rbtree.h configparser.h configparser.o: configparser.c config.h $(srcdir)/options.h \ - $(srcdir)/region-allocator.h $(srcdir)/rbtree.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/tsig.h $(srcdir)/rrl.h $(srcdir)/query.h \ - $(srcdir)/namedb.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/packet.h configparser.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 \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.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)/bitset.h $(srcdir)/ixfr.h $(srcdir)/query.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 \ - $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/udb.h $(srcdir)/options.h $(srcdir)/nsd.h \ - $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/packet.h $(srcdir)/tsig.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 \ - $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.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)/bitset.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/tsig.h $(srcdir)/ixfr.h $(srcdir)/zonec.h $(srcdir)/xfrd-catalog-zones.h $(srcdir)/xfrd.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 \ - $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h \ - $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.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 \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.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 \ - $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/nsd.h $(srcdir)/bitset.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.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 \ - $(srcdir)/buffer.h $(srcdir)/util.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)/bitset.h $(srcdir)/xfrd-notify.h \ - $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/rrl.h $(srcdir)/query.h $(srcdir)/packet.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 \ - $(srcdir)/util.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 \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h \ - $(srcdir)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/rdata.h $(srcdir)/axfr.h $(srcdir)/options.h $(srcdir)/zonec.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 \ - $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \ - $(srcdir)/ixfr.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/options.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)/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 \ - $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsec3.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 \ - $(srcdir)/util.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 \ - $(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)/util/proxy_protocol.h config.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)/region-allocator.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/options.h $(srcdir)/rbtree.h $(srcdir)/rrl.h $(srcdir)/query.h \ - $(srcdir)/namedb.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/packet.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 \ $(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)/tsig.h \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/dname.h $(srcdir)/options.h $(srcdir)/rbtree.h $(srcdir)/zonec.h $(srcdir)/namedb.h \ - $(srcdir)/dns.h $(srcdir)/radtree.h +nsd-control.o: $(srcdir)/nsd-control.c config.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 \ $(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)/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 \ - $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h \ - $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/answer.h $(srcdir)/packet.h $(srcdir)/query.h $(srcdir)/tsig.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 \ $(srcdir)/region-allocator.h $(srcdir)/rbtree.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h \ - $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/ixfr.h $(srcdir)/difffile.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 \ - $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/query.h \ - $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/tsig.h $(srcdir)/rdata.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 \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h $(srcdir)/query.h \ - $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.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)/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)/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)/radtree.h $(srcdir)/rbtree.h $(srcdir)/zonec.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 \ - $(srcdir)/region-allocator.h $(srcdir)/util.h -remote.o: $(srcdir)/remote.c config.h $(srcdir)/remote.h $(srcdir)/util.h $(srcdir)/xfrd.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 \ $(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)/bitset.h $(srcdir)/difffile.h $(srcdir)/udb.h $(srcdir)/ipc.h $(srcdir)/netio.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)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h \ - $(srcdir)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/lookup3.h $(srcdir)/options.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 \ $(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)/verify.h $(srcdir)/util/proxy_protocol.h config.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 siphash.o: $(srcdir)/siphash.c tsig.o: $(srcdir)/tsig.c config.h $(srcdir)/tsig.h $(srcdir)/buffer.h \ - $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/tsig-openssl.h $(srcdir)/dns.h $(srcdir)/packet.h $(srcdir)/namedb.h \ - $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/query.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.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 \ - $(srcdir)/region-allocator.h $(srcdir)/tsig.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dname.h -udb.o: $(srcdir)/udb.c config.h $(srcdir)/udb.h $(srcdir)/lookup3.h $(srcdir)/util.h -util.o: $(srcdir)/util.c config.h $(srcdir)/util.h $(srcdir)/region-allocator.h $(srcdir)/dname.h \ - $(srcdir)/buffer.h $(srcdir)/namedb.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/rdata.h $(srcdir)/zonec.h $(srcdir)/nsd.h $(srcdir)/edns.h \ - $(srcdir)/bitset.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 \ + $(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 \ - $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.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 \ - $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.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)/bitset.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)/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 \ $(srcdir)/difffile.h $(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h \ - $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/udb.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.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)/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 \ - $(srcdir)/rbtree.h $(srcdir)/region-allocator.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/dns.h \ - $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.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 \ - $(srcdir)/tsig.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/rbtree.h $(srcdir)/xfrd.h \ - $(srcdir)/namedb.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/xfrd-tcp.h $(srcdir)/packet.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 \ $(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)/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 +xfr-inspect.o: $(srcdir)/xfr-inspect.c config.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 \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/rdata.h \ - $(srcdir)/options.h $(srcdir)/nsec3.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 basename.o: $(srcdir)/compat/basename.c @@ -620,37 +665,39 @@ cutest.o: $(srcdir)/tpkg/cutest/cutest.c $(srcdir)/tpkg/cutest/cutest.h cutest_dname.o: $(srcdir)/tpkg/cutest/cutest_dname.c config.h \ $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/dname.h $(srcdir)/buffer.h \ - $(srcdir)/region-allocator.h $(srcdir)/util.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 \ $(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 \ $(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)/iterated_hash.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.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 \ $(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 \ $(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)/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)/bitset.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 \ $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/options.h $(srcdir)/region-allocator.h \ - $(srcdir)/rbtree.h $(srcdir)/util.h $(srcdir)/dname.h $(srcdir)/buffer.h $(srcdir)/util.h $(srcdir)/nsd.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/bitset.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 \ $(srcdir)/popen3.h $(srcdir)/tpkg/cutest/cutest.h cutest_radtree.o: $(srcdir)/tpkg/cutest/cutest_radtree.c config.h \ - $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/radtree.h $(srcdir)/region-allocator.h $(srcdir)/util.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 \ $(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 \ - $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/rbtree.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 \ $(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)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h $(srcdir)/edns.h $(srcdir)/bitset.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 \ $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/tpkg/cutest/qtest.h $(srcdir)/buffer.h $(srcdir)/region-allocator.h \ @@ -658,11 +705,13 @@ cutest_run.o: $(srcdir)/tpkg/cutest/cute cutest_udb.o: $(srcdir)/tpkg/cutest/cutest_udb.c config.h \ $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/udb.h cutest_util.o: $(srcdir)/tpkg/cutest/cutest_util.c config.h \ - $(srcdir)/tpkg/cutest/cutest.h $(srcdir)/region-allocator.h $(srcdir)/util.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)/dns.h \ - $(srcdir)/radtree.h $(srcdir)/options.h $(srcdir)/tsig.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 \ + $(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 \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.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)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.h $(srcdir)/namedb.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: aclocal.m4 =================================================================== RCS file: /cvs/src/usr.sbin/nsd/aclocal.m4,v diff -u -p -r1.5 aclocal.m4 --- aclocal.m4 15 Apr 2024 12:44:24 -0000 1.5 +++ aclocal.m4 3 Sep 2025 19:38:49 -0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.5 -*- Autoconf -*- +# generated automatically by aclocal 1.18.1 -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2025 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 12 (pkg-config-0.29.2) +# serial 13 (pkgconf) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -29,9 +29,7 @@ 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, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -dnl 02111-1307, USA. +dnl along with this program; if not, see . 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 @@ -60,8 +58,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]) -dnl ---------------------------------- +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to @@ -69,6 +67,12 @@ 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)))?$]) @@ -89,6 +93,9 @@ 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: config.guess =================================================================== RCS file: /cvs/src/usr.sbin/nsd/config.guess,v diff -u -p -r1.4 config.guess --- config.guess 3 Sep 2025 18:46:48 -0000 1.4 +++ config.guess 3 Sep 2025 19:38:49 -0000 @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2023 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-09' +timestamp='2023-08-22' # 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-2022 Free Software Foundation, Inc. +Copyright 1992-2023 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,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -169,6 +172,7 @@ 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" @@ -459,7 +463,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 ;; @@ -904,7 +908,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +970,37 @@ 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:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + 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 ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1066,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + 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:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1151,16 +1190,27 @@ EOF ;; x86_64:Linux:*:*) set_cc_for_build + CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then - 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 + 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 fi - GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC @@ -1180,7 +1230,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 ;; @@ -1321,7 +1371,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 GUESS=i586-unisys-sysv4 ;; @@ -1367,8 +1417,11 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; - x86_64:Haiku:*:*) - GUESS=x86_64-unknown-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 ;; 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.45 config.h.in --- config.h.in 3 Sep 2025 18:46:48 -0000 1.45 +++ config.h.in 3 Sep 2025 19:38:49 -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 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,139 +76,145 @@ /* 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 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 header file. */ #undef HAVE_EVENT_H -/* Define to 1 if you have the `EVP_cleanup' 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. */ #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 `ev_default_loop' 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. */ #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 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 presumably ftello) exists and is declared. */ +/* Define to 1 if fseeko (and ftello) are declared in stdio.h. */ #undef HAVE_FSEEKO -/* Define to 1 if you have the `gai_strerror' function. */ +/* 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 header file. */ @@ -217,65 +223,65 @@ /* Define to 1 if you have the 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 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 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 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 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 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 header file. */ @@ -293,10 +299,10 @@ /* Define to 1 if you have the 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 header file. */ @@ -311,16 +317,16 @@ /* Define to 1 if you have the 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) */ @@ -338,49 +344,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 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 header file. */ @@ -398,19 +404,19 @@ /* Define to 1 if you have the 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 header file. */ @@ -419,34 +425,34 @@ /* Define to 1 if you have the 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 header file. */ @@ -497,7 +503,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 header file. */ @@ -506,7 +512,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 header file. */ @@ -515,13 +521,13 @@ /* Define to 1 if you have the 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. */ @@ -561,6 +567,9 @@ /* Define to nsd-control proto version. */ #undef NSD_CONTROL_VERSION +/* Define the default metrics HTTP endpoint port. */ +#undef NSD_METRICS_PORT + /* Pathname to start nsd from nsd-control */ #undef NSD_START_PATH @@ -604,13 +613,16 @@ safely assume C89 semantics that RETSIGTYPE is void.' */ #undef RETSIGTYPE -/* The size of `off_t', as computed by sizeof. */ +/* NSD shared files dir */ +#undef SHAREDFILESDIR + +/* 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 C90 standard headers exist (not just the ones +/* Define to 1 if all of the C89 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 @@ -652,6 +664,10 @@ purposes. */ #undef USE_LOG_PROCESS_ROLE +/* Define this to expose NSD statistics via a prometheus metrics HTTP + endpoint. */ +#undef USE_METRICS + /* Define if you want to use internal select based events */ #undef USE_MINI_EVENT @@ -661,7 +677,7 @@ /* Define this to configure to use the radix tree. */ #undef USE_RADIX_TREE -/* Enable extensions on AIX 3, Interix. */ +/* Enable extensions on AIX, Interix, z/OS. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif @@ -722,11 +738,15 @@ #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 ISO/IEC TS 18661-3:2015. */ +/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */ #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ # undef __STDC_WANT_IEC_60559_TYPES_EXT__ #endif @@ -752,6 +772,9 @@ /* Define this to enable TCP fast open. */ #undef USE_TCP_FASTOPEN +/* Define this to enable the use of AF_XDP sockets. */ +#undef USE_XDP + /* Define this to enable per-zone statistics gathering. */ #undef USE_ZONE_STATS @@ -767,8 +790,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. */ @@ -780,25 +803,31 @@ /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* Define to 1 if necessary to make fseeko visible. */ #undef _LARGEFILE_SOURCE -/* Define for large files, on AIX-style hosts. */ +/* Define to 1 on platforms where this makes off_t a 64-bit type. */ #undef _LARGE_FILES /* Enable for compile on Minix */ #undef _NETBSD_SOURCE -/* Define to empty if `const' does not conform to ANSI C. */ +/* 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. */ #undef const -/* Define to `int' if doesn't define. */ +/* Define as 'int' if 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 @@ -819,7 +848,7 @@ /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc -/* Define to `long int' if does not define. */ +/* Define to 'long int' if does not define. */ #undef off_t /* Define as a signed integer type capable of holding a process identifier. */ @@ -828,7 +857,7 @@ /* Define "sig_atomic_t" to "int" if "sig_atomic_t" is missing */ #undef sig_atomic_t -/* Define to `unsigned int' if does not define. */ +/* Define as 'unsigned int' if doesn't define. */ #undef size_t /* Define "socklen_t" to "int" if "socklen_t" is missing */ @@ -843,7 +872,7 @@ /* Define "suseconds_t" to "time_t" if "suseconds_t" is missing */ #undef suseconds_t -/* Define to `int' if doesn't define. */ +/* Define as 'int' if doesn't define. */ #undef uid_t /* Define "uint16_t" to "unsigned short" if "uint16_t" is missing */ @@ -861,7 +890,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.4 config.sub --- config.sub 3 Sep 2025 18:46:48 -0000 1.4 +++ config.sub 3 Sep 2025 19:38:49 -0000 @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2023 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2023-09-19' # 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 &2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ 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*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,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) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1199,45 +1200,23 @@ 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 | loongarchx32 \ + | loongarch32 | loongarch64 \ | 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 | 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 \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ @@ -1285,7 +1264,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 @@ -1306,11 +1285,12 @@ 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 @@ -1341,6 +1321,10 @@ 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 @@ -1506,10 +1490,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=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. ;; @@ -1528,12 +1518,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1536,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1586,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; mips*-*) - os=elf + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1612,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1694,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,7 +1717,8 @@ esac fi -# Now, validate our (potentially fixed-up) OS. +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). + case $os in # Sometimes we do "kernel-libc", so those need to count as OSes. musl* | newlib* | relibc* | uclibc*) @@ -1720,6 +1729,9 @@ 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. @@ -1728,7 +1740,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* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1737,11 +1749,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1754,7 +1766,7 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) @@ -1762,41 +1774,99 @@ 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"\': OS \`"$os"\' not recognized 1>&2 + 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 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 in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +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*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # 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 exit 1 ;; esac @@ -1879,7 +1949,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: Index: configlexer.lex =================================================================== RCS file: /cvs/src/usr.sbin/nsd/configlexer.lex,v diff -u -p -r1.26 configlexer.lex --- configlexer.lex 3 Sep 2025 18:46:48 -0000 1.26 +++ configlexer.lex 3 Sep 2025 19:38:49 -0000 @@ -258,6 +258,10 @@ server-key-file{COLON} { LEXOUT(("v(%s) server-cert-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER_CERT_FILE;} control-key-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_KEY_FILE;} control-cert-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_CERT_FILE;} +metrics-enable{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_METRICS_ENABLE;} +metrics-interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_METRICS_INTERFACE;} +metrics-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_METRICS_PORT;} +metrics-path{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_METRICS_PATH;} AXFR { LEXOUT(("v(%s) ", yytext)); return VAR_AXFR;} UDP { LEXOUT(("v(%s) ", yytext)); return VAR_UDP;} rrl-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_SIZE;} @@ -327,6 +331,11 @@ verifier-timeout{COLON} { LEXOUT(("v(%s catalog{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CATALOG; } catalog-member-pattern{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CATALOG_MEMBER_PATTERN; } catalog-producer-zone{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CATALOG_PRODUCER_ZONE; } +xdp-interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XDP_INTERFACE; } +xdp-program-path{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XDP_PROGRAM_PATH; } +xdp-program-load{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XDP_PROGRAM_LOAD; } +xdp-bpffs-path{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XDP_BPFFS_PATH; } +xdp-force-copy{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XDP_FORCE_COPY; } {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} servers={UNQUOTEDLETTER}* { Index: configparser.y =================================================================== RCS file: /cvs/src/usr.sbin/nsd/configparser.y,v diff -u -p -r1.40 configparser.y --- configparser.y 3 Sep 2025 18:46:48 -0000 1.40 +++ configparser.y 3 Sep 2025 19:38:49 -0000 @@ -139,6 +139,10 @@ struct component { %token VAR_DROP_UPDATES %token VAR_XFRD_TCP_MAX %token VAR_XFRD_TCP_PIPELINE +%token VAR_METRICS_ENABLE +%token VAR_METRICS_INTERFACE +%token VAR_METRICS_PORT +%token VAR_METRICS_PATH /* dnstap */ %token VAR_DNSTAP @@ -213,6 +217,11 @@ struct component { %token VAR_CATALOG %token VAR_CATALOG_MEMBER_PATTERN %token VAR_CATALOG_PRODUCER_ZONE +%token VAR_XDP_INTERFACE +%token VAR_XDP_PROGRAM_PATH +%token VAR_XDP_PROGRAM_LOAD +%token VAR_XDP_BPFFS_PATH +%token VAR_XDP_FORCE_COPY /* zone */ %token VAR_ZONE @@ -587,6 +596,70 @@ server_option: } } } + } + | VAR_XDP_INTERFACE STRING + { +#ifdef USE_XDP + cfg_parser->opt->xdp_interface = region_strdup(cfg_parser->opt->region, $2); +#endif + } + | VAR_XDP_PROGRAM_PATH STRING + { +#ifdef USE_XDP + cfg_parser->opt->xdp_program_path = region_strdup(cfg_parser->opt->region, $2); +#endif + } + | VAR_XDP_PROGRAM_LOAD boolean + { +#ifdef USE_XDP + cfg_parser->opt->xdp_program_load = $2; +#endif + } + | VAR_XDP_BPFFS_PATH STRING + { +#ifdef USE_XDP + cfg_parser->opt->xdp_bpffs_path = region_strdup(cfg_parser->opt->region, $2); +#endif + } + | VAR_XDP_FORCE_COPY boolean + { +#ifdef USE_XDP + cfg_parser->opt->xdp_force_copy = $2; +#endif + } + | VAR_METRICS_ENABLE boolean + { +#ifdef USE_METRICS + cfg_parser->opt->metrics_enable = $2; +#endif /* USE_METRICS */ + } + | VAR_METRICS_INTERFACE ip_address + { +#ifdef USE_METRICS + struct ip_address_option *ip = cfg_parser->opt->metrics_interface; + if(ip == NULL) { + cfg_parser->opt->metrics_interface = $2; + } else { + while(ip->next != NULL) { ip = ip->next; } + ip->next = $2; + } +#endif /* USE_METRICS */ + } + | VAR_METRICS_PORT number + { +#ifdef USE_METRICS + if($2 == 0) { + yyerror("metrics port number expected"); + } else { + cfg_parser->opt->metrics_port = (int)$2; + } +#endif /* USE_METRICS */ + } + | VAR_METRICS_PATH STRING + { +#ifdef USE_METRICS + cfg_parser->opt->metrics_path = region_strdup(cfg_parser->opt->region, $2); +#endif /* USE_METRICS */ } ; Index: configure =================================================================== RCS file: /cvs/src/usr.sbin/nsd/configure,v diff -u -p -r1.62 configure --- configure 3 Sep 2025 18:46:48 -0000 1.62 +++ configure 3 Sep 2025 19:38:49 -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.11.0. +# Generated by GNU Autoconf 2.71 for NSD 4.13.0. # # Report bugs to . # @@ -612,8 +612,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='NSD' PACKAGE_TARNAME='nsd' -PACKAGE_VERSION='4.11.0' -PACKAGE_STRING='NSD 4.11.0' +PACKAGE_VERSION='4.13.0' +PACKAGE_STRING='NSD 4.13.0' PACKAGE_BUGREPORT='https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl' PACKAGE_URL='' @@ -664,11 +664,17 @@ DNSTAP_OBJ DNSTAP_SRC opt_dnstap_socket_path ENABLE_DNSTAP +PROTOC_GEN_C PROTOC_C +PROTOC +xdp +xdp_targets +BPF_CFLAGS +LLC +CLANG SSL_LIBS HAVE_SSL ratelimit_default -ratelimit host_os host_vendor host_cpu @@ -688,6 +694,7 @@ LEXLIB LEX_OUTPUT_ROOT user chrootdir +sharedfilesdir xfrdir cookiesecretsfile zonelistfile @@ -756,6 +763,7 @@ enable_option_checking with_configdir with_nsd_conf_file with_logfile +with_dbdir with_pidfile with_dbfile with_zonesdir @@ -763,6 +771,7 @@ with_xfrdfile with_zonelistfile with_cookiesecretsfile with_xfrdir +with_sharedfilesdir with_chroot with_user enable_flto @@ -788,6 +797,7 @@ enable_minimal_responses enable_mmap enable_radix_tree enable_packed +enable_xdp enable_dnstap with_dnstap_socket_path with_protobuf_c @@ -813,6 +823,9 @@ LIBS CPPFLAGS YFLAGS CPP +CLANG +LLC +BPF_CFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR @@ -1368,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.11.0 to adapt to many kinds of systems. +\`configure' configures NSD 4.13.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1434,7 +1447,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of NSD 4.11.0:";; + short | recursive ) echo "Configuration of NSD 4.13.0:";; esac cat <<\_ACEOF @@ -1453,19 +1466,19 @@ Optional Features: problems for IPv6 --enable-root-server Configure NSD as a root server (obsolete) --disable-ipv6 Disables IPv6 support - --enable-bind8-stats Enables BIND8 like NSTATS & XSTATS and statistics in + --disable-bind8-stats Disable BIND8 like NSTATS & XSTATS and statistics in nsd-control - --enable-zone-stats Enable per-zone statistics gathering (needs - --enable-bind8-stats) + --disable-zone-stats Disable per-zone statistics gathering (if enabled, + it needs bind8-stats) --enable-checking Enable internal runtime checks --enable-log-role Shows the role of processes in the logfile (enable this only for debugging purposes) --enable-memclean Cleanup memory (at exit) for eg. valgrind, memcheck - --enable-ratelimit Enable rate limiting - --enable-ratelimit-default-is-off - Enable this to set default of ratelimit to off - (enable in nsd.conf), otherwise ratelimit is enabled - by default if --enable-ratelimit is enabled + --disable-ratelimit Disable rate limiting + --disable-ratelimit-default-is-off + Disable this to set default of ratelimit to on (this + controls the default, ratelimits can be enabled and + disabled in nsd.conf) --disable-nsec3 Disable NSEC3 support --disable-minimal-responses Disable response minimization. More truncation. @@ -1475,7 +1488,8 @@ Optional Features: less memory, but uses some more CPU. --enable-packed Enable packed structure alignment, uses less memory, but unaligned reads. - --enable-dnstap Enable dnstap support (requires fstrm, protobuf-c) + --enable-xdp Enable XDP support. + --disable-dnstap Disable dnstap support (requires fstrm, protobuf-c) --enable-systemd compile with systemd support --enable-tcp-fastopen Enable TCP Fast Open --disable-westmere Disable Westmere (SSE4.2) parser kernel @@ -1488,6 +1502,8 @@ Optional Packages: --with-nsd_conf_file=path Pathname to the NSD configuration file --with-logfile=path Pathname to the default log file + --with-dbdir=dir Base directory for the xfrd zone timer state file, + the zone list file and the cookie secrets file --with-pidfile=path Pathname to the NSD pidfile --with-dbfile=path Pathname to the NSD database (obsolete) --with-zonesdir=dir NSD default location for zone files @@ -1497,6 +1513,8 @@ Optional Packages: --with-cookiesecretsfile=path Pathname to the NSD cookie secrets file --with-xfrdir=path Pathname to where the NSD transfer dir is created + --with-sharedfilesdir=dir + NSD shared files directory --with-chroot=dir NSD default chroot directory --with-user=username User name or ID to answer the queries with --with-libevent=pathname @@ -1533,6 +1551,9 @@ Some influential environment variables: This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. CPP C preprocessor + CLANG location of clang compiler (only needed for xdp) + LLC location of LLVM static compiler (only needed for xdp) + BPF_CFLAGS The list of arguments passed to the BPF compiler PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path @@ -1614,7 +1635,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -NSD configure 4.11.0 +NSD configure 4.13.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2271,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.11.0, which was +It was created by NSD $as_me 4.13.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -4293,6 +4314,13 @@ fi # dbdir=${localstatedir}/db/nsd +# Check whether --with-dbdir was given. +if test ${with_dbdir+y} +then : + withval=$with_dbdir; dbdir=$withval +fi + + # # Determine the pidfile location. Check if /var/run exists, if so set pidfile # to /var/run/nsd.pid by default @@ -4409,6 +4437,21 @@ _ACEOF +sharedfilesdir=${datarootdir}/nsd + +# Check whether --with-sharedfilesdir was given. +if test ${with_sharedfilesdir+y} +then : + withval=$with_sharedfilesdir; sharedfilesdir=$withval +fi + + +cat >>confdefs.h <<_ACEOF +#define SHAREDFILESDIR "`eval echo $sharedfilesdir`" +_ACEOF + + + # nsd sbin location. tmpinstantiate execprefix with defaults if not yet done. if test "x${exec_prefix}" = "xNONE"; then if test "x${prefix}" = "xNONE"; then exec_prefix="$ac_default_prefix" @@ -7102,10 +7145,38 @@ then : fi # only in libev. (tested on 4.00) + + # prometheus metrics depend on libevent 2.0 and later, and is therefore + # only enabled when the required version is found and used + + for ac_func in evhttp_free +do : + ac_fn_c_check_func "$LINENO" "evhttp_free" "ac_cv_func_evhttp_free" +if test "x$ac_cv_func_evhttp_free" = xyes +then : + printf "%s\n" "#define HAVE_EVHTTP_FREE 1" >>confdefs.h + + +printf "%s\n" "#define USE_METRICS /**/" >>confdefs.h + + +printf "%s\n" "#define NSD_METRICS_PORT 9100" >>confdefs.h + + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: disabling prometheus metrics" >&5 +printf "%s\n" "$as_me: disabling prometheus metrics" >&6;} + +fi + +done else printf "%s\n" "#define USE_MINI_EVENT 1" >>confdefs.h + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Prometheus metrics are disabled with the builtin libevent alternative" >&5 +printf "%s\n" "$as_me: Prometheus metrics are disabled with the builtin libevent alternative" >&6;} fi # Checks for header files. @@ -10458,13 +10529,13 @@ fi case "$enable_bind8_stats" in - yes|'') + no) + ;; + yes|*) printf "%s\n" "#define BIND8_STATS /**/" >>confdefs.h ;; - no|*) - ;; esac # Check whether --enable-zone-stats was given. @@ -10474,7 +10545,9 @@ then : fi case "$enable_zone_stats" in - yes) + no) + ;; + yes|*) printf "%s\n" "#define USE_ZONE_STATS /**/" >>confdefs.h @@ -10482,8 +10555,6 @@ printf "%s\n" "#define USE_ZONE_STATS /* printf "%s\n" "#define BIND8_STATS /**/" >>confdefs.h ;; - no|''|*) - ;; esac # Check whether --enable-checking was given. @@ -10665,18 +10736,15 @@ then : fi case "$enable_ratelimit" in - yes) + no) + ;; + yes|*) printf "%s\n" "#define RATELIMIT /**/" >>confdefs.h - ratelimit="xx" - ;; - no|*) - ratelimit="" ;; esac - # Check whether --enable-ratelimit-default-is-off was given. if test ${enable_ratelimit_default_is_off+y} then : @@ -10684,15 +10752,15 @@ then : fi case "$enable_ratelimit_default_is_off" in - yes) + no) + ratelimit_default="on" + ;; + yes|*) printf "%s\n" "#define RATELIMIT_DEFAULT_OFF /**/" >>confdefs.h ratelimit_default="off" ;; - no|*) - ratelimit_default="on" - ;; esac @@ -11099,6 +11167,12 @@ then : printf "%s\n" "#define HAVE_ASN1_STRING_GET0_DATA 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "EVP_PKEY_get0_type_name" "ac_cv_func_EVP_PKEY_get0_type_name" +if test "x$ac_cv_func_EVP_PKEY_get0_type_name" = xyes +then : + printf "%s\n" "#define HAVE_EVP_PKEY_GET0_TYPE_NAME 1" >>confdefs.h + +fi if test "$ac_cv_func_SHA1_Init" = "yes"; then @@ -11485,6 +11559,306 @@ fi ;; esac +# Check whether --enable-xdp was given. +if test ${enable_xdp+y} +then : + enableval=$enable_xdp; +fi + +case "$enable_xdp" in + yes) + +printf "%s\n" "#define USE_XDP /**/" >>confdefs.h + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing xdp_program__open_file" >&5 +printf %s "checking for library containing xdp_program__open_file... " >&6; } +if test ${ac_cv_search_xdp_program__open_file+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char xdp_program__open_file (); +int +main (void) +{ +return xdp_program__open_file (); + ; + return 0; +} +_ACEOF +for ac_lib in '' xdp +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_xdp_program__open_file=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_xdp_program__open_file+y} +then : + break +fi +done +if test ${ac_cv_search_xdp_program__open_file+y} +then : + +else $as_nop + ac_cv_search_xdp_program__open_file=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_xdp_program__open_file" >&5 +printf "%s\n" "$ac_cv_search_xdp_program__open_file" >&6; } +ac_res=$ac_cv_search_xdp_program__open_file +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else $as_nop + as_fn_error $? "Cannot find libxdp, but is needed for xdp support." "$LINENO" 5 +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing bpf_map__fd" >&5 +printf %s "checking for library containing bpf_map__fd... " >&6; } +if test ${ac_cv_search_bpf_map__fd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char bpf_map__fd (); +int +main (void) +{ +return bpf_map__fd (); + ; + return 0; +} +_ACEOF +for ac_lib in '' bpf +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_bpf_map__fd=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_bpf_map__fd+y} +then : + break +fi +done +if test ${ac_cv_search_bpf_map__fd+y} +then : + +else $as_nop + ac_cv_search_bpf_map__fd=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_bpf_map__fd" >&5 +printf "%s\n" "$ac_cv_search_bpf_map__fd" >&6; } +ac_res=$ac_cv_search_bpf_map__fd +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else $as_nop + as_fn_error $? "Cannot find libbpf, but is needed for xdp support." "$LINENO" 5 +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing cap_set_proc" >&5 +printf %s "checking for library containing cap_set_proc... " >&6; } +if test ${ac_cv_search_cap_set_proc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char cap_set_proc (); +int +main (void) +{ +return cap_set_proc (); + ; + return 0; +} +_ACEOF +for ac_lib in '' cap +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_cap_set_proc=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_cap_set_proc+y} +then : + break +fi +done +if test ${ac_cv_search_cap_set_proc+y} +then : + +else $as_nop + ac_cv_search_cap_set_proc=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_cap_set_proc" >&5 +printf "%s\n" "$ac_cv_search_cap_set_proc" >&6; } +ac_res=$ac_cv_search_cap_set_proc +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else $as_nop + as_fn_error $? "Cannot find libcap, but is needed for xdp support." "$LINENO" 5 +fi + + + # Using ARG_VAR here because AC_PROG_xxx doesn't exist for CLANG and LLC + + + # CHECK_PROG will not overwrite a variable if it is already provided by the user on the commandline + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CLANG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CLANG"; then + ac_cv_prog_CLANG="$CLANG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CLANG="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CLANG=$ac_cv_prog_CLANG +if test -n "$CLANG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CLANG" >&5 +printf "%s\n" "$CLANG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + # Extract the first word of "llc", so it can be a program name with args. +set dummy llc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_LLC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$LLC"; then + ac_cv_prog_LLC="$LLC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_LLC="llc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LLC=$ac_cv_prog_LLC +if test -n "$LLC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLC" >&5 +printf "%s\n" "$LLC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test "$CLANG" = "" && as_fn_error $? "Cannot find clang, but is needed for xdp support." "$LINENO" 5 + test "$LLC" = "" && as_fn_error $? "Cannot find llc, but is needed for xdp support." "$LINENO" 5 + + + test "$BPF_CFLAGS" = "" && BPF_CFLAGS="-Wall -Wextra -Wconversion -Werror" + + xdp_targets="xdp-dns-redirect_kern.o xdp-dns-redirect_kern_pinned.o" + + + xdp="xx" + ;; + no|*) + xdp="" + ;; +esac + # check for dnstap if requested # Check whether --enable-dnstap was given. @@ -11492,7 +11866,7 @@ if test ${enable_dnstap+y} then : enableval=$enable_dnstap; opt_dnstap=$enableval else $as_nop - opt_dnstap=no + opt_dnstap=yes fi @@ -11507,7 +11881,55 @@ fi if test "x$opt_dnstap" != "xno"; then - # Extract the first word of "protoc-c", so it can be a program name with args. + # Extract the first word of "protoc", so it can be a program name with args. +set dummy protoc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PROTOC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PROTOC in + [\\/]* | ?:[\\/]*) + ac_cv_path_PROTOC="$PROTOC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PROTOC="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PROTOC=$ac_cv_path_PROTOC +if test -n "$PROTOC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PROTOC" >&5 +printf "%s\n" "$PROTOC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + # 'protoc-c' is deprecated. We use 'protoc' instead. If it can not be + # found, try 'protoc-c'. + if test -z "$PROTOC"; then + # Extract the first word of "protoc-c", so it can be a program name with args. set dummy protoc-c; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } @@ -11552,10 +11974,84 @@ printf "%s\n" "no" >&6; } fi + else + PROTOC_C="$PROTOC" + fi if test -z "$PROTOC_C"; then - as_fn_error $? "The protoc-c program was not found. Please install protobuf-c!" "$LINENO" 5 + as_fn_error $? "The protoc or protoc-c program was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c to provide protoc or protoc-c" "$LINENO" 5 fi + # Check for protoc-gen-c plugin + # Extract the first word of "protoc-gen-c", so it can be a program name with args. +set dummy protoc-gen-c; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PROTOC_GEN_C+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PROTOC_GEN_C in + [\\/]* | ?:[\\/]*) + ac_cv_path_PROTOC_GEN_C="$PROTOC_GEN_C" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PROTOC_GEN_C="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PROTOC_GEN_C=$ac_cv_path_PROTOC_GEN_C +if test -n "$PROTOC_GEN_C"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PROTOC_GEN_C" >&5 +printf "%s\n" "$PROTOC_GEN_C" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + if test -z "$PROTOC_GEN_C"; then + as_fn_error $? "The protoc-gen-c plugin was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c-compiler to provide protoc-gen-c" "$LINENO" 5 + fi + + # Test that protoc-gen-c actually works + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if protoc-gen-c plugin works" >&5 +printf %s "checking if protoc-gen-c plugin works... " >&6; } + cat > conftest.proto << EOF +syntax = "proto2"; +message TestMessage { + optional string test_field = 1; +} +EOF + if $PROTOC_C --c_out=. conftest.proto >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h + as_fn_error $? "The protoc-gen-c plugin is not working properly. Please ensure protobuf-c-compiler is properly installed" "$LINENO" 5 + fi + + # Check whether --with-protobuf-c was given. if test ${with_protobuf_c+y} then : @@ -11650,7 +12146,7 @@ then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else $as_nop - as_fn_error $? "The fstrm library was not found. Please install fstrm!" "$LINENO" 5 + as_fn_error $? "The fstrm library was not found. It is needed for dnstap, use --disable-dnstap, or install fstrm-devel" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5 @@ -11711,7 +12207,7 @@ then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else $as_nop - as_fn_error $? "The protobuf-c library was not found. Please install protobuf-c!" "$LINENO" 5 + as_fn_error $? "The protobuf-c library was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c" "$LINENO" 5 fi @@ -11732,7 +12228,9 @@ printf "%s\n" "#define DNSTAP_SOCKET_PAT DNSTAP_OBJ="dnstap.o dnstap_collector.o dnstap.pb-c.o" - dnstap_config="dnstap/dnstap_config.h" + dnstap_config="dnstap/dnstap_config.h.tmp:dnstap/dnstap_config.h.in" + dnstap_config_tmp="dnstap/dnstap_config.h.tmp" + dnstap_config_out="dnstap/dnstap_config.h" else @@ -11886,6 +12384,9 @@ 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 : @@ -12643,7 +13144,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.11.0, which was +This file was extended by NSD $as_me 4.13.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12707,7 +13208,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.11.0 +NSD config.status 4.13.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" @@ -13562,3 +14063,17 @@ if test -n "$ac_unrecognized_opts" && te printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi +# If dnstap config has changed, overwrite it. +if test -n "$dnstap_config"; then + if test ! -f "$dnstap_config_out"; then + mv "$dnstap_config_tmp" "$dnstap_config_out" || as_fn_error $? "Could not create $dnstap_config_out" "$LINENO" 5 + else if diff "$dnstap_config_out" "$dnstap_config_tmp" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: In $srcdir: $dnstap_config_out is unchanged" >&5 +printf "%s\n" "$as_me: In $srcdir: $dnstap_config_out is unchanged" >&6;} + rm -f "$dnstap_config_tmp" + else + rm -f "$dnstap_config_out" + mv "$dnstap_config_tmp" "$dnstap_config_out" || as_fn_error $? "Could not create $dnstap_config_out" "$LINENO" 5 + fi + fi +fi Index: configure.ac =================================================================== RCS file: /cvs/src/usr.sbin/nsd/configure.ac,v diff -u -p -r1.61 configure.ac --- configure.ac 3 Sep 2025 18:46:48 -0000 1.61 +++ configure.ac 3 Sep 2025 19:38:49 -0000 @@ -7,7 +7,7 @@ sinclude(dnstap/dnstap.m4) # autoconf-2.70 is needed for @runstatedir@ AC_PREREQ([2.70]) -AC_INIT([NSD],[4.11.0],[https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl]) +AC_INIT([NSD],[4.13.0],[https://github.com/NLnetLabs/nsd/issues or nsd-bugs@nlnetlabs.nl]) AC_CONFIG_HEADERS([config.h]) # @@ -82,6 +82,9 @@ AC_SUBST(logfile) # Database directory # dbdir=${localstatedir}/db/nsd +AC_ARG_WITH([dbdir], + AS_HELP_STRING([--with-dbdir=dir],[Base directory for the xfrd zone timer state file, the zone list file and the cookie secrets file]), + [dbdir=$withval]) # # Determine the pidfile location. Check if /var/run exists, if so set pidfile @@ -138,6 +141,11 @@ AC_ARG_WITH([xfrdir], AS_HELP_STRING([-- AC_DEFINE_UNQUOTED(XFRDIR, ["`eval echo $xfrdir`"], [Pathname to where the NSD transfer dir is created.]) AC_SUBST(xfrdir) +sharedfilesdir=${datarootdir}/nsd +AC_ARG_WITH([sharedfilesdir], AS_HELP_STRING([--with-sharedfilesdir=dir],[NSD shared files directory]), [sharedfilesdir=$withval]) +AC_DEFINE_UNQUOTED(SHAREDFILESDIR, ["`eval echo $sharedfilesdir`"], [NSD shared files dir]) +AC_SUBST(sharedfilesdir) + # nsd sbin location. tmpinstantiate execprefix with defaults if not yet done. if test "x${exec_prefix}" = "xNONE"; then if test "x${prefix}" = "xNONE"; then exec_prefix="$ac_default_prefix" @@ -493,8 +501,18 @@ You can restart ./configure --with-libev AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51) AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00) + + # prometheus metrics depend on libevent 2.0 and later, and is therefore + # only enabled when the required version is found and used + AC_CHECK_FUNCS([evhttp_free], [ + AC_DEFINE_UNQUOTED([USE_METRICS], [], [Define this to expose NSD statistics via a prometheus metrics HTTP endpoint.]) + AC_DEFINE_UNQUOTED([NSD_METRICS_PORT], [9100], [Define the default metrics HTTP endpoint port.]) + ], [ + AC_MSG_NOTICE([disabling prometheus metrics]) + ]) else AC_DEFINE(USE_MINI_EVENT, 1, [Define if you want to use internal select based events]) + AC_MSG_NOTICE([Prometheus metrics are disabled with the builtin libevent alternative]) fi # Checks for header files. @@ -976,24 +994,24 @@ case "$enable_ipv6" in ;; esac -AC_ARG_ENABLE(bind8-stats, AS_HELP_STRING([--enable-bind8-stats],[Enables BIND8 like NSTATS & XSTATS and statistics in nsd-control])) +AC_ARG_ENABLE(bind8-stats, AS_HELP_STRING([--disable-bind8-stats],[Disable BIND8 like NSTATS & XSTATS and statistics in nsd-control])) case "$enable_bind8_stats" in - yes|'') - AC_DEFINE_UNQUOTED([BIND8_STATS], [], [Define this to enable BIND8 like NSTATS & XSTATS.]) + no) ;; - no|*) + yes|*) + AC_DEFINE_UNQUOTED([BIND8_STATS], [], [Define this to enable BIND8 like NSTATS & XSTATS.]) ;; esac -AC_ARG_ENABLE(zone-stats, AS_HELP_STRING([--enable-zone-stats],[Enable per-zone statistics gathering (needs --enable-bind8-stats)])) +AC_ARG_ENABLE(zone-stats, AS_HELP_STRING([--disable-zone-stats],[Disable per-zone statistics gathering (if enabled, it needs bind8-stats)])) case "$enable_zone_stats" in - yes) + no) + ;; + yes|*) AC_DEFINE_UNQUOTED([USE_ZONE_STATS], [], [Define this to enable per-zone statistics gathering.]) AC_DEFINE_UNQUOTED([BIND8_STATS], [], [Define this to enable BIND8 like NSTATS & XSTATS.]) ;; - no|''|*) - ;; esac AC_ARG_ENABLE(checking, AS_HELP_STRING([--enable-checking],[Enable internal runtime checks])) @@ -1023,28 +1041,24 @@ AC_ARG_ENABLE(memclean, AS_HELP_STRING([ if test "$enable_memclean" = "yes"; then AC_DEFINE_UNQUOTED([MEMCLEAN], [1], [Define this to cleanup memory at exit (eg. for valgrind, etc.)]) fi -AC_ARG_ENABLE(ratelimit, AS_HELP_STRING([--enable-ratelimit],[Enable rate limiting])) +AC_ARG_ENABLE(ratelimit, AS_HELP_STRING([--disable-ratelimit],[Disable rate limiting])) case "$enable_ratelimit" in - yes) - AC_DEFINE_UNQUOTED([RATELIMIT], [], [Define this to enable rate limiting.]) - dnl causes awk to not match the exclusion start marker. - ratelimit="xx" + no) ;; - no|*) - ratelimit="" + yes|*) + AC_DEFINE_UNQUOTED([RATELIMIT], [], [Define this to enable rate limiting.]) ;; esac -AC_SUBST(ratelimit) -AC_ARG_ENABLE(ratelimit-default-is-off, AS_HELP_STRING([--enable-ratelimit-default-is-off],[Enable this to set default of ratelimit to off (enable in nsd.conf), otherwise ratelimit is enabled by default if --enable-ratelimit is enabled])) +AC_ARG_ENABLE(ratelimit-default-is-off, AS_HELP_STRING([--disable-ratelimit-default-is-off],[Disable this to set default of ratelimit to on (this controls the default, ratelimits can be enabled and disabled in nsd.conf)])) case "$enable_ratelimit_default_is_off" in - yes) + no) + ratelimit_default="on" + ;; + yes|*) AC_DEFINE_UNQUOTED([RATELIMIT_DEFAULT_OFF], [], [Define this to set ratelimit to off by default.]) ratelimit_default="off" ;; - no|*) - ratelimit_default="on" - ;; esac AC_SUBST(ratelimit_default) @@ -1084,7 +1098,7 @@ if test x$HAVE_SSL = x"yes"; then SSL_LIBS="-lssl" AC_SUBST(SSL_LIBS) AC_CHECK_HEADERS([openssl/ssl.h openssl/err.h openssl/rand.h openssl/ocsp.h openssl/core_names.h openssl/x509v3.h],,, [AC_INCLUDES_DEFAULT]) - AC_CHECK_FUNCS([HMAC_CTX_reset HMAC_CTX_new EVP_cleanup ERR_load_crypto_strings OPENSSL_init_crypto CRYPTO_memcmp EC_KEY_new_by_curve_name EVP_MAC_CTX_new EVP_MAC_CTX_set_params EVP_MAC_CTX_get_mac_size SHA1_Init ASN1_STRING_get0_data]) + AC_CHECK_FUNCS([HMAC_CTX_reset HMAC_CTX_new EVP_cleanup ERR_load_crypto_strings OPENSSL_init_crypto CRYPTO_memcmp EC_KEY_new_by_curve_name EVP_MAC_CTX_new EVP_MAC_CTX_set_params EVP_MAC_CTX_get_mac_size SHA1_Init ASN1_STRING_get0_data EVP_PKEY_get0_type_name]) if test "$ac_cv_func_SHA1_Init" = "yes"; then ACX_FUNC_DEPRECATED([SHA1_Init], [(void)SHA1_Init(NULL);], [ #include @@ -1187,6 +1201,37 @@ case "$enable_packed" in ;; esac +AC_ARG_ENABLE(xdp, AS_HELP_STRING([--enable-xdp],[Enable XDP support.])) +case "$enable_xdp" in + yes) + AC_DEFINE_UNQUOTED([USE_XDP], [], [Define this to enable the use of AF_XDP sockets.]) + + AC_SEARCH_LIBS(xdp_program__open_file, [xdp],, [AC_MSG_ERROR([Cannot find libxdp, but is needed for xdp support.])]) + AC_SEARCH_LIBS(bpf_map__fd, [bpf],, [AC_MSG_ERROR([Cannot find libbpf, but is needed for xdp support.])]) + AC_SEARCH_LIBS(cap_set_proc, [cap],, [AC_MSG_ERROR([Cannot find libcap, but is needed for xdp support.])]) + + # Using ARG_VAR here because AC_PROG_xxx doesn't exist for CLANG and LLC + AC_ARG_VAR(CLANG, [location of clang compiler (only needed for xdp)]) + AC_ARG_VAR(LLC, [location of LLVM static compiler (only needed for xdp)]) + # CHECK_PROG will not overwrite a variable if it is already provided by the user on the commandline + AC_CHECK_PROG(CLANG, clang, clang) + AC_CHECK_PROG(LLC, llc, llc) + test "$CLANG" = "" && AC_MSG_ERROR([Cannot find clang, but is needed for xdp support.]) + test "$LLC" = "" && AC_MSG_ERROR([Cannot find llc, but is needed for xdp support.]) + + AC_ARG_VAR(BPF_CFLAGS, [The list of arguments passed to the BPF compiler]) + test "$BPF_CFLAGS" = "" && BPF_CFLAGS="-Wall -Wextra -Wconversion -Werror" + + xdp_targets="xdp-dns-redirect_kern.o xdp-dns-redirect_kern_pinned.o" + AC_SUBST(xdp_targets) + + xdp="xx" + ;; + no|*) + xdp="" + ;; +esac +AC_SUBST(xdp) # check for dnstap if requested dt_DNSTAP([${localstatedir}/run/nsd-dnstap.sock], [ @@ -1200,7 +1245,9 @@ dt_DNSTAP([${localstatedir}/run/nsd-dnst AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_collector.c"]) AC_SUBST([DNSTAP_OBJ], ["dnstap.o dnstap_collector.o dnstap.pb-c.o"]) - dnstap_config="dnstap/dnstap_config.h" + dnstap_config="dnstap/dnstap_config.h.tmp:dnstap/dnstap_config.h.in" + dnstap_config_tmp="dnstap/dnstap_config.h.tmp" + dnstap_config_out="dnstap/dnstap_config.h" ], [ AC_SUBST([ENABLE_DNSTAP], [0]) @@ -1444,5 +1491,18 @@ AC_ARG_ENABLE(westmere, AS_HELP_STRING([ AC_ARG_ENABLE(haswell, AS_HELP_STRING([--disable-haswell], [Disable Haswell (AVX2) parser kernel])) AC_CONFIG_SUBDIRS([simdzone]) AC_OUTPUT +# If dnstap config has changed, overwrite it. +if test -n "$dnstap_config"; then + if test ! -f "$dnstap_config_out"; then + mv "$dnstap_config_tmp" "$dnstap_config_out" || AC_MSG_ERROR([Could not create $dnstap_config_out]) + else if diff "$dnstap_config_out" "$dnstap_config_tmp" >/dev/null 2>&1; then + AC_MSG_NOTICE([In $srcdir: $dnstap_config_out is unchanged]) + rm -f "$dnstap_config_tmp" + else + rm -f "$dnstap_config_out" + mv "$dnstap_config_tmp" "$dnstap_config_out" || AC_MSG_ERROR([Could not create $dnstap_config_out]) + fi + fi +fi m4_unquote( _m4_defn([_m4_wrap_text])_m4_popdef([_m4_wrap_text])) Index: difffile.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/difffile.c,v diff -u -p -r1.23 difffile.c --- difffile.c 3 Sep 2025 18:46:48 -0000 1.23 +++ difffile.c 3 Sep 2025 19:38:49 -0000 @@ -13,6 +13,7 @@ #include #include #include +#include #include "difffile.h" #include "xfrd-disk.h" #include "util.h" @@ -758,10 +759,10 @@ delete_RR(namedb_type* db, const dname_t rrset->rr_count-1]) zone->nsec3_param = &rrset->rrs[rrnum]; else - zone->nsec3_param = - (void*)zone->nsec3_param - -(void*)rrs_orig + - (void*)rrset->rrs; + zone->nsec3_param = (void*) + ((char*)zone->nsec3_param + -(char*)rrs_orig + + (char*)rrset->rrs); } #endif /* NSEC3 */ rrset->rr_count --; @@ -868,8 +869,8 @@ add_RR(namedb_type* db, const dname_type 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*)zone->nsec3_param - - (void*)rrs_old + (void*)rrset->rrs; + zone->nsec3_param = (void*)((char*)zone->nsec3_param - + (char*)rrs_old + (char*)rrset->rrs); } #endif /* NSEC3 */ } @@ -994,7 +995,7 @@ static int apply_ixfr(nsd_type* nsd, FILE *in, uint32_t serialno, uint32_t seq_nr, uint32_t seq_total, int* is_axfr, int* delete_mode, int* rr_count, - struct zone* zone, int* bytes, + struct zone* zone, uint64_t* bytes, int* softfail, struct ixfr_store* ixfr_store) { uint32_t msglen, checklen, pkttype; @@ -1287,7 +1288,7 @@ apply_ixfr_for_zone(nsd_type* nsd, zone_ uint32_t time_end_1, time_start_1; uint8_t committed; uint32_t i; - int num_bytes = 0; + uint64_t num_bytes = 0; assert(zone); /* read zone name and serial */ @@ -1412,7 +1413,7 @@ apply_ixfr_for_zone(nsd_type* nsd, zone_ double elapsed = (double)(time_end_0 - time_start_0)+ (double)((double)time_end_1 -(double)time_start_1) / 1000000.0; - VERBOSITY(1, (LOG_INFO, "zone %s %s of %d bytes in %g seconds", + VERBOSITY(1, (LOG_INFO, "zone %s %s of %"PRIu64" bytes in %g seconds", zone_buf, log_buf, num_bytes, elapsed)); } } @@ -1911,6 +1912,9 @@ task_process_add_zone(struct nsd* nsd, u log_msg(LOG_ERR, "can not add zone %s %s", zname, pname); return; } + /* zdname is not used by the zone allocation. */ + region_recycle(nsd->db->region, (void*)zdname, + dname_total_size(zdname)); z->zonestatid = (unsigned)task->yesno; /* if zone is empty, attempt to read the zonefile from disk (if any) */ if(!z->soa_rrset && z->opts->pattern->zonefile) { Index: dname.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/dname.c,v diff -u -p -r1.16 dname.c --- dname.c 3 Sep 2025 18:46:48 -0000 1.16 +++ dname.c 3 Sep 2025 19:38:49 -0000 @@ -35,7 +35,7 @@ dname_make(region_type *region, const ui assert(name); while (1) { - if (label_is_pointer(label)) + if (!label_is_normal(label)) return NULL; label_offsets[label_count] = (uint8_t) (label - name); @@ -44,6 +44,8 @@ dname_make(region_type *region, const ui if (label_is_root(label)) break; + if (name_size > MAXDOMAINLEN) + return NULL; label = label_next(label); } Index: dns.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/dns.c,v diff -u -p -r1.22 dns.c --- dns.c 3 Sep 2025 18:46:48 -0000 1.22 +++ dns.c 3 Sep 2025 19:38:49 -0000 @@ -116,7 +116,7 @@ static rrtype_descriptor_type rrtype_des { RDATA_ZF_NSAP } }, /* 23 */ { TYPE_NSAP_PTR, "NSAP-PTR", 1, 1, - { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, + { RDATA_WF_TEXT }, { RDATA_ZF_UNQUOTED } }, /* 24 */ { TYPE_SIG, "SIG", 9, 9, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG, @@ -152,16 +152,16 @@ static rrtype_descriptor_type rrtype_des { RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_BINARY }, { RDATA_ZF_DNAME, RDATA_ZF_NXT } }, /* 31 */ - { 31, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { TYPE_EID, "EID", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_HEX } }, /* 32 */ - { 32, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { TYPE_NIMLOC, "NIMLOC", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_HEX } }, /* 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 } }, /* 34 */ - { 34, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { TYPE_ATMA, "ATMA", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_ATMA } }, /* 35 */ { TYPE_NAPTR, "NAPTR", 6, 6, { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_TEXT, RDATA_WF_TEXT, @@ -183,7 +183,9 @@ static rrtype_descriptor_type rrtype_des { TYPE_DNAME, "DNAME", 1, 1, { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 40 */ - { 40, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 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 } }, @@ -363,7 +365,9 @@ static rrtype_descriptor_type rrtype_des { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM, RDATA_ZF_BASE64 } }, /* 58 - TALINK */ - { 58, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 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 }, @@ -485,7 +489,11 @@ static rrtype_descriptor_type rrtype_des , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM } }, /* 66 */ - { 66, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 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 */ @@ -888,15 +896,23 @@ static rrtype_descriptor_type rrtype_des { RDATA_WF_TEXTS }, { RDATA_ZF_TEXTS } }, /* 259 - DOA */ - { 259, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 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 */ - { 260, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 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, Index: dns.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/dns.h,v diff -u -p -r1.21 dns.h --- dns.h 3 Sep 2025 18:46:48 -0000 1.21 +++ dns.h 3 Sep 2025 19:38:49 -0000 @@ -104,7 +104,7 @@ typedef enum nsd_rc nsd_rc_type; #define TYPE_ISDN 20 /* RFC1183 */ #define TYPE_RT 21 /* RFC1183 */ #define TYPE_NSAP 22 /* RFC1706 (deprecated by RFC9121) */ -#define TYPE_NSAP_PTR 23 /* RFC1348 (deprecated by RFC9121)*/ +#define TYPE_NSAP_PTR 23 /* RFC1348 (deprecated by RFC9121) */ #define TYPE_SIG 24 /* 2535typecode */ #define TYPE_KEY 25 /* 2535typecode */ #define TYPE_PX 26 /* RFC2163 */ @@ -112,15 +112,16 @@ typedef enum nsd_rc nsd_rc_type; #define TYPE_AAAA 28 /* ipv6 address */ #define TYPE_LOC 29 /* LOC record RFC1876 */ #define TYPE_NXT 30 /* 2535typecode */ - +#define TYPE_EID 31 /* draft-ietf-nimrod-dns-01 */ +#define TYPE_NIMLOC 32 /* draft-ietf-nimrod-dns-01 */ #define TYPE_SRV 33 /* SRV record RFC2782 */ - +#define TYPE_ATMA 34 /* ATM Address */ #define TYPE_NAPTR 35 /* RFC2915 */ #define TYPE_KX 36 /* RFC2230 Key Exchange Delegation Record */ #define TYPE_CERT 37 /* RFC2538 */ #define TYPE_A6 38 /* RFC2874 */ #define TYPE_DNAME 39 /* RFC2672 */ - +#define TYPE_SINK 40 /* draft-eastlake-kitchen-sink */ #define TYPE_OPT 41 /* Pseudo OPT record... */ #define TYPE_APL 42 /* RFC3123 */ #define TYPE_DS 43 /* RFC 4033, 4034, and 4035 */ @@ -137,7 +138,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_CDS 59 /* RFC 7344 */ #define TYPE_CDNSKEY 60 /* RFC 7344 */ #define TYPE_OPENPGPKEY 61 /* RFC 7929 */ @@ -145,6 +146,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_SPF 99 /* RFC 4408 */ @@ -164,10 +166,12 @@ typedef enum nsd_rc nsd_rc_type; #define TYPE_URI 256 /* RFC 7553 */ #define TYPE_CAA 257 /* RFC 6844 */ #define TYPE_AVC 258 /* AVC/avc-completed-template */ - +#define TYPE_DOA 259 /* draft-durand-doa-over-dns */ +#define TYPE_AMTRELAY 260 /* RFC 8777 */ #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_TA 32768 /* http://www.watson.org/~weiler/INI1999-19.pdf */ #define TYPE_DLV 32769 /* RFC 4431 */ @@ -214,6 +218,7 @@ enum rdata_wireformat 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. */ @@ -227,7 +232,8 @@ enum rdata_wireformat RDATA_WF_EUI64, /* 64-bit address. */ RDATA_WF_LONG_TEXT, /* Long (>255) text string. */ RDATA_WF_SVCPARAM, /* SvcParam [=] */ - RDATA_WF_HIP /* HIP rdata up to the Rendezvous Servers */ + 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; @@ -243,6 +249,7 @@ enum rdata_zoneformat 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. */ @@ -270,6 +277,9 @@ enum rdata_zoneformat RDATA_ZF_TAG, /* A sequence of letters and numbers. */ RDATA_ZF_SVCPARAM, /* SvcParam [=] */ 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 enum rdata_zoneformat rdata_zoneformat_type; @@ -291,7 +301,7 @@ typedef struct rrtype_descriptor rrtype_ * * CLA + 1 */ -#define RRTYPE_DESCRIPTORS_LENGTH (TYPE_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); Index: edns.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/edns.h,v diff -u -p -r1.6 edns.h --- edns.h 3 Sep 2025 18:46:48 -0000 1.6 +++ edns.h 3 Sep 2025 19:38:49 -0000 @@ -28,11 +28,11 @@ struct query; struct edns_data { - char ok[OPT_LEN]; - char error[OPT_LEN]; - char rdata_none[OPT_RDATA]; - char nsid[OPT_HDR]; - char cookie[OPT_HDR]; + unsigned char ok[OPT_LEN]; + unsigned char error[OPT_LEN]; + unsigned char rdata_none[OPT_RDATA]; + unsigned char nsid[OPT_HDR]; + unsigned char cookie[OPT_HDR]; }; typedef struct edns_data edns_data_type; Index: install-sh =================================================================== RCS file: /cvs/src/usr.sbin/nsd/install-sh,v diff -u -p -r1.2 install-sh --- install-sh 5 Nov 2015 22:58:42 -0000 1.2 +++ install-sh 3 Sep 2025 19:38:49 -0000 @@ -1,251 +1,541 @@ #!/bin/sh -# # install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). + +scriptversion=2023-11-23.18; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -# Copyright 1991 by the Massachusetts Institute of Technology +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. # -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. +# +# FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - +# from scratch. -# set DOITPROG to echo to test this script +tab=' ' +nl=' +' +IFS=" $tab$nl" -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" +# Set DOITPROG to "echo" to test this script. +doit=${DOITPROG-} +doit_exec=${doit:-exec} -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done +stripcmd= -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi +src= +dst= +dir_arg= +dst_arg= -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else +copy_on_change=false +is_target_a_directory=possibly -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic +Options: + --help display this help and exit. + --version display version info and exit. - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" +If -S is not specified, no backups are attempted. -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi +Report bugs to . +GNU Automake home page: . +General help using GNU software: ." - pathcomp="${pathcomp}/" -done -fi +while test $# -ne 0; do + case $1 in + -c) ;; -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else + -C) copy_on_change=true;; -# If we're going to rename the final executable, determine the name now. + -d) dir_arg=true;; - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi + -g) chgrpcmd="$chgrpprog $2" + shift;; -# don't allow the sed command to completely eliminate the filename + --help) echo "$usage"; exit $?;; - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; -# Make a temp file name in the proper directory. + -p) cpprog="$cpprog -p";; - dsttmp=$dstdir/#inst.$$# + -s) stripcmd=$stripprog;; -# Move or copy the file name to the temp name + -S) backupsuffix="$2" + shift;; - $doit $instcmd $src $dsttmp && + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; - trap "rm -f ${dsttmp}" 0 && + -T) is_target_a_directory=never;; -# and set any options; do chmod last to preserve setuid bits + --version) echo "$0 $scriptversion"; exit $?;; -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. + --) shift + break;; - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + -*) echo "$0: invalid option: $1" >&2 + exit 1;; -# Now rename the file to the real destination. + *) break;; + esac + shift +done - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. -fi && +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done -exit 0 +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: Index: ipc.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/ipc.c,v diff -u -p -r1.13 ipc.c --- ipc.c 3 Sep 2025 18:46:48 -0000 1.13 +++ ipc.c 3 Sep 2025 19:38:49 -0000 @@ -290,7 +290,7 @@ parent_handle_child_command(netio_type * (struct main_ipc_handler_data*)handler->user_data; /* do a nonblocking write to the child if it is ready. */ - if (event_types & NETIO_EVENT_WRITE) { + if ((event_types & NETIO_EVENT_WRITE)) { if(data->child->need_to_send_STATS && !data->child->need_to_exit) { send_stat_to_child(data, handler->fd); Index: ixfr.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/ixfr.c,v diff -u -p -r1.4 ixfr.c --- ixfr.c 3 Sep 2025 18:46:48 -0000 1.4 +++ ixfr.c 3 Sep 2025 19:38:49 -0000 @@ -200,12 +200,16 @@ static size_t dname_length(const uint8_t 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; } @@ -353,6 +357,9 @@ static int ixfr_write_rr_pkt(struct quer 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; @@ -1348,6 +1355,8 @@ void ixfr_store_delrr(struct ixfr_store* uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet, uint16_t rrlen, struct region* temp_region) { + if(ixfr_store->cancelled) + return; ixfr_store_putrr(ixfr_store, dname, type, klass, ttl, packet, rrlen, temp_region, &ixfr_store->data->del, &ixfr_store->data->del_len, &ixfr_store->del_capacity); @@ -1357,6 +1366,8 @@ void ixfr_store_addrr(struct ixfr_store* uint16_t type, uint16_t klass, uint32_t ttl, struct buffer* packet, uint16_t rrlen, struct region* temp_region) { + if(ixfr_store->cancelled) + return; ixfr_store_putrr(ixfr_store, dname, type, klass, ttl, packet, rrlen, temp_region, &ixfr_store->data->add, &ixfr_store->data->add_len, &ixfr_store->add_capacity); @@ -2243,6 +2254,11 @@ void ixfr_write_to_file(struct zone* zon static void domain_table_delete(struct domain_table* table, struct domain* domain) { + /* first adjust the number list so that domain is the last one */ + numlist_make_last(table, domain); + /* pop off the domain from the number list */ + (void)numlist_pop_last(table); + #ifdef USE_RADIX_TREE radix_delete(table->nametree, domain->rnode); #else @@ -2270,10 +2286,10 @@ static int can_del_temp_domain(struct do /* delete temporary domain */ static void ixfr_temp_deldomain(struct domain_table* temptable, - struct domain* domain) + struct domain* domain, struct domain* avoid) { struct domain* p; - if(!can_del_temp_domain(domain)) + if(domain == avoid || !can_del_temp_domain(domain)) return; p = domain->parent; /* see if this domain is someones wildcard-child-closest-match, @@ -2286,7 +2302,7 @@ static void ixfr_temp_deldomain(struct d domain_table_delete(temptable, domain); while(p) { struct domain* up = p->parent; - if(!can_del_temp_domain(p)) + if(p == avoid || !can_del_temp_domain(p)) break; if(p->parent && p->parent->wildcard_child_closest_match == p) p->parent->wildcard_child_closest_match = @@ -2342,7 +2358,7 @@ static void clear_temp_table_of_rr(struc rdata_atom_domain(rr->rdatas[i]); domain->usage --; if(domain != tempzone->apex && domain->usage == 0) - ixfr_temp_deldomain(temptable, domain); + ixfr_temp_deldomain(temptable, domain, rr->owner); } } @@ -2355,7 +2371,7 @@ static void clear_temp_table_of_rr(struc } else { rr->owner->rrsets = NULL; if(rr->owner->usage == 0) { - ixfr_temp_deldomain(temptable, rr->owner); + ixfr_temp_deldomain(temptable, rr->owner, NULL); } } } @@ -2457,13 +2473,14 @@ static int ixfr_data_readdel(struct ixfr return 0; } clear_temp_table_of_rr(temptable, tempzone, rr); - region_free_all(tempregion); /* check SOA and also serial, because there could be other * add and del sections from older versions collated, we can * see this del section end when it has the serial */ if(rr->type != TYPE_SOA && soa_rr_get_serial(rr) != data->newserial) { + region_free_all(tempregion); return 1; } + region_free_all(tempregion); ixfr_trim_capacity(&data->del, &data->del_len, &capacity); return 2; } @@ -2480,10 +2497,11 @@ static int ixfr_data_readadd(struct ixfr return 0; } clear_temp_table_of_rr(temptable, tempzone, rr); - region_free_all(tempregion); if(rr->type != TYPE_SOA || soa_rr_get_serial(rr) != data->newserial) { + region_free_all(tempregion); return 1; } + region_free_all(tempregion); ixfr_trim_capacity(&data->add, &data->add_len, &capacity); return 2; } Index: ixfrcreate.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/ixfrcreate.c,v diff -u -p -r1.4 ixfrcreate.c --- ixfrcreate.c 20 Dec 2023 17:29:01 -0000 1.4 +++ ixfrcreate.c 3 Sep 2025 19:38:49 -0000 @@ -1031,6 +1031,8 @@ static void ixfr_create_finishup(struct } if(append_mem) { ixfr_store_finish(store, nsd, log_buf); + } else { + ixfr_store_free(store); } } Index: metrics.c =================================================================== RCS file: metrics.c diff -N metrics.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ metrics.c 3 Sep 2025 19:38:49 -0000 @@ -0,0 +1,603 @@ +/* + * metrics.c -- prometheus metrics endpoint + * + * Copyright (c) 2001-2025, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ + +#include "config.h" + +#ifdef USE_METRICS + +#include +#include +#include +#include +#include +#include +#include + +#include "nsd.h" +#include "xfrd.h" +#include "options.h" +#include "remote.h" +#include "metrics.h" + +/** if you want zero to be inhibited in stats output. + * it omits zeroes for types that have no acronym and unused-rcodes */ +const int metrics_inhibit_zero = 1; + +/** + * list of connection accepting file descriptors + */ +struct metrics_acceptlist { + struct metrics_acceptlist* next; + int accept_fd; + char* ident; + struct daemon_metrics* metrics; +}; + +/** + * The metrics daemon state. + */ +struct daemon_metrics { + /** the master process for this metrics daemon */ + struct xfrd_state* xfrd; + /** commpoints for accepting HTTP connections */ + struct metrics_acceptlist* accept_list; + /** last time stats was reported */ + struct timeval stats_time, boot_time; + /** libevent http server */ + struct evhttp *http_server; +}; + +static void +metrics_http_callback(struct evhttp_request *req, void *p); + +struct daemon_metrics* +daemon_metrics_create(struct nsd_options* cfg) +{ + struct daemon_metrics* metrics = (struct daemon_metrics*)xalloc_zero( + sizeof(*metrics)); + assert(cfg->metrics_enable); + + /* and try to open the ports */ + if(!daemon_metrics_open_ports(metrics, cfg)) { + log_msg(LOG_ERR, "could not open metrics port"); + daemon_metrics_delete(metrics); + return NULL; + } + + if(gettimeofday(&metrics->boot_time, NULL) == -1) + log_msg(LOG_ERR, "gettimeofday: %s", strerror(errno)); + metrics->stats_time = metrics->boot_time; + + return metrics; +} + +void daemon_metrics_close(struct daemon_metrics* metrics) +{ + struct metrics_acceptlist *h, *nh; + if(!metrics) return; + + /* close listen sockets */ + h = metrics->accept_list; + while(h) { + nh = h->next; + close(h->accept_fd); + free(h->ident); + free(h); + h = nh; + } + metrics->accept_list = NULL; + + if (metrics->http_server) { + evhttp_free(metrics->http_server); + } +} + +void daemon_metrics_delete(struct daemon_metrics* metrics) +{ + if(!metrics) return; + daemon_metrics_close(metrics); + free(metrics); +} + +static int +create_tcp_accept_sock(struct addrinfo* addr, int* noproto) +{ +#if defined(SO_REUSEADDR) || (defined(INET6) && (defined(IPV6_V6ONLY) || defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU))) + int on = 1; +#endif + int s; + *noproto = 0; + if ((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) { +#if defined(INET6) + if (addr->ai_family == AF_INET6 && + errno == EAFNOSUPPORT) { + *noproto = 1; + log_msg(LOG_WARNING, "fallback to TCP4, no IPv6: not supported"); + return -1; + } +#endif /* INET6 */ + log_msg(LOG_ERR, "can't create a socket: %s", strerror(errno)); + return -1; + } +#ifdef SO_REUSEADDR + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + log_msg(LOG_ERR, "setsockopt(..., SO_REUSEADDR, ...) failed: %s", strerror(errno)); + } +#endif /* SO_REUSEADDR */ +#if defined(INET6) && defined(IPV6_V6ONLY) + if (addr->ai_family == AF_INET6 && + setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) + { + log_msg(LOG_ERR, "setsockopt(..., IPV6_V6ONLY, ...) failed: %s", strerror(errno)); + close(s); + return -1; + } +#endif + /* set it nonblocking */ + /* (StevensUNP p463), if tcp listening socket is blocking, then + it may block in accept, even if select() says readable. */ + if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { + log_msg(LOG_ERR, "cannot fcntl tcp: %s", strerror(errno)); + } + /* Bind it... */ + if (bind(s, (struct sockaddr *)addr->ai_addr, addr->ai_addrlen) != 0) { + log_msg(LOG_ERR, "can't bind tcp socket: %s", strerror(errno)); + close(s); + return -1; + } + /* Listen to it... */ + if (listen(s, TCP_BACKLOG_METRICS) == -1) { + log_msg(LOG_ERR, "can't listen: %s", strerror(errno)); + close(s); + return -1; + } + return s; +} + +/** + * Add and open a new metrics port + * @param metrics: metrics with result list. + * @param ip: ip str + * @param nr: port nr + * @param noproto_is_err: if lack of protocol support is an error. + * @return false on failure. + */ +static int +metrics_add_open(struct daemon_metrics* metrics, struct nsd_options* cfg, const char* ip, + int nr, int noproto_is_err) +{ + struct addrinfo hints; + struct addrinfo* res; + struct metrics_acceptlist* hl; + int noproto = 0; + int fd, r; + char port[15]; + snprintf(port, sizeof(port), "%d", nr); + port[sizeof(port)-1]=0; + memset(&hints, 0, sizeof(hints)); + assert(ip); + + if(ip[0] == '/') { + /* This looks like a local socket */ + fd = create_local_accept_sock(ip, &noproto); + /* + * Change socket ownership and permissions so users other + * than root can access it provided they are in the same + * group as the user we run as. + */ + if(fd != -1) { +#ifdef HAVE_CHOWN + if(chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1) { + VERBOSITY(3, (LOG_INFO, "cannot chmod metrics socket %s: %s", ip, strerror(errno))); + } + if (cfg->username && cfg->username[0] && + nsd.uid != (uid_t)-1) { + if(chown(ip, nsd.uid, nsd.gid) == -1) + VERBOSITY(2, (LOG_INFO, "cannot chown %u.%u %s: %s", + (unsigned)nsd.uid, (unsigned)nsd.gid, + ip, strerror(errno))); + } +#else + (void)cfg; +#endif + } + } else { + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + /* if we had no interface ip name, "default" is what we + * would do getaddrinfo for. */ + if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) { + log_msg(LOG_ERR, "metrics interface %s:%s getaddrinfo: %s %s", + ip, port, gai_strerror(r), +#ifdef EAI_SYSTEM + r==EAI_SYSTEM?(char*)strerror(errno):"" +#else + "" +#endif + ); + return 0; + } + + /* open fd */ + fd = create_tcp_accept_sock(res, &noproto); + freeaddrinfo(res); + } + + if(fd == -1 && noproto) { + if(!noproto_is_err) + return 1; /* return success, but do nothing */ + log_msg(LOG_ERR, "cannot open metrics interface %s %d : " + "protocol not supported", ip, nr); + return 0; + } + if(fd == -1) { + log_msg(LOG_ERR, "cannot open metrics interface %s %d", ip, nr); + return 0; + } + + /* alloc */ + hl = (struct metrics_acceptlist*)xalloc_zero(sizeof(*hl)); + hl->metrics = metrics; + hl->ident = strdup(ip); + if(!hl->ident) { + log_msg(LOG_ERR, "malloc failure"); + close(fd); + free(hl); + return 0; + } + hl->next = metrics->accept_list; + metrics->accept_list = hl; + + hl->accept_fd = fd; + return 1; +} + +int +daemon_metrics_open_ports(struct daemon_metrics* metrics, struct nsd_options* cfg) +{ + assert(cfg->metrics_enable && cfg->metrics_port); + if(cfg->metrics_interface) { + ip_address_option_type* p; + for(p = cfg->metrics_interface; p; p = p->next) { + if(!metrics_add_open(metrics, cfg, p->address, cfg->metrics_port, 1)) { + return 0; + } + } + } else { + /* defaults */ + if(cfg->do_ip6 && !metrics_add_open(metrics, cfg, "::1", cfg->metrics_port, 0)) { + return 0; + } + if(cfg->do_ip4 && + !metrics_add_open(metrics, cfg, "127.0.0.1", cfg->metrics_port, 1)) { + return 0; + } + } + return 1; +} + +void +daemon_metrics_attach(struct daemon_metrics* metrics, struct xfrd_state* xfrd) +{ + int fd; + struct metrics_acceptlist* p; + if(!metrics) return; + metrics->xfrd = xfrd; + + metrics->http_server = evhttp_new(xfrd->event_base); + for(p = metrics->accept_list; p; p = p->next) { + fd = p->accept_fd; + if (evhttp_accept_socket(metrics->http_server, fd)) { + log_msg(LOG_ERR, "metrics: cannot set http server to accept socket"); + } + + /* only handle requests to metrics_path, anything else returns 404 */ + evhttp_set_cb(metrics->http_server, + metrics->xfrd->nsd->options->metrics_path, + metrics_http_callback, p); + /* evhttp_set_gencb(metrics->http_server, metrics_http_callback_generic, p); */ + } +} + +/* Callback for handling the active http request to the specific URI */ +static void +metrics_http_callback(struct evhttp_request *req, void *p) +{ + struct evbuffer *reply = NULL; + struct daemon_metrics *metrics = ((struct metrics_acceptlist *)p)->metrics; + + /* currently only GET requests are supported/allowed */ + enum evhttp_cmd_type cmd = evhttp_request_get_command(req); + if (cmd != EVHTTP_REQ_GET /* && cmd != EVHTTP_REQ_HEAD */) { + evhttp_send_error(req, HTTP_BADMETHOD, 0); + return; + } + + reply = evbuffer_new(); + + if (!reply) { + evhttp_send_error(req, HTTP_INTERNAL, 0); + log_msg(LOG_ERR, "failed to allocate reply buffer\n"); + return; + } + + evhttp_add_header(evhttp_request_get_output_headers(req), + "Content-Type", "text/plain; version=0.0.4"); +#ifdef BIND8_STATS + process_stats(NULL, reply, metrics->xfrd, 1); + evhttp_send_reply(req, HTTP_OK, NULL, reply); + VERBOSITY(3, (LOG_INFO, "metrics operation completed, response sent")); +#else + evhttp_send_reply(req, HTTP_NOCONTENT, "No Content - Statistics disabled", reply); + log_msg(LOG_NOTICE, "metrics requested, but no stats enabled at compile time\n"); + (void)metrics; +#endif /* BIND8_STATS */ + + evbuffer_free(reply); +} + +#ifdef BIND8_STATS +/** print long number*/ +static int +print_longnum(struct evbuffer *buf, char* desc, uint64_t x) +{ + if(x > (uint64_t)1024*1024*1024) { + /*more than a Gb*/ + size_t front = (size_t)(x / (uint64_t)1000000); + size_t back = (size_t)(x % (uint64_t)1000000); + return evbuffer_add_printf(buf, "%s%lu%6.6lu\n", desc, + (unsigned long)front, (unsigned long)back); + } else { + return evbuffer_add_printf(buf, "%s%lu\n", desc, (unsigned long)x); + } +} + +static void +print_metric_help_and_type(struct evbuffer *buf, char *prefix, char *name, + char *help, char *type) +{ + evbuffer_add_printf(buf, "# HELP %s%s %s\n# TYPE %s%s %s\n", + prefix, name, help, prefix, name, type); +} + +static void +print_stat_block(struct evbuffer *buf, struct nsdst* st, + char *name) +{ + size_t i; + + const char* rcstr[] = {"NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", + "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET", "NXRRSET", "NOTAUTH", + "NOTZONE", "RCODE11", "RCODE12", "RCODE13", "RCODE14", "RCODE15", + "BADVERS" + }; + + char prefix[512] = {0}; + if (name) { + snprintf(prefix, sizeof(prefix), "nsd_zonestats_%s_", name); + } else { + snprintf(prefix, sizeof(prefix), "nsd_"); + } + + /* nsd_queries_by_type_total */ + print_metric_help_and_type(buf, prefix, "queries_by_type_total", + "Total number of queries received by type.", + "counter"); + for(i=0; i<= 255; i++) { + if(metrics_inhibit_zero && st->qtype[i] == 0 && + strncmp(rrtype_to_string(i), "TYPE", 4) == 0) + continue; + evbuffer_add_printf(buf, "%squeries_by_type_total{type=\"%s\"} %lu\n", + prefix, rrtype_to_string(i), (unsigned long)st->qtype[i]); + } + + /* nsd_queries_by_class_total */ + print_metric_help_and_type(buf, prefix, "queries_by_class_total", + "Total number of queries received by class.", + "counter"); + for(i=0; i<4; i++) { + if(metrics_inhibit_zero && st->qclass[i] == 0 && i != CLASS_IN) + continue; + evbuffer_add_printf(buf, "%squeries_by_class_total{class=\"%s\"} %lu\n", + prefix, rrclass_to_string(i), (unsigned long)st->qclass[i]); + } + + /* nsd_queries_by_opcode_total */ + print_metric_help_and_type(buf, prefix, "queries_by_opcode_total", + "Total number of queries received by opcode.", + "counter"); + for(i=0; i<6; i++) { + if(metrics_inhibit_zero && st->opcode[i] == 0 && i != OPCODE_QUERY) + continue; + evbuffer_add_printf(buf, "%squeries_by_opcode_total{opcode=\"%s\"} %lu\n", + prefix, opcode2str(i), (unsigned long)st->opcode[i]); + } + + /* nsd_queries_by_rcode_total */ + print_metric_help_and_type(buf, prefix, "queries_by_rcode_total", + "Total number of queries received by rcode.", + "counter"); + for(i=0; i<17; i++) { + if(metrics_inhibit_zero && st->rcode[i] == 0 && + i > RCODE_YXDOMAIN) /*NSD does not use larger*/ + continue; + evbuffer_add_printf(buf, "%squeries_by_rcode_total{rcode=\"%s\"} %lu\n", + prefix, rcstr[i], (unsigned long)st->rcode[i]); + } + + /* nsd_queries_by_transport_total */ + print_metric_help_and_type(buf, prefix, "queries_by_transport_total", + "Total number of queries received by transport.", + "counter"); + evbuffer_add_printf(buf, "%squeries_by_transport_total{transport=\"udp\"} %lu\n", prefix, (unsigned long)st->qudp); + evbuffer_add_printf(buf, "%squeries_by_transport_total{transport=\"udp6\"} %lu\n", prefix, (unsigned long)st->qudp6); + + /* nsd_queries_with_edns_total */ + print_metric_help_and_type(buf, prefix, "queries_with_edns_total", + "Total number of queries received with EDNS OPT.", + "counter"); + evbuffer_add_printf(buf, "%squeries_with_edns_total %lu\n", prefix, (unsigned long)st->edns); + + /* nsd_queries_with_edns_failed_total */ + print_metric_help_and_type(buf, prefix, "queries_with_edns_failed_total", + "Total number of queries received with EDNS OPT where EDNS parsing failed.", + "counter"); + evbuffer_add_printf(buf, "%squeries_with_edns_failed_total %lu\n", prefix, (unsigned long)st->ednserr); + + /* nsd_connections_total */ + print_metric_help_and_type(buf, prefix, "connections_total", + "Total number of connections.", + "counter"); + evbuffer_add_printf(buf, "%sconnections_total{transport=\"tcp\"} %lu\n", prefix, (unsigned long)st->ctcp); + evbuffer_add_printf(buf, "%sconnections_total{transport=\"tcp6\"} %lu\n", prefix, (unsigned long)st->ctcp6); + evbuffer_add_printf(buf, "%sconnections_total{transport=\"tls\"} %lu\n", prefix, (unsigned long)st->ctls); + evbuffer_add_printf(buf, "%sconnections_total{transport=\"tls6\"} %lu\n", prefix, (unsigned long)st->ctls6); + + /* nsd_xfr_requests_served_total */ + print_metric_help_and_type(buf, prefix, "xfr_requests_served_total", + "Total number of answered zone transfers.", + "counter"); + evbuffer_add_printf(buf, "%sxfr_requests_served_total{xfrtype=\"AXFR\"} %lu\n", prefix, (unsigned long)st->raxfr); + evbuffer_add_printf(buf, "%sxfr_requests_served_total{xfrtype=\"IXFR\"} %lu\n", prefix, (unsigned long)st->rixfr); + + /* nsd_queries_dropped_total */ + print_metric_help_and_type(buf, prefix, "queries_dropped_total", + "Total number of dropped queries.", + "counter"); + evbuffer_add_printf(buf, "%squeries_dropped_total %lu\n", prefix, (unsigned long)st->dropped); + + /* nsd_queries_rx_failed_total */ + print_metric_help_and_type(buf, prefix, "queries_rx_failed_total", + "Total number of queries where receive failed.", + "counter"); + evbuffer_add_printf(buf, "%squeries_rx_failed_total %lu\n", prefix, (unsigned long)st->rxerr); + + /* nsd_answers_tx_failed_total */ + print_metric_help_and_type(buf, prefix, "answers_tx_failed_total", + "Total number of answers where transmit failed.", + "counter"); + evbuffer_add_printf(buf, "%sanswers_tx_failed_total %lu\n", prefix, (unsigned long)st->txerr); + + /* nsd_answers_without_aa_total */ + print_metric_help_and_type(buf, prefix, "answers_without_aa_total", + "Total number of NOERROR answers without AA flag set.", + "counter"); + evbuffer_add_printf(buf, "%sanswers_without_aa_total %lu\n", prefix, (unsigned long)st->nona); + + /* nsd_answers_truncated_total */ + print_metric_help_and_type(buf, prefix, "answers_truncated_total", + "Total number of truncated answers.", + "counter"); + evbuffer_add_printf(buf, "%sanswers_truncated_total %lu\n", prefix, (unsigned long)st->truncated); +} + +#ifdef USE_ZONE_STATS +void +metrics_zonestat_print_one(struct evbuffer *buf, char *name, + struct nsdst *zst) +{ + char prefix[512] = {0}; + snprintf(prefix, sizeof(prefix), "nsd_zonestats_%s_", name); + + 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, + (unsigned long)(zst->qudp + zst->qudp6 + zst->ctcp + + zst->ctcp6 + zst->ctls + zst->ctls6)); + print_stat_block(buf, zst, name); +} +#endif /*USE_ZONE_STATS*/ + +void +metrics_print_stats(struct evbuffer *buf, xfrd_state_type *xfrd, + struct timeval *now, int clear, struct nsdst *st, + struct nsdst **zonestats, struct timeval *rc_stats_time) +{ + size_t i; + struct timeval elapsed, uptime; + + /* nsd_queries_total */ + print_metric_help_and_type(buf, "nsd_", "queries_total", + "Total number of queries received.", "counter"); + /*per CPU and total*/ + for(i=0; insd->child_count; i++) { + evbuffer_add_printf(buf, "nsd_queries_total{server=\"%d\"} %lu\n", + (int)i, (unsigned long)xfrd->nsd->children[i].query_count); + } + + print_stat_block(buf, st, NULL); + + /* uptime (in seconds) */ + timeval_subtract(&uptime, now, &xfrd->nsd->metrics->boot_time); + print_metric_help_and_type(buf, "nsd_", "time_up_seconds_total", + "Uptime since server boot in seconds.", "counter"); + evbuffer_add_printf(buf, "nsd_time_up_seconds_total %lu.%6.6lu\n", + (unsigned long)uptime.tv_sec, (unsigned long)uptime.tv_usec); + + /* time elapsed since last nsd-control stats reset (in seconds) */ + /* if remote-control is disabled aka rc_stats_time == NULL + * use metrics' stats_time */ + if (rc_stats_time) { + timeval_subtract(&elapsed, now, rc_stats_time); + } else { + timeval_subtract(&elapsed, now, &xfrd->nsd->metrics->stats_time); + } + print_metric_help_and_type(buf, "nsd_", "time_elapsed_seconds", + "Time since last statistics printout and " + "reset (by nsd-control stats) in seconds.", + "untyped"); + evbuffer_add_printf(buf, "nsd_time_elapsed_seconds %lu.%6.6lu\n", + (unsigned long)elapsed.tv_sec, (unsigned long)elapsed.tv_usec); + + /*mem info, database on disksize*/ + print_metric_help_and_type(buf, "nsd_", "size_db_on_disk_bytes", + "Size of DNS database on disk.", "gauge"); + print_longnum(buf, "nsd_size_db_on_disk_bytes ", st->db_disk); + + print_metric_help_and_type(buf, "nsd_", "size_db_in_mem_bytes", + "Size of DNS database in memory.", "gauge"); + print_longnum(buf, "nsd_size_db_in_mem_bytes ", st->db_mem); + + print_metric_help_and_type(buf, "nsd_", "size_xfrd_in_mem_bytes", + "Size of zone transfers and notifies in xfrd process, excluding TSIG data.", + "gauge"); + print_longnum(buf, "nsd_size_xfrd_in_mem_bytes ", region_get_mem(xfrd->region)); + + print_metric_help_and_type(buf, "nsd_", "size_config_on_disk_bytes", + "Size of zonelist file on disk, excluding nsd.conf.", + "gauge"); + print_longnum(buf, "nsd_size_config_on_disk_bytes ", + xfrd->nsd->options->zonelist_off); + + print_metric_help_and_type(buf, "nsd_", "size_config_in_mem_bytes", + "Size of config data in memory.", "gauge"); + print_longnum(buf, "nsd_size_config_in_mem_bytes ", region_get_mem( + xfrd->nsd->options->region)); + + /* number of zones serverd */ + print_metric_help_and_type(buf, "nsd_", "zones_primary", + "Number of primary zones served.", "gauge"); + evbuffer_add_printf(buf, "nsd_zones_primary %lu\n", + (unsigned long)(xfrd->notify_zones->count - xfrd->zones->count)); + + print_metric_help_and_type(buf, "nsd_", "zones_secondary", + "Number of secondary zones served.", "gauge"); + evbuffer_add_printf(buf, "nsd_zones_secondary %lu\n", + (unsigned long)xfrd->zones->count); + +#ifdef USE_ZONE_STATS + zonestat_print(NULL, buf, xfrd, clear, zonestats); /*per-zone statistics*/ +#else + (void)clear; (void)zonestats; +#endif +} + +#endif /*BIND8_STATS*/ + +#endif /* USE_METRICS */ Index: metrics.h =================================================================== RCS file: metrics.h diff -N metrics.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ metrics.h 3 Sep 2025 19:38:49 -0000 @@ -0,0 +1,92 @@ +/* + * metrics.h -- prometheus metrics endpoint + * + * Copyright (c) 2001-2025, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ + +#ifndef DAEMON_METRICS_H +#define DAEMON_METRICS_H + +struct xfrd_state; +struct nsd_options; +struct daemon_metrics; +struct evbuffer; + +#ifdef BIND8_STATS +struct nsdst; +#endif /* BIND8_STATS */ + +/* the metrics daemon needs little backlog */ +#define TCP_BACKLOG_METRICS 16 /* listen() tcp backlog */ + +/** + * Create new metrics endpoint for the daemon. + * @param cfg: config. + * @return new state, or NULL on failure. + */ +struct daemon_metrics* daemon_metrics_create(struct nsd_options* cfg); + +/** + * Delete metrics daemon and close HTTP listeners. + * @param m: daemon to delete. + */ +void daemon_metrics_delete(struct daemon_metrics* m); + +/** + * Close metrics HTTP listener ports. + * Does not delete the object itself. + * @param m: state to close. + */ +void daemon_metrics_close(struct daemon_metrics* m); + +/** + * Open and create HTTP listeners for metrics daemon. + * @param m: metrics state that contains list of accept sockets. + * @param cfg: config options. + * @return false on failure. + */ +int daemon_metrics_open_ports(struct daemon_metrics* m, + struct nsd_options* cfg); + +/** + * Setup HTTP listener. + * @param m: state + * @param xfrd: the process that hosts the daemon. + * m's HTTP listener is attached to its event base. + */ +void daemon_metrics_attach(struct daemon_metrics* m, struct xfrd_state* xfrd); + +#ifdef BIND8_STATS +/** + * Print stats as prometheus metrics to HTTP buffer + * @param buf: the HTTP buffer to write to + * @param xfrd: the process that hosts the daemon. + * @param now: current time + * @param clear: whether to reset the stats time + * @param st: the stats + * @param zonestats: the zonestats + * @param rc_stats_time: pointer to the remote-control stats_time member + * to correctly print the elapsed time since last stats reset + */ +void metrics_print_stats(struct evbuffer *buf, struct xfrd_state *xfrd, + struct timeval *now, int clear, struct nsdst *st, + struct nsdst **zonestats, + struct timeval *rc_stats_time); + +#ifdef USE_ZONE_STATS +/** + * Print zonestat metrics for a single zonestats object + * @param buf: the HTTP buffer to write to + * @param name: the zonestats name + * @param zst: the stats to print + */ +void metrics_zonestat_print_one(struct evbuffer *buf, char *name, + struct nsdst *zst); +#endif /* USE_ZONE_STATS */ + +#endif /*BIND8_STATS*/ + +#endif /* DAEMON_METRICS_H */ Index: mini_event.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/mini_event.c,v diff -u -p -r1.4 mini_event.c --- mini_event.c 30 Jun 2022 10:49:39 -0000 1.4 +++ mini_event.c 3 Sep 2025 19:38:49 -0000 @@ -350,10 +350,10 @@ event_add(struct event* ev, struct timev return -1; if( (ev->ev_flags&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { ev->ev_base->fds[ev->ev_fd] = ev; - if(ev->ev_flags&EV_READ) { + if((ev->ev_flags&EV_READ)) { FD_SET(FD_SET_T ev->ev_fd, &ev->ev_base->reads); } - if(ev->ev_flags&EV_WRITE) { + if((ev->ev_flags&EV_WRITE)) { FD_SET(FD_SET_T ev->ev_fd, &ev->ev_base->writes); } FD_SET(FD_SET_T ev->ev_fd, &ev->ev_base->content); Index: namedb.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/namedb.c,v diff -u -p -r1.15 namedb.c --- namedb.c 24 Oct 2021 12:14:19 -0000 1.15 +++ namedb.c 3 Sep 2025 19:38:49 -0000 @@ -81,8 +81,7 @@ allocate_domain_nsec3(domain_table_type* } #endif /* NSEC3 */ -/** make the domain last in the numlist, changes numbers of domains */ -static void +void numlist_make_last(domain_table_type* table, domain_type* domain) { uint32_t sw; @@ -122,8 +121,7 @@ numlist_make_last(domain_table_type* tab table->numlist_last = domain; } -/** pop the biggest domain off the numlist */ -static domain_type* +domain_type* numlist_pop_last(domain_table_type* table) { domain_type* d = table->numlist_last; Index: namedb.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/namedb.h,v diff -u -p -r1.18 namedb.h --- namedb.h 3 Sep 2025 18:46:48 -0000 1.18 +++ namedb.h 3 Sep 2025 19:38:49 -0000 @@ -474,4 +474,9 @@ void zone_rr_iter_init(zone_rr_iter_type rr_type *zone_rr_iter_next(zone_rr_iter_type *iter); +/** make the domain last in the numlist, changes numbers of domains */ +void numlist_make_last(domain_table_type* table, domain_type* domain); +/** pop the biggest domain off the numlist */ +domain_type* numlist_pop_last(domain_table_type* table); + #endif /* NAMEDB_H */ Index: netio.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/netio.c,v diff -u -p -r1.3 netio.c --- netio.c 3 Feb 2018 11:03:51 -0000 1.3 +++ netio.c 3 Sep 2025 19:38:49 -0000 @@ -148,10 +148,10 @@ netio_dispatch(netio_type *netio, const fds[numfd].events = 0; fds[numfd].revents = 0; handler->pfd = numfd; - if (handler->event_types & NETIO_EVENT_READ) { + if ((handler->event_types & NETIO_EVENT_READ)) { fds[numfd].events |= POLLIN; } - if (handler->event_types & NETIO_EVENT_WRITE) { + if ((handler->event_types & NETIO_EVENT_WRITE)) { fds[numfd].events |= POLLOUT; } numfd++; @@ -251,7 +251,7 @@ netio_dispatch(netio_type *netio, const event_types |= NETIO_EVENT_WRITE; } - if (event_types & handler->event_types) { + if ((event_types & handler->event_types)) { handler->event_handler(netio, handler, event_types & handler->event_types); ++result; } Index: nsd-checkconf.8.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd-checkconf.8.in,v diff -u -p -r1.44 nsd-checkconf.8.in --- nsd-checkconf.8.in 3 Sep 2025 18:46:48 -0000 1.44 +++ nsd-checkconf.8.in 3 Sep 2025 19:38:49 -0000 @@ -1,4 +1,4 @@ -.TH "nsd\-checkconf" "8" "dec 12, 2024" "NLnet Labs" "nsd 4.11.0" +.TH "nsd\-checkconf" "8" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0" .\" Copyright (c) 2001\-2024, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" Index: nsd-checkconf.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd-checkconf.c,v diff -u -p -r1.38 nsd-checkconf.c --- nsd-checkconf.c 3 Sep 2025 18:46:48 -0000 1.38 +++ nsd-checkconf.c 3 Sep 2025 19:38:49 -0000 @@ -467,6 +467,12 @@ config_print_zone(nsd_options_type* opt, SERV_GET_INT(rrl_ipv6_prefix_length, o); SERV_GET_INT(rrl_whitelist_ratelimit, o); #endif +#ifdef USE_METRICS + SERV_GET_BIN(metrics_enable, o); + SERV_GET_IP(metrics_interface, metrics_interface, o); + SERV_GET_INT(metrics_port, o); + SERV_GET_STR(metrics_path, o); +#endif /* USE_METRICS */ #ifdef USE_DNSTAP SERV_GET_BIN(dnstap_enable, o); SERV_GET_STR(dnstap_socket_path, o); @@ -733,6 +739,14 @@ config_test_print_server(nsd_options_typ for(p = opt->proxy_protocol_port; p; p = p->next) printf("\tproxy-protocol-port: %d\n", p->port); } + +#ifdef USE_METRICS + printf("\tmetrics-enable: %s\n", opt->metrics_enable?"yes":"no"); + for(ip = opt->metrics_interface; ip; ip=ip->next) + print_string_var("metrics-interface:", ip->address); + printf("\tmetrics-port: %d\n", opt->metrics_port); + print_string_var("metrics-path:", opt->metrics_path); +#endif /* USE_METRICS */ #ifdef USE_DNSTAP printf("\ndnstap:\n"); Index: nsd-checkzone.8.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd-checkzone.8.in,v diff -u -p -r1.28 nsd-checkzone.8.in --- nsd-checkzone.8.in 3 Sep 2025 18:46:48 -0000 1.28 +++ nsd-checkzone.8.in 3 Sep 2025 19:38:49 -0000 @@ -1,4 +1,4 @@ -.TH "nsd\-checkzone" "8" "dec 12, 2024" "NLnet Labs" "nsd 4.11.0" +.TH "nsd\-checkzone" "8" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0" .\" 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.32 nsd-control.8.in --- nsd-control.8.in 3 Sep 2025 18:46:48 -0000 1.32 +++ nsd-control.8.in 3 Sep 2025 19:38:49 -0000 @@ -1,4 +1,4 @@ -.TH "nsd\-control" "8" "dec 12, 2024" "NLnet Labs" "nsd 4.11.0" +.TH "nsd\-control" "8" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0" .\" 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.8 nsd-mem.c --- nsd-mem.c 3 Sep 2025 18:46:48 -0000 1.8 +++ nsd-mem.c 3 Sep 2025 19:38:49 -0000 @@ -23,6 +23,7 @@ #include "namedb.h" #include "difffile.h" #include "util.h" +#include "ixfr.h" struct nsd nsd; @@ -169,6 +170,7 @@ check_zone_mem(const char* tf, struct zo /* init*/ memset(&zmem, 0, sizeof(zmem)); memset(&nsd, 0, sizeof(nsd)); + nsd.region = region_create(xalloc, free); nsd.db = db = namedb_open(opt); if(!db) error("cannot open namedb"); zone = namedb_zone_create(db, dname, zo); @@ -185,9 +187,11 @@ check_zone_mem(const char* tf, struct zo print_zone_mem(&zmem); /* delete the zone from memory */ + zone_ixfr_free(zone->ixfr); namedb_close(db); udb_base_free(taskudb); unlink(tf); + region_destroy(nsd.region); /* add up totals */ add_mem(totmem, &zmem); @@ -211,6 +215,8 @@ check_mem(struct nsd_options* opt) account_total(opt, &totmem); /* print statistics */ print_tot_mem(&totmem); + + nsd_options_destroy(opt); } /* dummy functions to link */ Index: nsd.8.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd.8.in,v diff -u -p -r1.46 nsd.8.in --- nsd.8.in 3 Sep 2025 18:46:48 -0000 1.46 +++ nsd.8.in 3 Sep 2025 19:38:49 -0000 @@ -1,9 +1,9 @@ -.TH "NSD" "8" "dec 12, 2024" "NLnet Labs" "NSD 4.11.0" +.TH "NSD" "8" "Sep 3, 2025" "NLnet Labs" "NSD 4.13.0" .\" Copyright (c) 2001\-2024, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" .B nsd -\- Name Server Daemon (NSD) version 4.11.0. +\- Name Server Daemon (NSD) version 4.13.0. .SH "SYNOPSIS" .B nsd .RB [ \-4 ] Index: nsd.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd.c,v diff -u -p -r1.48 nsd.c --- nsd.c 3 Sep 2025 18:46:48 -0000 1.48 +++ nsd.c 3 Sep 2025 19:38:49 -0000 @@ -54,9 +54,18 @@ #include "remote.h" #include "xfrd-disk.h" #include "ipc.h" +#include "util.h" +#ifdef USE_METRICS +#include "metrics.h" +#endif /* USE_METRICS */ #ifdef USE_DNSTAP #include "dnstap/dnstap_collector.h" #endif +#ifdef USE_XDP +#include +#include "xdp-server.h" +#include "xdp-util.h" +#endif #include "util/proxy_protocol.h" /* The server handler... */ @@ -79,7 +88,7 @@ usage (void) " -4 Only listen to IPv4 connections.\n" " -6 Only listen to IPv6 connections.\n" " -a ip-address[@port] Listen to the specified incoming IP address (and port)\n" - " May be specified multiple times).\n" + " (May be specified multiple times).\n" " -c configfile Read specified configfile instead of %s.\n" " -d do not fork as a daemon process.\n" #ifndef NDEBUG @@ -521,74 +530,13 @@ figure_sockets( #endif } -/* print server affinity for given socket. "*" if socket has no affinity with - any specific server, "x-y" if socket has affinity with more than two - consecutively numbered servers, "x" if socket has affinity with a specific - server number, which is not necessarily just one server. e.g. "1 3" is - printed if socket has affinity with servers number one and three, but not - server number two. */ -static ssize_t -print_socket_servers(struct nsd_socket *sock, char *buf, size_t bufsz) -{ - int i, x, y, z, n = (int)(sock->servers->size); - char *sep = ""; - size_t off, tot; - ssize_t cnt = 0; - - assert(bufsz != 0); - - off = tot = 0; - x = y = z = -1; - for (i = 0; i <= n; i++) { - if (i == n || !nsd_bitset_isset(sock->servers, i)) { - cnt = 0; - if (i == n && x == -1) { - assert(y == -1); - assert(z == -1); - cnt = snprintf(buf, bufsz, "-"); - } else if (y > z) { - assert(x > z); - if (x == 0 && y == (n - 1)) { - assert(z == -1); - cnt = snprintf(buf+off, bufsz-off, - "*"); - } else if (x == y) { - cnt = snprintf(buf+off, bufsz-off, - "%s%d", sep, x+1); - } else if (x == (y - 1)) { - cnt = snprintf(buf+off, bufsz-off, - "%s%d %d", sep, x+1, y+1); - } else { - assert(y > (x + 1)); - cnt = snprintf(buf+off, bufsz-off, - "%s%d-%d", sep, x+1, y+1); - } - } - z = i; - if (cnt > 0) { - tot += (size_t)cnt; - off = (tot < bufsz) ? tot : bufsz - 1; - sep = " "; - } else if (cnt < 0) { - return -1; - } - } else if (x <= z) { - x = y = i; - } else { - assert(x > z); - y = i; - } - } - - return tot; -} - static void print_sockets( struct nsd_socket *udp, struct nsd_socket *tcp, size_t ifs) { +#define SERVERBUF_SIZE_MAX (999*4+1) /* assume something big */ char sockbuf[INET6_ADDRSTRLEN + 6 + 1]; - char *serverbuf; + char serverbuf[SERVERBUF_SIZE_MAX]; size_t i, serverbufsz, servercnt; const char *fmt = "listen on ip-address %s (%s) with server(s): %s"; struct nsd_bitset *servers; @@ -601,8 +549,7 @@ print_sockets( assert(tcp != NULL); servercnt = udp[0].servers->size; - serverbufsz = (((servercnt / 10) * servercnt) + servercnt) + 1; - serverbuf = xalloc(serverbufsz); + serverbufsz = SERVERBUF_SIZE_MAX; /* warn user of unused servers */ servers = xalloc(nsd_bitset_size(servercnt)); @@ -611,12 +558,12 @@ print_sockets( for(i = 0; i < ifs; i++) { assert(udp[i].servers->size == servercnt); addrport2str((void*)&udp[i].addr.ai_addr, sockbuf, sizeof(sockbuf)); - print_socket_servers(&udp[i], serverbuf, serverbufsz); + (void)print_socket_servers(udp[i].servers, serverbuf, serverbufsz); nsd_bitset_or(servers, servers, udp[i].servers); VERBOSITY(3, (LOG_NOTICE, fmt, sockbuf, "udp", serverbuf)); assert(tcp[i].servers->size == servercnt); addrport2str((void*)&tcp[i].addr.ai_addr, sockbuf, sizeof(sockbuf)); - print_socket_servers(&tcp[i], serverbuf, serverbufsz); + (void)print_socket_servers(tcp[i].servers, serverbuf, serverbufsz); nsd_bitset_or(servers, servers, tcp[i].servers); VERBOSITY(3, (LOG_NOTICE, fmt, sockbuf, "tcp", serverbuf)); } @@ -629,7 +576,6 @@ print_sockets( "any specified ip-address", i+1); } } - free(serverbuf); free(servers); } @@ -1159,6 +1105,32 @@ main(int argc, char *argv[]) nsd.child_count = nsd.options->server_count; } +#ifdef USE_XDP + /* make sure we will spawn enough servers to serve all queues of the + * selected network device, otherwise traffic to these queues will take + * the non-af_xdp path */ + if (nsd.options->xdp_interface) { + int res = ethtool_channels_get(nsd.options->xdp_interface); + if (res <= 0) { + log_msg(LOG_ERR, + "xdp: could not determine netdev queue count: %s. " + "(attempting to continue with 1 queue)", + strerror(errno)); + nsd.xdp.xdp_server.queue_count = 1; + } else { + nsd.xdp.xdp_server.queue_count = res; + } + + if (nsd.child_count < nsd.xdp.xdp_server.queue_count) { + log_msg(LOG_NOTICE, + "xdp configured but server-count not high enough to serve " + "all netdev queues, raising server-count to %u", + nsd.xdp.xdp_server.queue_count); + nsd.child_count = nsd.xdp.xdp_server.queue_count; + } + } +#endif + #ifdef SO_REUSEPORT if(nsd.options->reuseport && nsd.child_count > 1) { nsd.reuseport = nsd.child_count; @@ -1475,6 +1447,23 @@ main(int argc, char *argv[]) } #endif +#ifdef USE_XDP + /* Set XDP config */ + nsd.xdp.xdp_server.region = nsd.region; + nsd.xdp.xdp_server.interface_name = nsd.options->xdp_interface; + nsd.xdp.xdp_server.bpf_prog_filename = nsd.options->xdp_program_path; + nsd.xdp.xdp_server.bpf_prog_should_load = nsd.options->xdp_program_load; + nsd.xdp.xdp_server.bpf_bpffs_path = nsd.options->xdp_bpffs_path; + nsd.xdp.xdp_server.force_copy = nsd.options->xdp_force_copy; + nsd.xdp.xdp_server.nsd = &nsd; + + if (!nsd.options->xdp_interface) + log_msg(LOG_NOTICE, "XDP support is enabled, but not configured. Not using XDP."); + + /* moved xdp_server_init to after privilege drop to prevent + * problems with file ownership of bpf object pins. */ +#endif + print_sockets(nsd.udp, nsd.tcp, nsd.ifs); /* Setup the signal handling... */ @@ -1517,6 +1506,12 @@ main(int argc, char *argv[]) if(!(nsd.rc = daemon_remote_create(nsd.options))) error("could not perform remote control setup"); } +#ifdef USE_METRICS + if(nsd.options->metrics_enable) { + if(!(nsd.metrics = daemon_metrics_create(nsd.options))) + error("could not perform metrics server setup"); + } +#endif /* USE_METRICS */ #if defined(HAVE_SSL) if(nsd.options->tls_service_key && nsd.options->tls_service_key[0] && nsd.options->tls_service_pem && nsd.options->tls_service_pem[0]) { @@ -1647,9 +1642,35 @@ main(int argc, char *argv[]) nsd.pidfile, strerror(errno)); } +#ifdef USE_XDP + if (nsd.options->xdp_interface) { + /* initializing xdp needs the CAP_SYS_ADMIN, therefore doing it + * before privilege drop (and not keeping CAP_SYS_ADMIN) */ + if (xdp_server_init(&nsd.xdp.xdp_server)) { + log_msg(LOG_ERR, "failed to initialize XDP... disabling XDP."); + nsd.options->xdp_interface = NULL; + } + } +#endif + /* Drop the permissions */ #ifdef HAVE_GETPWNAM if (*nsd.username) { +#ifdef USE_XDP + if (nsd.options->xdp_interface) { + /* tell kernel to keep (permitted) privileges across uid change */ + if (!prctl(PR_SET_KEEPCAPS, 1)) { + /* only keep needed capabilities across privilege drop */ + /* this needs to be close to the privilege drop to prevent issues + * with other setup functions like tls setup */ + set_caps(0); + } else { + log_msg(LOG_ERR, "couldn't set keep capabilities... disabling XDP."); + nsd.options->xdp_interface = NULL; + } + } +#endif /* USE_XDP */ + #ifdef HAVE_INITGROUPS if(initgroups(nsd.username, nsd.gid) != 0) log_msg(LOG_WARNING, "unable to initgroups %s: %s", @@ -1679,6 +1700,14 @@ main(int argc, char *argv[]) DEBUG(DEBUG_IPC,1, (LOG_INFO, "dropped user privileges, run as %s", nsd.username)); + +#ifdef USE_XDP + /* enable capabilities after privilege drop */ + if (nsd.options->xdp_interface) { + /* re-enable needed capabilities and drop setuid/gid capabilities */ + set_caps(1); + } +#endif /* USE_XDP */ } #endif /* HAVE_GETPWNAM */ Index: nsd.conf.5.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd.conf.5.in,v diff -u -p -r1.52 nsd.conf.5.in --- nsd.conf.5.in 3 Sep 2025 18:46:48 -0000 1.52 +++ nsd.conf.5.in 3 Sep 2025 19:38:49 -0000 @@ -1,4 +1,4 @@ -.TH "nsd.conf" "5" "dec 12, 2024" "NLnet Labs" "nsd 4.11.0" +.TH "nsd.conf" "5" "Sep 3, 2025" "NLnet Labs" "nsd 4.13.0" .\" Copyright (c) 2001\-2024, NLnet Labs. All rights reserved. .\" See LICENSE for the license. .SH "NAME" @@ -148,9 +148,14 @@ work on other systems. .TP .B send\-buffer\-size:\fR Set the send buffer size for query-servicing sockets. Set to 0 to use the default settings. +It needs some space to be able to deal with packets that wait for local +address resolution, from like ARP and NDP discovery, before they are sent +out, hence it is elevated above the system default by default. +The default is 4194304 bytes (4m). .TP .B receive\-buffer\-size:\fR Set the receive buffer size for query-servicing sockets. Set to 0 to use the default settings. +The default is 1048576 bytes (1m). .TP .B debug\-mode:\fR Turns on debugging mode for nsd, does not fork a daemon process. @@ -228,6 +233,7 @@ enabled. The maximum number of concurrent, active TCP connections by each server. Default is 100. Same as command-line option .BR \-n . +That is the number of requests from clients to this server. .TP .B tcp\-reject\-overflow:\fR If set to yes, TCP connections made beyond the maximum set by tcp-count will @@ -261,6 +267,7 @@ negotiation between NSD and other server .B xfrd\-tcp\-max:\fR Number of sockets for xfrd to use for outgoing zone transfers. Default 128. Increase it to allow more zone transfer sockets, like to 256. +That is for zone transfers requested by this server from other servers. To save memory, this can be lowered, set it lower together with some other settings to have reduced memory footprint for NSD. xfrd\-tcp\-max: 32 and xfrd\-tcp\-pipeline: 128 and rrl\-size: 1000 @@ -272,7 +279,8 @@ size of the zone data. .TP .B xfrd\-tcp\-pipeline:\fR Number of simultaneous outgoing zone transfers that are possible on the -tcp sockets of xfrd. Max is 65536, default is 128. +tcp sockets of xfrd. Max is 65536, default is 128. That is for zone transfers +requested by this server from other servers. .TP .B ipv4\-edns\-size:\fR Preferred EDNS buffer size for IPv4. Default 1232. @@ -437,7 +445,6 @@ regardless of this option. Write updated secondary zones to their zonefile every N seconds. If the zone or pattern's "zonefile" option is set to "" (empty string), no zonefile is written. The default is 3600 (1 hour). -.\" rrlstart .TP .B rrl\-size:\fR This option gives the size of the hashtable. Default 1000000. More buckets @@ -451,11 +458,13 @@ blocked and unblocked subnets are logged and some receive TCP fallback replies. Once the rate limit is reached, NSD begins dropping responses. However, one in every "rrl\-slip" number of responses is allowed, with the TC bit set. If slip is set to 2, the -outgoing response rate will be halved. If it's set to 3, the outgoing +returned response rate will be halved. If it's set to 3, the returned response rate will be one\-third, and so on. If you set rrl\-slip to 10, traffic is reduced to 1/10th. Ratelimit options rrl\-ratelimit, rrl\-size and rrl\-whitelist\-ratelimit are updated when nsd\-control reconfig is done (also the zone\-specific ratelimit options are updated). +If not compiled in the option is ignored, the ratelimit can be on or off +by default by compile time configuration. .TP .B rrl\-slip:\fR This option controls the number of packets discarded before we send back a SLIP response @@ -474,7 +483,6 @@ The max qps for query sorts for a source whitelisted. Default @ratelimit_default@ (with a suggested 2000 qps). With the rrl\-whitelist option you can set specific queries to receive this qps limit instead of the normal limit. With the value 0 the rate is unlimited. -.\" rrlend .TP .B answer\-cookie:\fR Enable to answer to requests containing DNS Cookies as specified in RFC7873. @@ -601,6 +609,89 @@ The port number for proxy protocol servi times, additional port numbers can be used for proxy protocol service. The interface definitions that use this port number expect PROXYv2 proxy protocol traffic, for UDP, TCP and for TLS service. +.TP +.B xdp\-interface:\fR +The interface to use XDP with. This enables the use of AF_XDP sockets for UDP +queries. Default is "", disabled. (EXPERIMENTAL) + +.\" Considerations probably need improvement in format and wording +Considerations: +.br +\(bu If \fBcpu-affinity\fR is configured, please be aware of the cpu affinity +of network device queues. +.br +\(bu The number of spawned servers depends on the number of combined rx/tx +channels/queues of the selected interface. As many processes as there are +combined channels on the specified interface will receive traffic via XDP. +\fBserver-count\fR will be increased if necessary. If \fBserver-count\fR is +higher, the excess processes will not use XDP. +.br +\(bu The PROXYv2 protocol, DNSTAP, and ratelimiting are currently not supported +via XDP. +.TP +.B xdp\-program\-path:\fR +The eBPF XDP program to extract the XSKMAP from. Specify your own program here, +if you want to use a custom XDP program. The default program shipped with NSD +only redirects UDP (over Ethernet[+VLAN]+IPv4/6) traffic to port 53. +When using your own XDP program, it needs to define a BPF_MAP_TYPE_XSKMAP +named "xsks_map". + +This option needs to be set, even when NSD is configured not to load the +specified XDP program (see \fBxdp-program-load\fR), to be able to determine the +XSKMAP structure. In this case your XDP program needs to pin the above +mentioned map in a bpffs (see \fBxdp-bpffs-path\fR). + +Default is "@sharedfilesdir@/xdp-dns-redirect_kern.o". +.TP +.B xdp\-program\-load:\fR +Specify whether NSD should load the XDP program. If set to no, you need +to load the XDP program yourself. Default is yes, if xdp-interface is set. +.TP +.B xdp\-bpffs\-path:\fR +The path to the bpffs to store/read the xsks_map pin. The default XDP +program loaded by NSD doesn't need this option, it is only necessary if you +load a program that pins its BPF map. + +If NSD is configured to load an XDP program that pins its map, NSD needs to have +read/write/execute access to the specified bpffs to be able to create and later +delete the map pin. If you load the XDP program yourself, NSD only needs read +and write access to the pin file itself (but at least execute access to the +parent directories). The default bpffs (/sys/fs/bpf) usually doesn't have the +necessary permissions set for non-root users. You can either set the necessary +permissions or mount your own bpffs. + +Default is "/sys/fs/bpf". +.TP +.B xdp\-force\-copy:\fR +Force the use of XDP_COPY mode instead of zero copy for AF_XDP sockets. This +can help with drivers with broken AF_XDP support. Default is no. +.TP +.B metrics\-enable:\fR +Enable the prometheus metrics HTTP endpoint. It exposes the same statistics as +the \fInsd\-control\fR(8) stats_noreset command, but with metric names +following the prometheus specification. (Requires libevent2) + +To generate per zone metrics, specify the \fBzonestats\fR option on the desired +zones. + +Beware, that when using \fInsd\-control\fR(8) stats (instead of stats_noreset), +the statistics will be reset for the HTTP metrics endpoint as well. +.TP +.B metrics\-interface:\fR +NSD will bind to the listed addresses or interfaces to serve the prometheus +metrics. Can be given multiple times to bind multiple ip\-addresses. Use +0.0.0.0 and ::0 to bind to the wildcard interface. + +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. + +Default is 127.0.0.1 and ::1. +.TP +.B metrics\-port:\fR +The port number for the HTTP service. Default is 9100. +.TP +.B metrics\-path:\fR +The HTTP path to expose the metrics at. Default is "/metrics". .SS "Remote Control" The .B remote\-control: @@ -990,7 +1081,7 @@ configured with max\-refresh\-time, min\ min\-retry\-time if given. .TP .B zonestats:\fR -When compiled with \-\-enable\-zone\-stats NSD can collect statistics per zone. +When not compiled without zone\-stats NSD can collect statistics per zone. This name gives the group where statistics are added to. The groups are output from nsd\-control stats and stats_noreset. Default is "". You can use "%s" to use the name of the zone to track its statistics. @@ -999,7 +1090,6 @@ If not compiled in, the option can be gi .B include\-pattern:\fR The options from the given pattern are included at this point. The referenced pattern must be defined above this zone. -.\" rrlstart .TP .B rrl\-whitelist:\fR This option causes queries of this rrltype to be whitelisted, for this @@ -1010,7 +1100,6 @@ employs to make different types not inte are logged in the loglines when a subnet is blocked (in verbosity 2). The RRL classification types are: nxdomain, error, referral, any, rrsig, wildcard, nodata, dnskey, positive, all. -.\" rrlend .TP .B multi\-primary\-check:\fR Default no. If enabled, checks all primaries for the last version. It uses Index: nsd.conf.sample.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd.conf.sample.in,v diff -u -p -r1.25 nsd.conf.sample.in --- nsd.conf.sample.in 3 Sep 2025 18:46:48 -0000 1.25 +++ nsd.conf.sample.in 3 Sep 2025 19:38:49 -0000 @@ -73,8 +73,8 @@ server: # reuseport: no # override maximum socket send buffer size. Default of 0 results in - # send buffer size being set to 1048576 (bytes). - # send-buffer-size: 1048576 + # send buffer size being set to 4194304 (bytes). + # send-buffer-size: 4194304 # override maximum socket receive buffer size. Default of 0 results in # receive buffer size being set to 1048576 (bytes). @@ -223,14 +223,14 @@ server: # Reload nsd.conf and update TSIG keys and zones on SIGHUP. # reload-config: no - # RRLconfig # Response Rate Limiting, size of the hashtable. Default 1000000. # rrl-size: 1000000 # Response Rate Limiting, maximum QPS allowed (from one query source). # If set to 0, ratelimiting is disabled. Also set # rrl-whitelist-ratelimit to 0 to disable ratelimit processing. - # Default is @ratelimit_default@. + # Default is @ratelimit_default@. If not compiled in, the option is + # ignored. # rrl-ratelimit: 200 # Response Rate Limiting, number of packets to discard before @@ -283,6 +283,58 @@ server: # expect PROXYv2. For UDP and TCP/TLS interfaces. # proxy-protocol-port: portno for each of the port numbers. + # The interface to use XDP with. Default is "", disabled. + # xdp-interface: eth0 + + # The eBPF XDP program to extract the XSKMAP from. Specify your own + # program here, if you want to use a custom XDP program. + # The default program shipped with NSD only redirects UDP + # (over Ethernet[+VLAN]+IPv4/6) traffic to port 53. When using your own + # XDP program, it needs to define a BPF_MAP_TYPE_XSKMAP named "xsks_map" + # and pin it (see xdp-bpffs-path) with read and write permission for NSD. + # This option needs to be set even when NSD is configured not to load + # the specified XDP program (see xdp-program-load), to be able to + # access the XSKMAP. Default is "@sharedfilesdir@/xdp-dns-redirect_kern.o". + # xdp-program-path: "@sharedfilesdir@/xdp-dns-redirect_kern.o" + + # Specify whether NSD should load the XDP program. If set to no, you need + # to load the XDP program yourself. Default is yes, if xdp-interface is set. + # xdp-program-load: yes + + # The path to the bpffs to store/read the xsks_map pin. The default XDP + # program loaded by NSD doesn't need this option, it is only necessary if + # you load a program that pins its BPF map. + # If NSD is configured to load an XDP program that pins its map, NSD needs + # to have read/write/execute access to the specified bpffs to be able to + # create and later delete the map pin. If you load the XDP program + # yourself, NSD only needs read and write access to the pin file itself + # (but at least execute access to the parent directories). The default + # bpffs (/sys/fs/bpf) usually doesn't have the necessary permissions set + # for non-root users. You can either set the necessary permissions or mount + # your own bpffs. Default is "/sys/fs/bpf". + # xdp-bpffs-path: "/sys/fs/bpf" + + # Force the use of XDP_COPY mode instead of zero copy for AF_XDP sockets. + # This can help with drivers with broken AF_XDP support. Default is no. + # xdp-force-copy: no + + # Enable the prometheus metrics HTTP endpoint. Default is no. + # metrics-enable: no + + # Interfaces to expose the HTTP endpoint on, default is on localhost. + # Interfaces can be specified by IP address or interface name. + # With an interface name, all IP addresses associated with that + # interface are used. Default is 127.0.0.1 and ::1. + # metrics-interface: 127.0.0.1 + # metrics-interface: ::1 + # metrics-interface: lo + + # Port number for the HTTP metrics endpoint. Default is 9100. + # metrics-port: 9100 + + # HTTP path for the metrics endpoint. Default is "/metrics". + # metrics-path: "/metrics" + verify: # Enable zone verification. Default is no. # enable: no @@ -315,7 +367,7 @@ verify: # Number of seconds before verifier is killed (0 is forever). # verifier-timeout: 0 -# DNSTAP config section, if compiled with that +# DNSTAP config section, ignored if not compiled with that # dnstap: # set this to yes and set one or more of dnstap-log-..-messages to yes. # dnstap-enable: no @@ -480,7 +532,7 @@ remote-control: # 0 is no limits enforced. # size-limit-xfr: 0 - # if compiled with --enable-zone-stats, give name of stat block for + # if not compiled without zone-stats, give name of stat block for # this zone (or group of zones). Output from nsd-control stats. # zonestats: "%s" @@ -539,7 +591,6 @@ remote-control: # zonefile: "example.com.zone" # request-xfr: 192.0.2.1 example.com.key - # RRLconfig # Response Rate Limiting, whitelist types # rrl-whitelist: nxdomain # rrl-whitelist: error @@ -551,5 +602,4 @@ remote-control: # rrl-whitelist: dnskey # rrl-whitelist: positive # rrl-whitelist: all - # RRLend Index: nsd.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd.h,v diff -u -p -r1.16 nsd.h --- nsd.h 3 Sep 2025 18:46:48 -0000 1.16 +++ nsd.h 3 Sep 2025 19:38:49 -0000 @@ -26,10 +26,16 @@ #include "dns.h" #include "edns.h" #include "bitset.h" +#ifdef USE_XDP +#include "xdp-server.h" +#endif struct netio_handler; struct nsd_options; struct udb_base; struct daemon_remote; +#ifdef USE_METRICS +struct daemon_metrics; +#endif /* USE_METRICS */ #ifdef USE_DNSTAP struct dt_collector; #endif @@ -117,6 +123,7 @@ typedef unsigned long stc_type; /* Data structure to keep track of statistics */ struct nsdst { time_t boot; + stc_type reloadcount; /* counts reloads */ stc_type qtype[257]; /* Counters per qtype */ stc_type qclass[4]; /* Class IN or Class CH or other */ stc_type qudp, qudp6; /* Number of queries udp and udp6 */ @@ -255,6 +262,9 @@ struct nsd region_type* server_region; struct netio_handler* xfrd_listener; struct daemon_remote* rc; +#ifdef USE_METRICS + struct daemon_metrics* metrics; +#endif /* USE_METRICS */ /* Configuration */ const char *pidfile; @@ -296,6 +306,13 @@ struct nsd size_t verifier_limit; /* Maximum number of active verifiers */ int verifier_pipe[2]; /* Pipe to trigger verifier exit handler */ struct verifier *verifiers; + +#ifdef USE_XDP + struct { + /* only one interface for now */ + struct xdp_server xdp_server; + } xdp; +#endif edns_data_type edns_ipv4; #if defined(INET6) Index: nsec3.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsec3.c,v diff -u -p -r1.28 nsec3.c --- nsec3.c 3 Sep 2025 18:46:48 -0000 1.28 +++ nsec3.c 3 Sep 2025 19:38:49 -0000 @@ -166,7 +166,7 @@ nsec3_has_soa(rr_type* rr) 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 */ + (rdata_atom_data(rr->rdatas[NSEC3_RDATA_BITMAP])[2]&0x02)) { /* SOA bit set */ return 1; } return 0; @@ -661,6 +661,7 @@ prehash_zone_complete(struct namedb* db, zone->nsec3_last = NULL; return; } + nsec3_zone_trees_create(db->region, zone); nsec3_precompile_newparam(db, zone); } Index: options.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/options.c,v diff -u -p -r1.31 options.c --- options.c 3 Sep 2025 18:46:48 -0000 1.31 +++ options.c 3 Sep 2025 19:38:49 -0000 @@ -162,6 +162,19 @@ nsd_options_create(region_type* region) opt->server_cert_file = CONFIGDIR"/nsd_server.pem"; opt->control_key_file = CONFIGDIR"/nsd_control.key"; opt->control_cert_file = CONFIGDIR"/nsd_control.pem"; +#ifdef USE_XDP + opt->xdp_interface = NULL; + opt->xdp_program_path = SHAREDFILESDIR"/xdp-dns-redirect_kern.o"; + opt->xdp_program_load = 1; + opt->xdp_bpffs_path = "/sys/fs/bpf"; + opt->xdp_force_copy = 0; +#endif +#ifdef USE_METRICS + opt->metrics_enable = 0; + opt->metrics_interface = NULL; + opt->metrics_port = NSD_METRICS_PORT; + opt->metrics_path = "/metrics"; +#endif /* USE_METRICS */ opt->verify_enable = 0; opt->verify_ip_addresses = NULL; @@ -2773,8 +2786,8 @@ config_apply_pattern(struct pattern_opti c_error("could not find pattern %s", name); return; } - if(strncmp(dest->pname, PATTERN_IMPLICIT_MARKER, - strlen(PATTERN_IMPLICIT_MARKER)) == 0 + if( (!dest->pname || strncmp(dest->pname, PATTERN_IMPLICIT_MARKER, + strlen(PATTERN_IMPLICIT_MARKER)) == 0) && pat->catalog_producer_zone) { c_error("patterns with an catalog-producer-zone option are to " "be used with \"nsd-control addzone\" only and cannot " @@ -3082,6 +3095,10 @@ resolve_interface_names(struct nsd_optio addrs, options->region); resolve_interface_names_for_ref(&options->control_interface, addrs, options->region); +#ifdef USE_METRICS + resolve_interface_names_for_ref(&options->metrics_interface, + addrs, options->region); +#endif /* USE_METRICS */ freeifaddrs(addrs); #else Index: options.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/options.h,v diff -u -p -r1.30 options.h --- options.h 3 Sep 2025 18:46:48 -0000 1.30 +++ options.h 3 Sep 2025 19:38:49 -0000 @@ -163,6 +163,30 @@ struct nsd_options { /** certificate file for nsd-control */ char* control_cert_file; +#ifdef USE_XDP + /** XDP interface name */ + const char* xdp_interface; + /** XDP/eBPF program file path */ + const char* xdp_program_path; + /** if NSD should load the XDP/eBPF program */ + int xdp_program_load; + /** path to bpffs for pinned BPF objects */ + const char* xdp_bpffs_path; + /** force copy mode instead of zero copy mode */ + int xdp_force_copy; +#endif + +#ifdef USE_METRICS + /** metrics section. enable toggle. */ + int metrics_enable; + /** the interfaces the metrics endpoint should listen on */ + struct ip_address_option* metrics_interface; + /** port number for the metrics endpoint */ + int metrics_port; + /** HTTP path for the metrics endpoint */ + char* metrics_path; +#endif /* USE_METRICS */ + #ifdef RATELIMIT /** number of buckets in rrl hashtable */ size_t rrl_size; Index: query.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/query.c,v diff -u -p -r1.43 query.c --- query.c 3 Sep 2025 18:46:48 -0000 1.43 +++ query.c 3 Sep 2025 19:38:50 -0000 @@ -203,6 +203,34 @@ query_create(region_type *region, uint16 return query; } +query_type * +query_create_with_buffer(region_type *region, + uint16_t *compressed_dname_offsets, size_t compressed_dname_size, + domain_type **compressed_dnames, struct buffer *buffer) +{ + query_type *query + = (query_type *) region_alloc_zero(region, sizeof(query_type)); + /* create region with large block size, because the initial chunk + saves many mallocs in the server */ + query->region = region_create_custom(xalloc, free, 16384, 16384/8, 32, 0); + region_add_cleanup(region, query_cleanup, query); + query->compressed_dname_offsets = compressed_dname_offsets; + query->compressed_dnames = compressed_dnames; + query->packet = buffer; + query->compressed_dname_offsets_size = compressed_dname_size; + tsig_create_record(&query->tsig, region); + query->tsig_prepare_it = 1; + query->tsig_update_it = 1; + query->tsig_sign_it = 1; + return query; +} + +void +query_set_buffer_data(query_type *q, void *data, size_t data_capacity) +{ + buffer_create_from(q->packet, data, data_capacity); +} + void query_reset(query_type *q, size_t maxlen, int is_tcp) { Index: query.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/query.h,v diff -u -p -r1.9 query.h --- query.h 3 Sep 2025 18:46:48 -0000 1.9 +++ query.h 3 Sep 2025 19:38:50 -0000 @@ -216,6 +216,20 @@ query_type *query_create(region_type *re domain_type **compressed_dnames); /* + * Create a new query structure with buffer pointing to existing memory. + */ +query_type *query_create_with_buffer(region_type *region, + uint16_t *compressed_dname_offsets, + size_t compressed_dname_size, + domain_type **compressed_dnames, + struct buffer *buffer); + +/* + * Replace the query's buffer data. + */ +void query_set_buffer_data(query_type *q, void *data, size_t data_capacity); + +/* * Reset a query structure so it is ready for receiving and processing * a new query. */ Index: rbtree.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/rbtree.c,v diff -u -p -r1.3 rbtree.c --- rbtree.c 17 Feb 2017 20:04:45 -0000 1.3 +++ rbtree.c 3 Sep 2025 19:38:50 -0000 @@ -63,7 +63,13 @@ rbtree_create (region_type *region, int static void rbtree_rotate_left(rbtree_type *rbtree, rbnode_type *node) { - rbnode_type *right = node->right; + rbnode_type *right; + + /* Check if rbtree is NULL */ + if (!rbtree) { + return; + } + right = node->right; node->right = right->left; if (right->left != RBTREE_NULL) right->left->parent = node; @@ -90,7 +96,13 @@ rbtree_rotate_left(rbtree_type *rbtree, static void rbtree_rotate_right(rbtree_type *rbtree, rbnode_type *node) { - rbnode_type *left = node->left; + rbnode_type *left; + + /* Check if rbtree is NULL */ + if (!rbtree) { + return; + } + left = node->left; node->left = left->right; if (left->right != RBTREE_NULL) left->right->parent = node; @@ -115,6 +127,11 @@ rbtree_insert_fixup(rbtree_type *rbtree, { rbnode_type *uncle; + /* Check if rbtree is NULL */ + if (!rbtree) { + return; + } + /* While not at the root and need fixing... */ while (node != rbtree->root && node->parent->color == RED) { /* If our parent is left child of our grandparent... */ @@ -185,10 +202,17 @@ rbtree_insert (rbtree_type *rbtree, rbno { /* XXX Not necessary, but keeps compiler quiet... */ int r = 0; + rbnode_type *node; + rbnode_type *parent; + + /* Check if rbtree is NULL */ + if (!rbtree) { + return NULL; + } /* We start at the root of the tree */ - rbnode_type *node = rbtree->root; - rbnode_type *parent = RBTREE_NULL; + node = rbtree->root; + parent = RBTREE_NULL; /* Lets find the new parent... */ while (node != RBTREE_NULL) { @@ -237,6 +261,11 @@ rbtree_search (rbtree_type *rbtree, cons { rbnode_type *node; + /* Check if rbtree is NULL */ + if (!rbtree) { + return NULL; + } + if (rbtree_find_less_equal(rbtree, key, &node)) { return node; } else { @@ -257,6 +286,11 @@ static void swap_np(rbnode_type** x, rbn static void change_parent_ptr(rbtree_type* rbtree, rbnode_type* parent, rbnode_type* old, rbnode_type* new) { + /* Check if rbtree is NULL */ + if (!rbtree) { + return; + } + if(parent == RBTREE_NULL) { assert(rbtree->root == old); @@ -280,6 +314,12 @@ rbtree_delete(rbtree_type *rbtree, const { rbnode_type *to_delete; rbnode_type *child; + + /* Check if rbtree is NULL */ + if (!rbtree) { + return NULL; + } + if((to_delete = rbtree_search(rbtree, key)) == 0) return 0; rbtree->count--; @@ -358,6 +398,11 @@ static void rbtree_delete_fixup(rbtree_t rbnode_type* sibling; int go_up = 1; + /* Check if rbtree is NULL */ + if (!rbtree) { + return; + } + /* determine sibling to the node that is one-black short */ if(child_parent->right == child) sibling = child_parent->left; else sibling = child_parent->right; @@ -464,6 +509,12 @@ rbtree_find_less_equal(rbtree_type *rbtr assert(result); + /* Check if rbtree is NULL */ + if (!rbtree) { + *result = NULL; + return 0; + } + /* We start at root... */ node = rbtree->root; @@ -497,6 +548,11 @@ rbtree_first (rbtree_type *rbtree) { rbnode_type *node; + /* Check if rbtree is NULL */ + if (!rbtree) { + return NULL; + } + for (node = rbtree->root; node->left != RBTREE_NULL; node = node->left); return node; } @@ -505,6 +561,11 @@ rbnode_type * rbtree_last (rbtree_type *rbtree) { rbnode_type *node; + + /* Check if rbtree is NULL */ + if (!rbtree) { + return NULL; + } for (node = rbtree->root; node->right != RBTREE_NULL; node = node->right); return node; Index: rdata.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/rdata.c,v diff -u -p -r1.18 rdata.c --- rdata.c 3 Sep 2025 18:46:48 -0000 1.18 +++ rdata.c 3 Sep 2025 19:38:50 -0000 @@ -212,8 +212,8 @@ rdata_unquoted_to_string(buffer_type *ou for (i = 1; i <= length; ++i) { char ch = (char) data[i]; if (isprint((unsigned char)ch)) { - if (ch == '"' || ch == '\\' - || isspace((unsigned char)ch)) { + if (ch == '"' || ch == '\\' || ch == '(' || ch == ')' + || ch == '\'' || isspace((unsigned char)ch)) { buffer_printf(output, "\\"); } buffer_printf(output, "%c", ch); @@ -296,6 +296,15 @@ rdata_long_to_string(buffer_type *output } static int +rdata_longlong_to_string(buffer_type *output, rdata_atom_type rdata, + rr_type* ATTR_UNUSED(rr)) +{ + uint64_t data = read_uint64(rdata_atom_data(rdata)); + buffer_printf(output, "%llu", (unsigned long long) data); + return 1; +} + +static int rdata_a_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { @@ -450,13 +459,13 @@ rdata_base32_to_string(buffer_type *outp static int rdata_base64_to_string(buffer_type *output, rdata_atom_type rdata, - rr_type* ATTR_UNUSED(rr)) + rr_type* rr) { int length; size_t size = rdata_atom_size(rdata); if(size == 0) { /* single zero represents empty buffer */ - buffer_write(output, "0", 1); + buffer_write(output, (rr->type == TYPE_DOA ? "-" : "0"), 1); return 1; } buffer_reserve(output, size * 2 + 1); @@ -607,30 +616,16 @@ rdata_services_to_string(buffer_type *ou static int rdata_ipsecgateway_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* rr) { - int gateway_type = rdata_atom_data(rr->rdatas[1])[0]; - switch(gateway_type) { + switch(rdata_atom_data(rr->rdatas[1])[0]) { case IPSECKEY_NOGATEWAY: buffer_printf(output, "."); break; case IPSECKEY_IP4: - rdata_a_to_string(output, rdata, rr); - break; + return rdata_a_to_string(output, rdata, rr); case IPSECKEY_IP6: - rdata_aaaa_to_string(output, rdata, rr); - break; + return rdata_aaaa_to_string(output, rdata, rr); case IPSECKEY_DNAME: - { - region_type* temp = region_create(xalloc, free); - const dname_type* d = dname_make(temp, - rdata_atom_data(rdata), 0); - if(!d) { - region_destroy(temp); - return 0; - } - buffer_printf(output, "%s", dname_to_string(d, NULL)); - region_destroy(temp); - } - break; + return rdata_dns_name_to_string(output, rdata, rr); default: return 0; } @@ -975,6 +970,56 @@ rdata_hip_to_string(buffer_type *output, } static int +rdata_atma_to_string(buffer_type *output, rdata_atom_type rdata, + rr_type* ATTR_UNUSED(rr)) +{ + uint16_t size = rdata_atom_size(rdata), i; + + 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); + 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; +} + +static int +rdata_amtrelay_d_type_to_string(buffer_type *output, rdata_atom_type rdata, + rr_type* ATTR_UNUSED(rr)) +{ + uint8_t data = *rdata_atom_data(rdata); + buffer_printf(output , "%c %lu", (data & 0x80 ? '1' : '0'), + ((unsigned long)data & 0x7f)); + return 1; +} + +static int +rdata_amtrelay_relay_to_string(buffer_type *output, rdata_atom_type rdata, + rr_type* rr) +{ + 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; + } + return 1; +} + +static int rdata_unknown_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { @@ -992,6 +1037,7 @@ static rdata_to_string_type rdata_to_str 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, @@ -1019,6 +1065,9 @@ static rdata_to_string_type rdata_to_str 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 }; @@ -1077,6 +1126,9 @@ rdata_wireformat_to_rdata_atoms(region_t 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); @@ -1152,6 +1204,26 @@ rdata_wireformat_to_rdata_atoms(region_t if (buffer_position(packet) + length <= end) { length += buffer_current(packet)[0]; length += read_uint16(buffer_current(packet) + 2); + } + 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; } break; } Index: remote.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/remote.c,v diff -u -p -r1.28 remote.c --- remote.c 3 Sep 2025 18:46:48 -0000 1.28 +++ remote.c 3 Sep 2025 19:38:50 -0000 @@ -82,6 +82,10 @@ #include "ipc.h" #include "remote.h" +#ifdef USE_METRICS +#include "metrics.h" +#endif /* USE_METRICS */ + #ifdef HAVE_SYS_TYPES_H # include #endif @@ -221,11 +225,6 @@ remote_accept_callback(int fd, short eve static void remote_control_callback(int fd, short event, void* arg); -#ifdef BIND8_STATS -/* process the statistics and output them */ -static void process_stats(RES* ssl, xfrd_state_type* xfrd, int peek); -#endif - /** ---- end of private defines ---- **/ #ifdef HAVE_SSL @@ -247,7 +246,7 @@ log_crypto_err(const char* str) #ifdef BIND8_STATS /** subtract timers and the values do not overflow or become negative */ -static void +void timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start) { @@ -1123,8 +1122,13 @@ print_zonestatus(RES* ssl, xfrd_state_ty return 1; } if(!ssl_printf(ssl, " state: %s\n", - (xz->state == xfrd_zone_ok)?"ok":( - (xz->state == xfrd_zone_expired)?"expired":"refreshing"))) + xz->state == xfrd_zone_expired ? "expired" + : xz->state != xfrd_zone_ok ? "refreshing" + : !xz->soa_nsd_acquired || !xz->soa_disk_acquired + || xz->soa_nsd.serial == xz->soa_disk.serial ? "ok" + : compare_serial( ntohl(xz->soa_nsd.serial) + , ntohl(xz->soa_disk.serial)) < 0 ? "old-serial" + : "future-serial")) return 0; if(!print_soa_status(ssl, "served-serial", &xz->soa_nsd, xz->soa_nsd_acquired)) @@ -1266,7 +1270,7 @@ static void do_stats(RES* ssl, xfrd_state_type* xfrd, int peek) { #ifdef BIND8_STATS - process_stats(ssl, xfrd, peek); + process_stats(ssl, NULL, xfrd, peek); #else (void)xfrd; (void)peek; (void)ssl_printf(ssl, "error no stats enabled at compile time\n"); @@ -1755,7 +1759,104 @@ add_pat(xfrd_state_type* xfrd, struct pa xfrd_set_reload_now(xfrd); } -/** interrupt zones that are using changed or removed patterns */ +/** check if a zone's transfer configuration has actually changed */ +static int +zone_transfer_config_changed(xfrd_zone_type* xz, struct pattern_options* oldp, struct pattern_options* newp) +{ + /* If pattern doesn't exist in new config, we must interrupt */ + if(!newp) { + VERBOSITY(1, (LOG_INFO, "zone %s: pattern removed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + /* Check if request_xfr ACL list has changed */ + /* This also tests for TSIG key name changes. */ + if(!acl_list_equal(oldp->request_xfr, newp->request_xfr)) { + VERBOSITY(1, (LOG_INFO, "zone %s: request_xfr ACL changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + /* Check if other transfer-related settings have changed */ + if(oldp->size_limit_xfr != newp->size_limit_xfr) { + VERBOSITY(1, (LOG_INFO, "zone %s: size_limit_xfr changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + if(oldp->allow_axfr_fallback != newp->allow_axfr_fallback) { + VERBOSITY(1, (LOG_INFO, "zone %s: allow_axfr_fallback changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + if(oldp->max_refresh_time != newp->max_refresh_time) { + VERBOSITY(1, (LOG_INFO, "zone %s: max_refresh_time changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + if(oldp->min_refresh_time != newp->min_refresh_time) { + VERBOSITY(1, (LOG_INFO, "zone %s: min_refresh_time changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + if(oldp->max_retry_time != newp->max_retry_time) { + VERBOSITY(1, (LOG_INFO, "zone %s: max_retry_time changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + if(oldp->min_retry_time != newp->min_retry_time) { + VERBOSITY(1, (LOG_INFO, "zone %s: min_retry_time changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + if(oldp->min_expire_time != newp->min_expire_time) { + VERBOSITY(1, (LOG_INFO, "zone %s: min_expire_time changed, interrupting transfer", + xz->zone_options->name)); + return 1; + } + + /* No significant changes detected */ + /* Suppress logging when no changes detected to reduce log noise */ + return 0; +} + +/** check if a zone's notify configuration has actually changed */ +static int +zone_notify_config_changed(struct notify_zone* nz, struct pattern_options* oldp, struct pattern_options* newp) +{ + /* If pattern doesn't exist in new config, we must interrupt */ + if(!newp) { + VERBOSITY(1, (LOG_INFO, "notify zone %s: pattern removed, interrupting notify", + nz->options->name)); + return 1; + } + + /* Check if notify ACL list has changed */ + /* This also tests for TSIG key name changes. */ + if(!acl_list_equal(oldp->notify, newp->notify)) { + VERBOSITY(1, (LOG_INFO, "notify zone %s: notify ACL changed, interrupting notify", + nz->options->name)); + return 1; + } + + /* Check if notify-related settings have changed */ + if(oldp->notify_retry != newp->notify_retry) { + VERBOSITY(1, (LOG_INFO, "notify zone %s: notify_retry changed, interrupting notify", + nz->options->name)); + return 1; + } + + /* No significant changes detected */ + /* Suppress logging when no changes detected to reduce log noise */ + return 0; +} + static void repat_interrupt_zones(xfrd_state_type* xfrd, struct nsd_options* newopt) { @@ -1769,8 +1870,9 @@ repat_interrupt_zones(xfrd_state_type* x struct pattern_options* oldp = xz->zone_options->pattern; struct pattern_options* newp = pattern_options_find(newopt, oldp->pname); - if(!newp || !acl_list_equal(oldp->request_xfr, - newp->request_xfr)) { + + /* Only interrupt if the zone's transfer configuration has actually changed */ + if(zone_transfer_config_changed(xz, oldp, newp)) { /* interrupt transfer */ if(xz->tcp_conn != -1) { xfrd_tcp_release(xfrd->tcp_set, xz); @@ -1793,7 +1895,9 @@ repat_interrupt_zones(xfrd_state_type* x struct pattern_options* oldp = nz->options->pattern; struct pattern_options* newp = pattern_options_find(newopt, oldp->pname); - if(!newp || !acl_list_equal(oldp->notify, newp->notify)) { + + /* Only interrupt if the zone's notify configuration has actually changed */ + if(zone_notify_config_changed(nz, oldp, newp)) { /* interrupt notify */ if(nz->notify_send_enable) { notify_disable(nz); @@ -1886,7 +1990,7 @@ repat_patterns(xfrd_state_type* xfrd, st const dname_type* dname = parse_implicit_name(xfrd, p->pname); if (dname) { - if (newstate & REPAT_SLAVE) { + if ((newstate & REPAT_SLAVE)) { struct zone_options* zopt = zone_options_find( oldopt, dname); @@ -1894,11 +1998,11 @@ repat_patterns(xfrd_state_type* xfrd, st xfrd_init_slave_zone( xfrd, zopt); } - } else if (newstate & REPAT_MASTER) { + } else if ((newstate & REPAT_MASTER)) { xfrd_del_slave_zone(xfrd, dname); } - if (newstate & REPAT_CATALOG_CONSUMER) { + if ((newstate & REPAT_CATALOG_CONSUMER)) { struct zone_options* zopt = zone_options_find( oldopt, dname); @@ -1906,7 +2010,7 @@ repat_patterns(xfrd_state_type* xfrd, st xfrd_init_catalog_consumer_zone( xfrd, zopt); } - } else if (newstate & REPAT_CATALOG_CONSUMER_DEINIT) { + } else if ((newstate & REPAT_CATALOG_CONSUMER_DEINIT)) { xfrd_deinit_catalog_consumer_zone( xfrd, dname); } @@ -1928,19 +2032,19 @@ repat_patterns(xfrd_state_type* xfrd, st RBTREE_FOR(zone_opt, struct zone_options*, oldopt->zone_options) { struct pattern_options* oldp = zone_opt->pattern; if (!oldp->implicit) { - if (oldp->xfrd_flags & REPAT_SLAVE) { + if ((oldp->xfrd_flags & REPAT_SLAVE)) { /* xfrd needs stable reference so get * it from the oldopt(modified) tree */ xfrd_init_slave_zone(xfrd, zone_opt); - } else if (oldp->xfrd_flags & REPAT_MASTER) { + } else if ((oldp->xfrd_flags & REPAT_MASTER)) { xfrd_del_slave_zone(xfrd, (const dname_type*) zone_opt->node.key); } - if (oldp->xfrd_flags & REPAT_CATALOG_CONSUMER) { + if ((oldp->xfrd_flags & REPAT_CATALOG_CONSUMER)) { xfrd_init_catalog_consumer_zone(xfrd, zone_opt); - } else if (oldp->xfrd_flags & REPAT_CATALOG_CONSUMER_DEINIT) { + } else if ((oldp->xfrd_flags & REPAT_CATALOG_CONSUMER_DEINIT)) { xfrd_deinit_catalog_consumer_zone(xfrd, (const dname_type*) zone_opt->node.key); @@ -2049,6 +2153,7 @@ do_repattern(RES* ssl, xfrd_state_type* region_type* region = region_create(xalloc, free); struct nsd_options* opt; const char* cfgfile = xfrd->nsd->options->configfile; + int reload_needed_before = xfrd->need_to_send_reload; /* check chroot and configfile, if possible to reread */ if(xfrd->nsd->chrootdir) { @@ -2079,6 +2184,13 @@ do_repattern(RES* ssl, xfrd_state_type* repat_patterns(xfrd, opt); repat_options(xfrd, opt); zonestat_inc_ifneeded(xfrd); + + /* Check if any changes were actually made by comparing reload state */ + if(xfrd->need_to_send_reload == reload_needed_before) { + (void)ssl_printf(ssl, "reconfig completed: no changes detected\n"); + } else { + (void)ssl_printf(ssl, "reconfig completed: changes applied\n"); + } send_ok(ssl); region_destroy(region); } @@ -2843,7 +2955,7 @@ remote_control_callback(int fd, short ev } #ifdef BIND8_STATS -static const char* +const char* opcode2str(int o) { switch(o) { @@ -2991,9 +3103,9 @@ resize_zonestat(xfrd_state_type* xfrd, s xfrd->zonestat_clear_num = num; } -static void -zonestat_print(RES* ssl, xfrd_state_type* xfrd, int clear, - struct nsdst** zonestats) +void +zonestat_print(RES *ssl, struct evbuffer *evbuf, xfrd_state_type *xfrd, + int clear, struct nsdst **zonestats) { struct zonestatname* n; struct nsdst stat0, stat1; @@ -3035,11 +3147,21 @@ zonestat_print(RES* ssl, xfrd_state_type } /* stat0 contains the details that we want to print */ - if(!ssl_printf(ssl, "%s%snum.queries=%lu\n", name, ".", - (unsigned long)(stat0.qudp + stat0.qudp6 + stat0.ctcp + - stat0.ctcp6 + stat0.ctls + stat0.ctls6))) - return; - print_stat_block(ssl, name, ".", &stat0); + if (ssl) { + if(!ssl_printf(ssl, "%s%snum.queries=%lu\n", name, ".", + (unsigned long)(stat0.qudp + stat0.qudp6 + stat0.ctcp + + stat0.ctcp6 + stat0.ctls + stat0.ctls6))) + return; + print_stat_block(ssl, name, ".", &stat0); + } + +#ifdef USE_METRICS + if (evbuf) { + metrics_zonestat_print_one(evbuf, name, &stat0); + } +#else + (void)evbuf; +#endif /* USE_METRICS */ } } #endif /* USE_ZONE_STATS */ @@ -3099,16 +3221,14 @@ print_stats(RES* ssl, xfrd_state_type* x if(!ssl_printf(ssl, "zone.slave=%lu\n", (unsigned long)xfrd->zones->count)) return; #ifdef USE_ZONE_STATS - zonestat_print(ssl, xfrd, clear, zonestats); /* per-zone statistics */ + zonestat_print(ssl, NULL, xfrd, clear, zonestats); /* per-zone statistics */ #else (void)clear; (void)zonestats; #endif } -/* allocate stats temp arrays, for taking a coherent snapshot of the - * statistics values at that time. */ -static void -process_stats_alloc(xfrd_state_type* xfrd, struct nsdst** stats, +void +process_stats_alloc(struct xfrd_state* xfrd, struct nsdst** stats, struct nsdst** zonestats) { *stats = xmallocarray(xfrd->nsd->child_count*2, sizeof(struct nsdst)); @@ -3120,9 +3240,8 @@ process_stats_alloc(xfrd_state_type* xfr #endif } -/* grab a copy of the statistics, at this particular time. */ -static void -process_stats_grab(xfrd_state_type* xfrd, struct timeval* stattime, +void +process_stats_grab(struct xfrd_state* xfrd, struct timeval* stattime, struct nsdst* stats, struct nsdst** zonestats) { if(gettimeofday(stattime, NULL) == -1) @@ -3139,14 +3258,24 @@ process_stats_grab(xfrd_state_type* xfrd #endif } -/* add the old and new processes stat values into the first part of the - * array of stats */ -static void -process_stats_add_old_new(xfrd_state_type* xfrd, struct nsdst* stats) +void +process_stats_add_old_new(struct xfrd_state* xfrd, struct nsdst* stats) { size_t i; uint64_t dbd = stats[0].db_disk; uint64_t dbm = stats[0].db_mem; + stc_type count1, count2; + + /* Pick up the latest database memory use value. */ + count1 = stats[0].reloadcount; + count2 = stats[xfrd->nsd->child_count+0].reloadcount; + /* This comparison allows roll over, the check is count2 > count1. */ + if((count2 > count1 && count2-count1 < 0xffff) || + (count2 < count1 && count1-count2 > 0xffff)) { + dbd = stats[xfrd->nsd->child_count+0].db_disk; + dbm = stats[xfrd->nsd->child_count+0].db_mem; + } + /* The old and new server processes have separate stat blocks, * and these are added up together. This results in the statistics * values per server-child. The reload task briefly forks both @@ -3158,9 +3287,8 @@ process_stats_add_old_new(xfrd_state_typ stats[0].db_mem = dbm; } -/* manage clearing of stats, a cumulative count of cleared statistics */ -static void -process_stats_manage_clear(xfrd_state_type* xfrd, struct nsdst* stats, +void +process_stats_manage_clear(struct xfrd_state* xfrd, struct nsdst* stats, int peek) { struct nsdst st; @@ -3189,9 +3317,8 @@ process_stats_manage_clear(xfrd_state_ty } } -/* add up the statistics to get the total over the server children. */ -static void -process_stats_add_total(xfrd_state_type* xfrd, struct nsdst* total, +void +process_stats_add_total(struct xfrd_state* xfrd, struct nsdst* total, struct nsdst* stats) { size_t i; @@ -3208,19 +3335,39 @@ process_stats_add_total(xfrd_state_type* } } -/* process the statistics and output them */ -static void -process_stats(RES* ssl, xfrd_state_type* xfrd, int peek) +void +process_stats(RES* ssl, struct evbuffer *evbuf, struct xfrd_state* xfrd, int peek) { struct timeval stattime; struct nsdst* stats, *zonestats[2], total; + /* it only really makes sense for one to be used at a time and would + * otherwise cause issues if peek is zero */ + assert((ssl && !evbuf) || (!ssl && evbuf)); + process_stats_alloc(xfrd, &stats, zonestats); process_stats_grab(xfrd, &stattime, stats, zonestats); process_stats_add_old_new(xfrd, stats); process_stats_manage_clear(xfrd, stats, peek); process_stats_add_total(xfrd, &total, stats); - print_stats(ssl, xfrd, &stattime, !peek, &total, zonestats); + if (ssl) { + print_stats(ssl, xfrd, &stattime, !peek, &total, zonestats); + } +#ifdef USE_METRICS + if (evbuf) { + if (xfrd->nsd->options->control_enable) { + /* only pass in rc->stats_time if remote-conrol is enabled, + * otherwise stats_time is uninitialized */ + metrics_print_stats(evbuf, xfrd, &stattime, !peek, &total, zonestats, + &xfrd->nsd->rc->stats_time); + } else { + metrics_print_stats(evbuf, xfrd, &stattime, !peek, &total, zonestats, + NULL); + } + } +#else + (void)evbuf; +#endif /* USE_METRICS */ if(!peek) { xfrd->nsd->rc->stats_time = stattime; } Index: remote.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/remote.h,v diff -u -p -r1.5 remote.h --- remote.h 3 Sep 2025 18:46:48 -0000 1.5 +++ remote.h 3 Sep 2025 19:38:50 -0000 @@ -48,6 +48,12 @@ struct xfrd_state; struct nsd_options; +#ifdef BIND8_STATS +struct nsdst; +struct remote_stream; +struct evbuffer; +#endif /* BIND8_STATS */ + /* private, defined in remote.c to keep ssl.h out of this header */ struct daemon_remote; @@ -102,5 +108,91 @@ void daemon_remote_attach(struct daemon_ int create_local_accept_sock(const char* path, int* noproto); void xfrd_reload_config(struct xfrd_state *xfrd); + +#ifdef BIND8_STATS + +/** + * Allocate stats temp arrays, for taking a coherent snapshot of the + * statistics values at that time. + * @param xfrd: the process that hosts the control connection. + * @param stats: where to store the stats pointer + * @param zonestats: where to store the zonestats pointer + */ +void process_stats_alloc(struct xfrd_state* xfrd, + struct nsdst** stats, + struct nsdst** zonestats); + +/** + * Grab a copy of the statistics, at this particular time. + * @param xfrd: the process that hosts the control connection. + * @param stattime: where to write the timeofday + * @param stats: where to copy the stats to + * @param zonestats: where to copy the zonestats to + */ +void process_stats_grab(struct xfrd_state* xfrd, + struct timeval* stattime, + struct nsdst* stats, + struct nsdst** zonestats); +/** + * Add the old and new processes stat values into the first part of the + * array of stats + * @param xfrd: the process that hosts the control connection. + * @param stats: the stats pointer + */ +void process_stats_add_old_new(struct xfrd_state* xfrd, struct nsdst* stats); + +/** + * Manage clearing of stats, a cumulative count of cleared statistics + * @param xfrd: the process that hosts the control connection. + * @param stats: the stats pointer + * @param peek: whether to reset the stats time (0) or not (1) + */ +void +process_stats_manage_clear(struct xfrd_state* xfrd, + struct nsdst* stats, + int peek); + +/** + * Add up the statistics to get the total over the server children. + * @param xfrd: the process that hosts the control connection. + * @param total: where to store the total data + * @param stats: the stats pointer + */ +void process_stats_add_total(struct xfrd_state* xfrd, + struct nsdst* total, + struct nsdst* stats); + +/** + * Process the statistics and output them + * @param ssl: the remote stream to write normal remote-control output to + * @param evbuf: the HTTP buffer to write prometheus metrics output to + * @param xfrd: the process that hosts the control connection. + * @param peek: whether to reset the stats time (0) or not (1) + */ +void process_stats(struct remote_stream* ssl, + struct evbuffer* evbuf, + struct xfrd_state* xfrd, + int peek); + +#ifdef USE_ZONE_STATS +/** + * Process the zonestat statistics and output them + * @param ssl: the remote stream to write normal remote-control output to + * @param evbuf: the HTTP buffer to write prometheus metrics output to + * @param xfrd: the process that hosts the control connection. + * @param clear: whether to reset the stats time + * @param zonestats: the zonestats pointer + */ +void zonestat_print(struct remote_stream *ssl, struct evbuffer *evbuf, + struct xfrd_state *xfrd, int clear, + struct nsdst **zonestats); +#endif /*USE_ZONE_STATS*/ + +const char* opcode2str(int o); + +void timeval_subtract(struct timeval *d, const struct timeval *end, + const struct timeval *start); + +#endif /* BIND8_STATS */ #endif /* DAEMON_REMOTE_H */ Index: server.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/server.c,v diff -u -p -r1.53 server.c --- server.c 3 Sep 2025 18:46:48 -0000 1.53 +++ server.c 3 Sep 2025 19:38:50 -0000 @@ -87,6 +87,12 @@ #endif #include "verify.h" #include "util/proxy_protocol.h" +#ifdef USE_XDP +#include "xdp-server.h" +#endif +#ifdef USE_METRICS +#include "metrics.h" +#endif /* USE_METRICS */ #define RELOAD_SYNC_TIMEOUT 25 /* seconds */ @@ -168,6 +174,14 @@ struct tcp_accept_handler_data { int pp2_enabled; }; +#ifdef USE_XDP +struct xdp_handler_data { + struct nsd *nsd; + struct xdp_server *server; + struct event event; +}; +#endif + /* * These globals are used to enable the TCP accept handlers * when the number of TCP connection drops below the maximum @@ -202,6 +216,9 @@ struct mmsghdr { static struct mmsghdr msgs[NUM_RECV_PER_SELECT]; static struct iovec iovecs[NUM_RECV_PER_SELECT]; static struct query *queries[NUM_RECV_PER_SELECT]; +#ifdef USE_XDP +static struct query *xdp_queries[XDP_RX_BATCH_SIZE]; +#endif /* * Data for the TCP connection handlers. @@ -356,6 +373,10 @@ static void handle_tls_reading(int fd, s static void handle_tls_writing(int fd, short event, void* arg); #endif +#ifdef USE_XDP +static void handle_xdp(int fd, short event, void* arg); +#endif + /* * Send all children the quit nonblocking, then close pipe. */ @@ -570,7 +591,7 @@ server_zonestat_alloc(struct nsd* nsd) exit(1); } nsd->zonestatfd[1] = open(nsd->zonestatfname[1], O_CREAT|O_RDWR, 0600); - if(nsd->zonestatfd[0] == -1) { + if(nsd->zonestatfd[1] == -1) { log_msg(LOG_ERR, "cannot create %s: %s", nsd->zonestatfname[1], strerror(errno)); close(nsd->zonestatfd[0]); @@ -1256,7 +1277,7 @@ 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 = 1*1024*1024; + int rcv = 1*1024*1024, snd = 4*1024*1024; if(-1 == (sock->s = socket( sock->addr.ai_family, sock->addr.ai_socktype, 0))) @@ -1533,6 +1554,7 @@ server_prepare(struct nsd *nsd) #ifdef BIND8_STATS /* Initialize times... */ time(&nsd->st->boot); + nsd->st->reloadcount = 0; set_bind8_alarm(nsd); #endif /* BIND8_STATS */ @@ -1606,6 +1628,9 @@ server_shutdown(struct nsd *nsd) tsig_finalize(); daemon_remote_delete(nsd->rc); /* ssl-delete secret keys */ +#ifdef USE_METRICS + daemon_metrics_delete(nsd->metrics); +#endif /* USE_METRICS */ #ifdef HAVE_SSL if (nsd->tls_ctx) SSL_CTX_free(nsd->tls_ctx); @@ -1904,23 +1929,29 @@ server_send_soa_xfrd(struct nsd* nsd, in #ifdef HAVE_SSL static void -log_crypto_from_err(const char* str, unsigned long err) +log_crypto_from_err(int level, const char* str, unsigned long err) { /* error:[error code]:[library name]:[function name]:[reason string] */ char buf[128]; unsigned long e; ERR_error_string_n(err, buf, sizeof(buf)); - log_msg(LOG_ERR, "%s crypto %s", str, buf); + log_msg(level, "%s crypto %s", str, buf); while( (e=ERR_get_error()) ) { ERR_error_string_n(e, buf, sizeof(buf)); - log_msg(LOG_ERR, "and additionally crypto %s", buf); + log_msg(level, "and additionally crypto %s", buf); } } void log_crypto_err(const char* str) { - log_crypto_from_err(str, ERR_get_error()); + log_crypto_from_err(LOG_ERR, str, ERR_get_error()); +} + +void +log_crypto_warning(const char* str) +{ + log_crypto_from_err(LOG_WARNING, str, ERR_get_error()); } /** true if the ssl handshake error has to be squelched from the logs */ @@ -2085,6 +2116,20 @@ add_ocsp_data_cb(SSL *s, void* ATTR_UNUS } } +static int +server_alpn_cb(SSL* ATTR_UNUSED(s), + const unsigned char** out, unsigned char* outlen, + const unsigned char* in, unsigned int inlen, + void* ATTR_UNUSED(arg)) +{ + static const unsigned char alpns[] = { 3, 'd', 'o', 't' }; + unsigned char* tmp_out; + + SSL_select_next_proto(&tmp_out, outlen, alpns, sizeof(alpns), in, inlen); + *out = tmp_out; + return SSL_TLSEXT_ERR_OK; +} + SSL_CTX* server_tls_ctx_setup(char* key, char* pem, char* verifypem) { @@ -2125,6 +2170,15 @@ server_tls_ctx_setup(char* key, char* pe return 0; } #endif +#if defined(SSL_OP_NO_TLSv1_2) && defined(SSL_OP_NO_TLSv1_3) + /* if we have tls 1.3 disable 1.2 */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2) + != SSL_OP_NO_TLSv1_2){ + log_crypto_err("could not set SSL_OP_NO_TLSv1_2"); + SSL_CTX_free(ctx); + return 0; + } +#endif #if defined(SSL_OP_NO_RENEGOTIATION) /* disable client renegotiation */ if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & @@ -2134,6 +2188,13 @@ server_tls_ctx_setup(char* key, char* pe return 0; } #endif +#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF) + /* disable client renegotiation */ + if((SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF) & + SSL_OP_IGNORE_UNEXPECTED_EOF) != SSL_OP_IGNORE_UNEXPECTED_EOF) { + log_crypto_warning("could not set SSL_OP_IGNORE_UNEXPECTED_EOF"); + } +#endif #if defined(SHA256_DIGEST_LENGTH) && defined(SSL_TXT_CHACHA20) /* if we detect system-wide crypto policies, use those */ if (access( "/etc/crypto-policies/config", F_OK ) != 0 ) { @@ -2180,6 +2241,7 @@ server_tls_ctx_setup(char* key, char* pe SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(verifypem)); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } + SSL_CTX_set_alpn_select_cb(ctx, server_alpn_cb, NULL); return ctx; } @@ -2391,7 +2453,7 @@ static void server_reload_handle_sigchld void* ATTR_UNUSED(arg)) { assert(sig == SIGCHLD); - assert(event & EV_SIGNAL); + assert((event & EV_SIGNAL)); /* reap the exited old-serve child(s) */ while(waitpid(-1, NULL, WNOHANG) > 0) { @@ -2406,7 +2468,7 @@ static void server_reload_handle_quit_sy (struct quit_sync_event_data*)arg; ssize_t r; - if(event & EV_TIMEOUT) { + if((event & EV_TIMEOUT)) { sig_atomic_t cmd = NSD_QUIT_SYNC; DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: ipc send quit to main")); @@ -2419,13 +2481,14 @@ static void server_reload_handle_quit_sy */ return; } - assert(event & EV_READ); + assert((event & EV_READ)); assert(cb_data->read < sizeof(cb_data->to_read.cmd)); r = read(cmdsocket, cb_data->to_read.buf + cb_data->read, sizeof(cb_data->to_read.cmd) - cb_data->read); if(r == 0) { - log_msg(LOG_ERR, "reload: old-main quit during quit sync"); + DEBUG(DEBUG_IPC, 1, (LOG_WARNING, + "reload: old-main quit during quit sync")); cb_data->to_read.cmd = NSD_RELOAD; } else if(r == -1) { @@ -2550,6 +2613,12 @@ server_reload(struct nsd *nsd, region_ty if(nsd->mode == NSD_RELOAD_FAILED) { exit(NSD_RELOAD_FAILED); } +#ifdef BIND8_STATS + nsd->stats_per_child[nsd->stat_current][0].reloadcount = + nsd->stats_per_child[(nsd->stat_current==0?1:0)][0].reloadcount+1; + nsd->stats_per_child[nsd->stat_current][0].db_mem = + region_get_mem(nsd->db->region); +#endif /* listen for the signals of failed children again */ sigaction(SIGCHLD, &old_sigchld, NULL); @@ -2635,7 +2704,7 @@ server_reload(struct nsd *nsd, region_ty exit(1); } assert(cmd == NSD_RELOAD); - udb_ptr_unlink(last_task, nsd->task[nsd->mytask]); + udb_ptr_set(last_task, nsd->task[nsd->mytask], 0); task_process_sync(nsd->task[nsd->mytask]); #ifdef USE_ZONE_STATS server_zonestat_realloc(nsd); /* realloc for next children */ @@ -2949,6 +3018,15 @@ server_main(struct nsd *nsd) task_remap(nsd->task[nsd->mytask]); udb_ptr_init(&xfrs2process, nsd->task[nsd->mytask]); udb_ptr_init(&last_task , nsd->task[nsd->mytask]); + /* last_task and xfrs2process MUST be unlinked in all + * possible branches of the fork() below. + * server_reload() will unlink them, but for failed + * fork and for the "old-main" (child) process, we MUST + * unlink them in the case statement below. + * Unlink by setting the value to 0, because + * reload_process_non_xfr_tasks() may clear (and + * implicitly unlink) xfrs2process. + */ reload_process_non_xfr_tasks(nsd, &xfrs2process , &last_task); /* Do actual reload */ @@ -2956,6 +3034,8 @@ server_main(struct nsd *nsd) switch (reload_pid) { case -1: log_msg(LOG_ERR, "fork failed: %s", strerror(errno)); + udb_ptr_set(&last_task, nsd->task[nsd->mytask], 0); + udb_ptr_set(&xfrs2process, nsd->task[nsd->mytask], 0); break; default: /* PARENT */ @@ -2987,6 +3067,8 @@ server_main(struct nsd *nsd) #ifdef USE_LOG_PROCESS_ROLE log_set_process_role("old-main"); #endif + udb_ptr_set(&last_task, nsd->task[nsd->mytask], 0); + udb_ptr_set(&xfrs2process, nsd->task[nsd->mytask], 0); reload_listener.fd = reload_sockets[0]; reload_listener.timeout = NULL; reload_listener.user_data = nsd; @@ -3007,13 +3089,6 @@ server_main(struct nsd *nsd) log_set_process_role("main"); #endif } - /* xfrs2process and last_task need to be reset in case - * "old-main" becomes "main" (due to an failed (exited) - * xfr update). If needed xfrs2process gets unlinked by - * "load", and last_task by the xfrd. - */ - memset(&xfrs2process, 0, sizeof(xfrs2process)); - memset(&last_task, 0, sizeof(last_task)); break; case NSD_QUIT_SYNC: /* synchronisation of xfrd, parent and reload */ @@ -3132,6 +3207,10 @@ server_main(struct nsd *nsd) (void)kill(nsd->pid, SIGTERM); } +#ifdef USE_XDP + xdp_server_cleanup(&nsd->xdp.xdp_server); +#endif + #ifdef MEMCLEAN /* OS collects memory pages */ region_destroy(server_region); #endif @@ -3313,6 +3392,33 @@ add_tcp_handler( data->event_added = 1; } +#ifdef USE_XDP +static void +add_xdp_handler(struct nsd *nsd, + struct xdp_server *xdp, + struct xdp_handler_data *data) { + + 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); + if (sock < 0) { + log_msg(LOG_ERR, "xdp: xsk socket file descriptor is invalid: %s", + strerror(errno)); + return; + } + // TODO: check which EV_flags are needed + event_set(handler, sock, EV_PERSIST|EV_READ, handle_xdp, data); + if (event_base_set(nsd->event_base, handler) != 0) + log_msg(LOG_ERR, "nsd xdp: event_base_set failed"); + if (event_add(handler, NULL) != 0) + log_msg(LOG_ERR, "nsd xdp: event_add failed"); +} +#endif + /* * Serve DNS request to verifiers (short-lived) */ @@ -3532,7 +3638,7 @@ server_child(struct nsd *nsd) numifs = nsd->ifs; } - if (nsd->server_kind & NSD_SERVER_UDP) { + if ((nsd->server_kind & NSD_SERVER_UDP)) { int child = nsd->this_child->child_num; memset(msgs, 0, sizeof(msgs)); for (i = 0; i < NUM_RECV_PER_SELECT; i++) { @@ -3570,7 +3676,7 @@ server_child(struct nsd *nsd) * and disable them based on the current number of active TCP * connections. */ - if (nsd->server_kind & NSD_SERVER_TCP) { + if ((nsd->server_kind & NSD_SERVER_TCP)) { int child = nsd->this_child->child_num; tcp_accept_handler_count = numifs; tcp_accept_handlers = region_alloc_array(server_region, @@ -3595,6 +3701,53 @@ server_child(struct nsd *nsd) tcp_accept_handler_count = 0; } +#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) { + 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 { + nsd->xdp.xdp_server.queue_index = nsd->this_child->child_num; + nsd->xdp.xdp_server.queries = xdp_queries; + + log_msg(LOG_INFO, + "xdp: using socket with queue_id %d on interface %s", + 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 + * that receives the packet data. + * Using scratch data so that the existing functions in regards + * to queries and buffers don't break by use of NULL pointers */ + struct buffer *buffer = region_alloc_zero( + nsd->server_region, + sizeof(struct buffer)); + buffer_create_from(buffer, scratch_data, scratch_data_len); + xdp_queries[i] = query_create_with_buffer( + server_region, + compressed_dname_offsets, + compression_table_size, + compressed_dnames, + buffer); + query_reset(xdp_queries[i], UDP_MAX_MESSAGE_LEN, 0); + } + } + } +#endif + /* The main loop... */ while ((mode = nsd->mode) != NSD_QUIT) { if(mode == NSD_RUN) nsd->mode = mode = server_signal_mode(nsd); @@ -3645,6 +3798,10 @@ server_child(struct nsd *nsd) } } + /* This part is seemingly never reached as the loop WOULD exit on NSD_QUIT, + * but nsd->mode is only set to NSD_QUIT in ipc_child_quit. However, that + * function also calls exit(). */ + service_remaining_tcp(nsd); #ifdef BIND8_STATS bind8_stats(nsd); @@ -3663,7 +3820,7 @@ server_child(struct nsd *nsd) static void remaining_tcp_timeout(int ATTR_UNUSED(fd), short event, void* arg) { int* timed_out = (int*)arg; - assert(event & EV_TIMEOUT); (void)event; + assert((event & EV_TIMEOUT)); (void)event; /* wake up the service tcp thread, note event is no longer * registered */ *timed_out = 1; @@ -4266,7 +4423,11 @@ more_read_buf_tcp(int fd, struct tcp_han return 0; } else { char buf[48]; - addr2str(&data->query->remote_addr, buf, sizeof(buf)); + if(data->query) { + addr2str(&data->query->remote_addr, buf, sizeof(buf)); + } else { + snprintf(buf, sizeof(buf), "unknown"); + } #ifdef ECONNRESET if (verbosity >= 2 || errno != ECONNRESET) #endif /* ECONNRESET */ @@ -4571,8 +4732,9 @@ handle_tcp_writing(int fd, short event, struct event_base* ev_base; uint32_t now = 0; - if ((event & EV_TIMEOUT)) { + if ((event & EV_TIMEOUT) || !q) { /* Connection timed out. */ + /* Or data->query is NULL, in which case nothing to do. */ cleanup_tcp_handler(data); return; } @@ -4608,7 +4770,15 @@ handle_tcp_writing(int fd, short event, #ifdef EPIPE if(verbosity >= 2 || errno != EPIPE) #endif /* EPIPE 'broken pipe' */ - log_msg(LOG_ERR, "failed writing to tcp: %s", strerror(errno)); + { + char client_ip[128]; + if(data->query) { + addr2str(&data->query->client_addr, client_ip, sizeof(client_ip)); + } else { + snprintf(client_ip, sizeof(client_ip), "unknown"); + } + log_msg(LOG_ERR, "failed writing to tcp from %s: %s", client_ip, strerror(errno)); + } cleanup_tcp_handler(data); return; } @@ -4647,7 +4817,15 @@ handle_tcp_writing(int fd, short event, #ifdef EPIPE if(verbosity >= 2 || errno != EPIPE) #endif /* EPIPE 'broken pipe' */ - log_msg(LOG_ERR, "failed writing to tcp: %s", strerror(errno)); + { + char client_ip[128]; + if(data->query) { + addr2str(&data->query->client_addr, client_ip, sizeof(client_ip)); + } else { + snprintf(client_ip, sizeof(client_ip), "unknown"); + } + log_msg(LOG_ERR, "failed writing to tcp from %s: %s", client_ip, strerror(errno)); + } cleanup_tcp_handler(data); return; } @@ -4806,9 +4984,13 @@ tls_handshake(struct tcp_handler_data* d unsigned long err = ERR_get_error(); if(!squelch_err_ssl_handshake(err)) { char a[64], s[256]; - addr2str(&data->query->remote_addr, a, sizeof(a)); + if(data->query) { + addr2str(&data->query->remote_addr, a, sizeof(a)); + } else { + snprintf(a, sizeof(a), "unknown"); + } snprintf(s, sizeof(s), "TLS handshake failed from %s", a); - log_crypto_from_err(s, err); + log_crypto_from_err(LOG_ERR, s, err); } } cleanup_tcp_handler(data); @@ -5154,8 +5336,9 @@ handle_tls_writing(int fd, short event, buffer_type* write_buffer; uint32_t now = 0; - if ((event & EV_TIMEOUT)) { + if ((event & EV_TIMEOUT) || !q) { /* Connection timed out. */ + /* Or data->query is NULL, in which case nothing to do. */ cleanup_tcp_handler(data); return; } @@ -5218,7 +5401,17 @@ handle_tls_writing(int fd, short event, tcp_handler_setup_event(data, handle_tls_reading, fd, EV_PERSIST | EV_READ | EV_TIMEOUT); } else if(want != SSL_ERROR_WANT_WRITE) { cleanup_tcp_handler(data); - log_crypto_err("could not SSL_write"); + { + char client_ip[128], e[188]; + if(data->query) { + addr2str(&data->query->client_addr, client_ip, sizeof(client_ip)); + } else { + snprintf(client_ip, sizeof(client_ip), "unknown"); + } + snprintf(e, sizeof(e), "failed writing to tls from %s: %s", + client_ip, "SSL_write error"); + log_crypto_err(e); + } } return; } @@ -5510,6 +5703,15 @@ handle_tcp_accept(int fd, short event, v configure_handler_event_types(0); } } + +#ifdef USE_XDP +static void handle_xdp(int fd, short event, void* arg) { + struct xdp_handler_data *data = (struct xdp_handler_data*) arg; + + if ((event & EV_READ)) + xdp_handle_recv_and_send(data->server); +} +#endif static void send_children_command(struct nsd* nsd, sig_atomic_t command, int timeout) Index: tsig.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/tsig.c,v diff -u -p -r1.8 tsig.c --- tsig.c 14 May 2020 06:08:40 -0000 1.8 +++ tsig.c 3 Sep 2025 19:38:50 -0000 @@ -691,11 +691,13 @@ tsig_append_rr(tsig_record_type *tsig, b buffer_write_u32(packet, tsig->signed_time_low); buffer_write_u16(packet, tsig->signed_time_fudge); buffer_write_u16(packet, tsig->mac_size); - buffer_write(packet, tsig->mac_data, tsig->mac_size); + if(tsig->mac_size != 0) + buffer_write(packet, tsig->mac_data, tsig->mac_size); buffer_write_u16(packet, tsig->original_query_id); buffer_write_u16(packet, tsig->error_code); buffer_write_u16(packet, tsig->other_size); - buffer_write(packet, tsig->other_data, tsig->other_size); + if(tsig->other_size != 0) + buffer_write(packet, tsig->other_data, tsig->other_size); buffer_write_u16_at(packet, rdlength_pos, buffer_position(packet) - rdlength_pos Index: util.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/util.c,v diff -u -p -r1.30 util.c --- util.c 3 Sep 2025 18:46:48 -0000 1.30 +++ util.c 3 Sep 2025 19:38:50 -0000 @@ -1188,15 +1188,20 @@ void reconfig_cookies(struct nsd* nsd, s /* Cookie secrets in the configuration file take precedence */ if(options->cookie_secret) { - ssize_t len = hex_pton(options->cookie_secret, +#ifndef NDEBUG + ssize_t len = +#endif + hex_pton(options->cookie_secret, nsd->cookie_secrets[0].cookie_secret, NSD_COOKIE_SECRET_SIZE); - /* Cookie length guaranteed in configparser.y */ assert(len == NSD_COOKIE_SECRET_SIZE); nsd->cookie_count = 1; if(options->cookie_staging_secret) { - len = hex_pton(options->cookie_staging_secret, +#ifndef NDEBUG + len = +#endif + hex_pton(options->cookie_staging_secret, nsd->cookie_secrets[1].cookie_secret, NSD_COOKIE_SECRET_SIZE); /* Cookie length guaranteed in configparser.y */ @@ -1304,3 +1309,59 @@ generate_cookie_secrets: /*********************************************************************/ } +ssize_t +print_socket_servers(struct nsd_bitset *bitset, char *buf, size_t bufsz) +{ + /* x and y are the start and end points of a range of set bits */ + /* z is the last unset bit */ + int i, x, y, z, n = (int)(bitset->size); + char *sep = ""; + size_t off, written_total; + ssize_t written = 0; + + assert(bufsz != 0); + + off = written_total = 0; + x = y = z = -1; + for (i = 0; i <= n; i++) { + if (i == n || !nsd_bitset_isset(bitset, i)) { + written = 0; + if (i == n && x == -1) { + assert(y == -1); + assert(z == (n - 1)); + written = snprintf(buf, bufsz, "(none)"); + } else if (y > z) { + assert(x > z); + if (x == 0 && y == (n - 1)) { + assert(z == -1); + written = snprintf(buf+off, bufsz-off, + "(all)"); + } else if (x == y) { + written = snprintf(buf+off, bufsz-off, + "%s%d", sep, x+1); + } else if (x == (y - 1)) { + written = snprintf(buf+off, bufsz-off, + "%s%d %d", sep, x+1, y+1); + } else { + assert(y > (x + 1)); + written = snprintf(buf+off, bufsz-off, + "%s%d-%d", sep, x+1, y+1); + } + } + z = i; + if (written > 0) { + written_total += (size_t)written; + off = (written_total < bufsz) ? written_total : bufsz - 1; + sep = " "; + } else if (written < 0) { + return -1; + } + } else if (x <= z) { + x = y = i; + } else { + assert(x > z); + y = i; + } + } + return written_total; +} Index: util.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/util.h,v diff -u -p -r1.22 util.h --- util.h 3 Sep 2025 18:46:48 -0000 1.22 +++ util.h 3 Sep 2025 19:38:50 -0000 @@ -14,6 +14,7 @@ #include #include #include +#include "bitset.h" struct rr; struct buffer; struct region; @@ -255,7 +256,7 @@ read_uint32(const void *src) return ntohl(* (const uint32_t *) src); #else const uint8_t *p = (const uint8_t *) src; - return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; #endif } @@ -441,5 +442,18 @@ void activate_cookie_secret(struct nsd* void drop_cookie_secret(struct nsd* nsd); /* Configure nsd struct with how to respond to DNS Cookies based on options */ void reconfig_cookies(struct nsd* nsd, struct nsd_options* options); + +/* print server affinity for given socket's bitset. + * o "(all)"; if socket has no affinity with any specific server, + * o "(none)"; if no server uses the socket, + * o "x-y"; if socket has affinity with 'more than two consecutively' + * numbered servers, + * o "x"; if socket has affinity with a specific server number, which is + * not necessarily just one server. e.g. "1 3" is printed if + * socket has affinity with servers number one and three, but not + * server number two. Likewise "1 2" is printed if socket has + * affinity with servers one and two, but not server number three. + */ +ssize_t print_socket_servers(struct nsd_bitset *bitset, char *buf, size_t bufsz); #endif /* UTIL_H */ Index: verify.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/verify.c,v diff -u -p -r1.4 verify.c --- verify.c 29 Jun 2023 19:38:50 -0000 1.4 +++ verify.c 3 Sep 2025 19:38:50 -0000 @@ -137,7 +137,7 @@ static void verify_handle_stream(int fd, struct verifier *verifier; struct verifier_stream *stream; - assert(event & EV_READ); + assert((event & EV_READ)); assert(arg != NULL); verifier = (struct verifier *)arg; @@ -251,7 +251,7 @@ void verify_handle_timeout(int fd, short struct verifier *verifier; (void)fd; - assert(event & EV_TIMEOUT); + assert((event & EV_TIMEOUT)); assert(arg != NULL); verifier = (struct verifier *)arg; @@ -270,7 +270,7 @@ void verify_handle_signal(int sig, short struct nsd *nsd; assert(sig == SIGCHLD); - assert(event & EV_SIGNAL); + assert((event & EV_SIGNAL)); assert(arg != NULL); nsd = (struct nsd *)arg; @@ -294,7 +294,7 @@ void verify_handle_exit(int fd, short ev struct nsd *nsd; char buf[1]; - assert(event & EV_READ); + assert((event & EV_READ)); assert(arg != NULL); nsd = (struct nsd *)arg; @@ -371,11 +371,11 @@ verify_handle_command(int fd, short even sig_atomic_t mode; assert(nsd != NULL); - assert(event & (EV_READ + assert((event & (EV_READ #ifdef EV_CLOSED | EV_CLOSED #endif - )); + ))); if((len = read(fd, &mode, sizeof(mode))) == -1) { log_msg(LOG_ERR, "verify: verify_handle_command: read: %s", Index: xdp-dns-redirect_kern.c =================================================================== RCS file: xdp-dns-redirect_kern.c diff -N xdp-dns-redirect_kern.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xdp-dns-redirect_kern.c 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ + +#include /* must be before include bpf/... */ +#include +#include +#include /* for struct ethhdr */ +#include /* for IPPROTO_UDP */ +#include /* for struct iphdr */ +#include /* for struct ipv6hdr */ +#include /* for struct udphdr */ + +#define DEFAULT_ACTION XDP_PASS +#define DNS_PORT 53 + +// Define XSK MAP to store the descriptors of the user-space sockets +struct { + __uint(type, BPF_MAP_TYPE_XSKMAP); + __type(key, __u32); + __type(value, __u32); + __uint(max_entries, 128); + /* The commented line about pinning must stay, as it is used to generate + * a second bpf program */ + /* __uint(pinning, LIBBPF_PIN_BY_NAME); // SEDUNCOMMENTTHIS */ +} xsks_map SEC(".maps"); + +struct vlanhdr { + __u16 tci; + __u16 encap_proto; +}; + +struct cursor { + void *pos; + void *end; +}; + +static __always_inline void cursor_init(struct cursor *c, struct xdp_md *ctx) { + c->end = (void *)(long)ctx->data_end; + c->pos = (void *)(long)ctx->data; +} + +#define PARSE_FUNC_DECLARATION(STRUCT) \ + static __always_inline struct STRUCT *parse_##STRUCT(struct cursor *c) { \ + struct STRUCT *ret = c->pos; \ + if (c->pos + sizeof(struct STRUCT) > c->end) \ + return 0; \ + c->pos += sizeof(struct STRUCT); \ + return ret; \ + } + +PARSE_FUNC_DECLARATION(ethhdr) +PARSE_FUNC_DECLARATION(vlanhdr) +PARSE_FUNC_DECLARATION(iphdr) +PARSE_FUNC_DECLARATION(ipv6hdr) +PARSE_FUNC_DECLARATION(udphdr) + +// just fixing my editor highlight +#ifdef __NOTHING +#define JUST_FIXING_MY_SYNTAX_HIGHLIGHTING +#endif + +static __always_inline struct ethhdr * +parse_eth(struct cursor *c, __u16 *eth_proto) { + struct ethhdr *eth; + + if (!(eth = parse_ethhdr(c))) + return 0; + + *eth_proto = eth->h_proto; + if (*eth_proto == __bpf_htons(ETH_P_8021Q) || + *eth_proto == __bpf_htons(ETH_P_8021AD)) { + struct vlanhdr *vlan; + + if (!(vlan = parse_vlanhdr(c))) + return 0; + + *eth_proto = vlan->encap_proto; + if (*eth_proto == __bpf_htons(ETH_P_8021Q) || + *eth_proto == __bpf_htons(ETH_P_8021AD)) { + if (!(vlan = parse_vlanhdr(c))) + return 0; + + *eth_proto = vlan->encap_proto; + // TODO: check whether more tags are used? + } + } + return eth; +} + +SEC("xdp") +int xdp_dns_redirect(struct xdp_md *ctx) { + + struct cursor c; + struct ethhdr *eth; + __u16 eth_proto; + struct iphdr *ipv4; + struct ipv6hdr *ipv6; + struct udphdr *udp; + + __u32 index = ctx->rx_queue_index; + + cursor_init(&c, ctx); + + if (!(eth = parse_eth(&c, ð_proto))) + return DEFAULT_ACTION; + + if (eth_proto == __bpf_htons(ETH_P_IP)) { + if (!(ipv4 = parse_iphdr(&c)) || ipv4->protocol != IPPROTO_UDP) + return DEFAULT_ACTION; + + if (!(udp = parse_udphdr(&c)) || udp->dest != __bpf_htons(DNS_PORT)) + return DEFAULT_ACTION; + + // NOTE: Maybe not use goto and just have the redirect call here and in IPv6? + goto redirect_map; + + } else if (eth_proto == __bpf_htons(ETH_P_IPV6)) { + if (!(ipv6 = parse_ipv6hdr(&c)) || ipv6->nexthdr != IPPROTO_UDP) + return DEFAULT_ACTION; + + if (!(udp = parse_udphdr(&c)) || udp->dest != __bpf_htons(DNS_PORT)) + return DEFAULT_ACTION; + + goto redirect_map; + + } else { + return DEFAULT_ACTION; + } + +redirect_map: + if (bpf_map_lookup_elem(&xsks_map, &index)) { + return (int) bpf_redirect_map(&xsks_map, index, XDP_PASS); + } + + return XDP_PASS; +} + +// License needs to be GPL compatible to use bpf_printk. As we're not using +// that currently, the license could be solely BSD. +char _license[] SEC("license") = "Dual BSD/GPL"; Index: xdp-server.c =================================================================== RCS file: xdp-server.c diff -N xdp-server.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xdp-server.c 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,985 @@ +/* + * xdp-server.c -- integration of AF_XDP into nsd + * + * Copyright (c) 2024, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ + +/* + * Parts inspired by https://github.com/xdp-project/xdp-tutorial + */ + +#include "config.h" + +#ifdef USE_XDP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* #include */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "query.h" +#include "dns.h" +#include "util.h" +#include "xdp-server.h" +#include "xdp-util.h" +#include "nsd.h" + +// TODO: make configurable +#define DNS_PORT 53 + +struct xdp_config { + __u32 xdp_flags; + __u32 libxdp_flags; + __u16 xsk_bind_flags; +}; + +struct umem_ptr { + uint64_t addr; + uint32_t len; +}; + +static struct umem_ptr umem_ptrs[XDP_RX_BATCH_SIZE]; + +/* + * Allocate memory for UMEM and setup rings + */ +static int +xsk_configure_umem(struct xsk_umem_info *umem_info, uint64_t size); + +/* + * Retrieve a UMEM frame address for allocation + * + * Returns XDP_INVALID_UMEM_FRAME when there are no free frames available. + */ +static uint64_t xsk_alloc_umem_frame(struct xsk_socket_info *xsk); + +/* + * Bind AF_XDP socket and setup rings + */ +static int xsk_configure_socket(struct xdp_server *xdp, + struct xsk_socket_info *xsk_info, + struct xsk_umem_info *umem, + uint32_t queue_index); + +/* + * Get number of free frames in UMEM + */ +static uint64_t xsk_umem_free_frames(struct xsk_socket_info *xsk); + +/* + * Free a frame in UMEM + */ +static void xsk_free_umem_frame(struct xsk_socket_info *xsk, uint64_t frame); + +/* + * Fill fill ring with as many frames as possible + */ +static void fill_fq(struct xsk_socket_info *xsk); + +/* + * Load eBPF program to forward traffic to our socket + */ +static int load_xdp_program_and_map(struct xdp_server *xdp); + +/* + * Unload eBPF/XDP program + */ +static void unload_xdp_program(struct xdp_server *xdp); + +/* + * Figure out IP addresses to listen to. + */ +static int figure_ip_addresses(struct xdp_server *xdp); + +/* + * Add IP address to allowed destination addresses for incoming packets + */ +static void add_ip_address(struct xdp_server *xdp, + struct sockaddr_storage *addr); + +/* + * Check whether destination IPv4 is in allowed IPs list + */ +static int dest_ip_allowed4(struct xdp_server *xdp, struct iphdr *ipv4); + +/* + * Check whether destination IPv6 is in allowed IPs list + */ +static int dest_ip_allowed6(struct xdp_server *xdp, struct ipv6hdr *ipv6); + +/* + * Setup XDP sockets + */ +static int xdp_sockets_init(struct xdp_server *xdp); + +/* + * Cleanup XDP sockets and memory + */ +static void xdp_sockets_cleanup(struct xdp_server *xdp); + +/* + * Allocate a block of shared memory + */ +static void *alloc_shared_mem(size_t len); + +/* + * Collect free frames from completion queue + */ +static void drain_cq(struct xsk_socket_info *xsk); + +/* + * Send outstanding packets and recollect completed frame addresses + */ +static void handle_tx(struct xsk_socket_info *xsk); + +/* + * Process packet and indicate if it should be dropped + * return 0 or less => drop + * return greater than 0 => use for tx + */ +static int +process_packet(struct xdp_server *xdp, + uint8_t *pkt, + uint32_t *len, + struct query *query); + +static inline void swap_eth(struct ethhdr *eth); +static inline void swap_udp(struct udphdr *udp); +static inline void swap_ipv6(struct ipv6hdr *ipv6); +static inline void swap_ipv4(struct iphdr *ipv4); +static inline void *parse_udp(struct udphdr *udp); +static inline void *parse_ipv6(struct ipv6hdr *ipv6); +static inline void *parse_ipv4(struct iphdr *ipv4); + +/* + * Parse dns message and return new length of dns message + */ +static uint32_t parse_dns(struct nsd* nsd, + uint32_t dnslen, + struct query *q, + sa_family_t ai_family); + +/* *************** */ +/* Implementations */ +/* *************** */ + +static uint64_t xsk_alloc_umem_frame(struct xsk_socket_info *xsk) { + uint64_t frame; + if (xsk->umem->umem_frame_free == 0) { + return XDP_INVALID_UMEM_FRAME; + } + + frame = xsk->umem->umem_frame_addr[--xsk->umem->umem_frame_free]; + xsk->umem->umem_frame_addr[xsk->umem->umem_frame_free] = + XDP_INVALID_UMEM_FRAME; + return frame; +} + +static uint64_t xsk_umem_free_frames(struct xsk_socket_info *xsk) { + return xsk->umem->umem_frame_free; +} + +static void xsk_free_umem_frame(struct xsk_socket_info *xsk, uint64_t frame) { + assert(xsk->umem_frame_free < XDP_NUM_FRAMES); + xsk->umem->umem_frame_addr[xsk->umem->umem_frame_free++] = frame; +} + +static void fill_fq(struct xsk_socket_info *xsk) { + uint32_t stock_frames; + uint32_t idx_fq = 0; + /* fill the fill ring with as many frames as are available */ + /* get number of spots available in fq */ + stock_frames = xsk_prod_nb_free(&xsk->umem->fq, + (uint32_t) xsk_umem_free_frames(xsk)); + if (stock_frames > 0) { + /* ignoring prod__reserve return value, because we got stock_frames + * from xsk_prod_nb_free(), which are therefore available */ + xsk_ring_prod__reserve(&xsk->umem->fq, stock_frames, &idx_fq); + + for (uint32_t i = 0; i < stock_frames; ++i) { + /* TODO: handle lack of available frames? + * Is not necessary when the total amount of frames exceeds the + * total slots available across all queues combined */ + /* uint64_t frame = xsk_alloc_umem_frame(xsk); */ + /* if (frame == XDP_INVALID_UMEM_FRAME) */ + /* printf("xdp: trying to fill_addr INVALID UMEM FRAME"); */ + *xsk_ring_prod__fill_addr(&xsk->umem->fq, idx_fq++) = + xsk_alloc_umem_frame(xsk); + } + + xsk_ring_prod__submit(&xsk->umem->fq, stock_frames); + } +} + +static int load_xdp_program_and_map(struct xdp_server *xdp) { + struct bpf_map *map; + char errmsg[512]; + int err, ret; + /* UNSPEC => let libxdp decide */ + // TODO: put this into a config option as well? + enum xdp_attach_mode attach_mode = XDP_MODE_UNSPEC; + + DECLARE_LIBXDP_OPTS(bpf_object_open_opts, opts); + if (xdp->bpf_bpffs_path) + opts.pin_root_path = xdp->bpf_bpffs_path; + + /* for now our xdp program should contain just one program section */ + // TODO: look at xdp_program__create because it can take a pinned prog + xdp->bpf_prog = xdp_program__open_file(xdp->bpf_prog_filename, NULL, &opts); + + // conversion should be fine, libxdp errors shouldn't exceed (int), + // also libxdp_strerr takes int anyway... + err = (int) libxdp_get_error(xdp->bpf_prog); + if (err) { + libxdp_strerror(err, errmsg, sizeof(errmsg)); + log_msg(LOG_ERR, "xdp: could not open xdp program: %s\n", errmsg); + return err; + } + + if (xdp->bpf_prog_should_load) { + /* TODO: I find setting environment variables from within a program + * not a good thing to do, but for the meantime this helps... */ + /* This is done to allow unloading the XDP program we load without + * needing the SYS_ADMIN capability, and libxdp doesn't allow skipping + * the dispatcher through different means. */ + putenv("LIBXDP_SKIP_DISPATCHER=1"); + err = xdp_program__attach(xdp->bpf_prog, (int) xdp->interface_index, attach_mode, 0); + /* err = xdp_program__attach_single(xdp->bpf_prog, xdp->interface_index, attach_mode); */ + if (err) { + libxdp_strerror(err, errmsg, sizeof(errmsg)); + log_msg(LOG_ERR, "xdp: could not attach xdp program to interface '%s' : %s\n", + xdp->interface_name, errmsg); + return err; + } + + xdp->bpf_prog_fd = xdp_program__fd(xdp->bpf_prog); + xdp->bpf_prog_id = xdp_program__id(xdp->bpf_prog); + + /* We also need to get the file descriptor to the xsks_map */ + map = bpf_object__find_map_by_name(xdp_program__bpf_obj(xdp->bpf_prog), "xsks_map"); + ret = bpf_map__fd(map); + if (ret < 0) { + log_msg(LOG_ERR, "xdp: no xsks map found in xdp program: %s\n", strerror(ret)); + return ret; + } + xdp->xsk_map_fd = ret; + xdp->xsk_map = map; + } else { + char map_path[PATH_MAX]; + int fd; + + snprintf(map_path, PATH_MAX, "%s/%s", xdp->bpf_bpffs_path, "xsks_map"); + + fd = bpf_obj_get(map_path); + if (fd < 0) { + log_msg(LOG_ERR, "xdp: could not retrieve xsks_map pin from %s: %s", map_path, strerror(errno)); + return fd; + } + + map = bpf_object__find_map_by_name(xdp_program__bpf_obj(xdp->bpf_prog), "xsks_map"); + if ((ret = bpf_map__reuse_fd(map, fd))) { + log_msg(LOG_ERR, "xdp: could not re-use xsks_map: %s\n", strerror(errno)); + return ret; + } + + xdp->xsk_map_fd = fd; + xdp->xsk_map = map; + } + + return 0; +} + +static int +xsk_configure_umem(struct xsk_umem_info *umem_info, uint64_t size) { + int ret; + struct xsk_umem_config umem_config = { + .fill_size = XSK_RING_PROD__NUM_DESCS, + .comp_size = XSK_RING_CONS__NUM_DESCS, + .frame_size = XDP_FRAME_SIZE, + .frame_headroom = XSK_UMEM_FRAME_HEADROOM, + .flags = XSK_UMEM_FLAGS, + }; + + ret = xsk_umem__create(&umem_info->umem, umem_info->buffer, size, &umem_info->fq, &umem_info->cq, &umem_config); + if (ret) { + errno = -ret; + return ret; + } + + return 0; +} + +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 xdp_config cfg = { + .xdp_flags = 0, + .xsk_bind_flags = xsk_bind_flags, + .libxdp_flags = XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD, + }; + + struct xsk_socket_config xsk_cfg; + uint32_t idx, reserved; + int ret; + + xsk_info->umem = umem; + xsk_cfg.rx_size = XSK_RING_CONS__NUM_DESCS; + xsk_cfg.tx_size = XSK_RING_PROD__NUM_DESCS; + xsk_cfg.xdp_flags = cfg.xdp_flags; + xsk_cfg.bind_flags = cfg.xsk_bind_flags; + xsk_cfg.libxdp_flags = cfg.libxdp_flags; + + ret = xsk_socket__create(&xsk_info->xsk, + xdp->interface_name, + queue_index, + umem->umem, + &xsk_info->rx, + &xsk_info->tx, + &xsk_cfg); + if (ret) { + log_msg(LOG_ERR, "xdp: failed to create xsk_socket"); + goto error_exit; + } + + ret = xsk_socket__update_xskmap(xsk_info->xsk, xdp->xsk_map_fd); + if (ret) { + log_msg(LOG_ERR, "xdp: failed to update xskmap"); + goto error_exit; + } + + /* Initialize umem frame allocation */ + for (uint32_t i = 0; i < XDP_NUM_FRAMES; ++i) { + xsk_info->umem->umem_frame_addr[i] = i * XDP_FRAME_SIZE; + } + + xsk_info->umem->umem_frame_free = XDP_NUM_FRAMES; + + reserved = xsk_ring_prod__reserve(&xsk_info->umem->fq, + XSK_RING_PROD__NUM_DESCS, + &idx); + + if (reserved != XSK_RING_PROD__NUM_DESCS) { + log_msg(LOG_ERR, + "xdp: amount of reserved addr not as expected (is %d)", reserved); + // "ENOMEM 12 Cannot allocate memory" is the closest to the + // error that not as much memory was reserved as expected + ret = -12; + goto error_exit; + } + + for (uint32_t i = 0; i < XSK_RING_PROD__NUM_DESCS; ++i) { + *xsk_ring_prod__fill_addr(&xsk_info->umem->fq, idx++) = + xsk_alloc_umem_frame(xsk_info); + } + + xsk_ring_prod__submit(&xsk_info->umem->fq, XSK_RING_PROD__NUM_DESCS); + + return 0; + +error_exit: + errno = -ret; + return ret; +} + +static void *alloc_shared_mem(size_t len) { + /* MAP_ANONYMOUS memory is initialized with zero */ + return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); +} + +static int xdp_sockets_init(struct xdp_server *xdp) { + size_t umems_len = sizeof(struct xsk_umem_info) * xdp->queue_count; + size_t xsks_len = sizeof(struct xsk_socket_info) * xdp->queue_count; + + xdp->umems = (struct xsk_umem_info *) alloc_shared_mem(umems_len); + if (xdp->umems == MAP_FAILED) { + log_msg(LOG_ERR, + "xdp: failed to allocate shared memory for umem info: %s", + strerror(errno)); + return -1; + } + + xdp->xsks = (struct xsk_socket_info *) alloc_shared_mem(xsks_len); + if (xdp->xsks == MAP_FAILED) { + log_msg(LOG_ERR, + "xdp: failed to allocate shared memory for xsk info: %s", + strerror(errno)); + return -1; + } + + for (uint32_t q_idx = 0; q_idx < xdp->queue_count; ++q_idx) { + /* mmap is supposedly page-aligned, so should be fine */ + xdp->umems[q_idx].buffer = alloc_shared_mem(XDP_BUFFER_SIZE); + + if (xsk_configure_umem(&xdp->umems[q_idx], XDP_BUFFER_SIZE)) { + log_msg(LOG_ERR, "xdp: cannot create umem: %s", strerror(errno)); + goto out_err_umem; + } + + if (xsk_configure_socket(xdp, &xdp->xsks[q_idx], &xdp->umems[q_idx], + q_idx)) { + log_msg(LOG_ERR, + "xdp: cannot create AF_XDP socket: %s", + strerror(errno)); + goto out_err_xsk; + } + } + + return 0; + +out_err_xsk: + for (uint32_t i = 0; i < xdp->queue_count; ++i) + xsk_umem__delete(xdp->umems[i].umem); + +out_err_umem: + return -1; +} + +static void xdp_sockets_cleanup(struct xdp_server *xdp) { + for (uint32_t i = 0; i < xdp->queue_count; ++i) { + xsk_socket__delete(xdp->xsks[i].xsk); + xsk_umem__delete(xdp->umems[i].umem); + } +} + +int xdp_server_init(struct xdp_server *xdp) { + struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY}; + + /* check if interface name exists */ + xdp->interface_index = if_nametoindex(xdp->interface_name); + if (xdp->interface_index == 0) { + log_msg(LOG_ERR, "xdp: configured xdp-interface (%s) is unknown: %s", + xdp->interface_name, strerror(errno)); + return -1; + } + + /* (optionally) load xdp program and (definitely) set xsks_map_fd */ + if (load_xdp_program_and_map(xdp)) { + log_msg(LOG_ERR, "xdp: failed to load/pin xdp program/map"); + return -1; + } + + /* if we don't do set rlimit, libbpf does it */ + /* this either has to be done before privilege drop or + * requires CAP_SYS_RESOURCE */ + if (setrlimit(RLIMIT_MEMLOCK, &rlim)) { + log_msg(LOG_ERR, "xdp: cannot adjust rlimit (RLIMIT_MEMLOCK): \"%s\"\n", + strerror(errno)); + return -1; + } + + if (xdp_sockets_init(xdp)) + return -1; + + for (int i = 0; i < XDP_RX_BATCH_SIZE; ++i) { + umem_ptrs[i].addr = XDP_INVALID_UMEM_FRAME; + umem_ptrs[i].len = 0; + } + + if (!xdp->ip_addresses) + figure_ip_addresses(xdp); + + return 0; +} + +void xdp_server_cleanup(struct xdp_server *xdp) { + xdp_sockets_cleanup(xdp); + + /* only unpin if we loaded the program */ + if (xdp->bpf_prog_should_load) { + if (xdp->xsk_map && bpf_map__is_pinned(xdp->xsk_map)) { + if (bpf_map__unpin(xdp->xsk_map, NULL)) { + /* We currently ship an XDP program that doesn't pin the map. So + * if this error happens, it is because the user specified their + * custom XDP program to load by NSD. Therefore they should know + * about the pinned map and be able to unlink it themselves. + */ + log_msg(LOG_ERR, "xdp: failed to unpin bpf map during cleanup: \"%s\". " + "This is usually ok, but you need to unpin the map yourself. " + "This can usually be fixed by executing chmod o+wx %s\n", + strerror(errno), xdp->bpf_bpffs_path); + } + } + + unload_xdp_program(xdp); + } +} + +static void unload_xdp_program(struct xdp_server *xdp) { + DECLARE_LIBBPF_OPTS(bpf_xdp_attach_opts, bpf_opts, + .old_prog_fd = xdp->bpf_prog_fd); + + log_msg(LOG_INFO, "xdp: detaching xdp program %u from %s\n", + xdp->bpf_prog_id, xdp->interface_name); + + if (bpf_xdp_detach((int) xdp->interface_index, 0, &bpf_opts)) + log_msg(LOG_ERR, "xdp: failed to detach xdp program: %s\n", + strerror(errno)); +} + +static int dest_ip_allowed6(struct xdp_server *xdp, struct ipv6hdr *ipv6) { + struct xdp_ip_address *ip = xdp->ip_addresses; + if (!ip) + // no IPs available, allowing all + return 1; + + while (ip) { + if (ip->addr.ss_family == AF_INET6 && + !memcmp(&(((struct sockaddr_in6 *) &ip->addr)->sin6_addr), + &ipv6->daddr, + sizeof(struct in6_addr))) + return 1; + ip = ip->next; + } + + return 0; +} + +static int dest_ip_allowed4(struct xdp_server *xdp, struct iphdr *ipv4) { + struct xdp_ip_address *ip = xdp->ip_addresses; + if (!ip) + // no IPs available, allowing all + return 1; + + while (ip) { + if (ip->addr.ss_family == AF_INET && + ipv4->daddr == ((struct sockaddr_in *) &ip->addr)->sin_addr.s_addr) + return 1; + ip = ip->next; + } + + return 0; +} + +static void +add_ip_address(struct xdp_server *xdp, struct sockaddr_storage *addr) { + struct xdp_ip_address *ip = xdp->ip_addresses; + if (!ip) { + xdp->ip_addresses = region_alloc_zero(xdp->region, + sizeof(struct xdp_ip_address)); + ip = xdp->ip_addresses; + } else { + while (ip->next) + ip = ip->next; + + ip->next = region_alloc_zero(xdp->region, + sizeof(struct xdp_ip_address)); + ip = ip->next; + } + + memcpy(&ip->addr, addr, sizeof(struct sockaddr_storage)); +} + +static int figure_ip_addresses(struct xdp_server *xdp) { + // TODO: if using VLANs, also find appropriate IP addresses? + struct ifaddrs *ifaddr; + int family, ret = 0; + + if (getifaddrs(&ifaddr) == -1) { + log_msg(LOG_ERR, "xdp: couldn't determine local IP addresses. " + "Serving all IP addresses now"); + return -1; + } + + for (struct ifaddrs *ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + + if (strcmp(ifa->ifa_name, xdp->interface_name)) + continue; + + family = ifa->ifa_addr->sa_family; + + switch (family) { + default: + continue; + case AF_INET: + case AF_INET6: + add_ip_address(xdp, (struct sockaddr_storage *) ifa->ifa_addr); + } + } + + freeifaddrs(ifaddr); + return ret; +} + +static inline void swap_eth(struct ethhdr *eth) { + uint8_t tmp_mac[ETH_ALEN]; + memcpy(tmp_mac, eth->h_dest, ETH_ALEN); + memcpy(eth->h_dest, eth->h_source, ETH_ALEN); + memcpy(eth->h_source, tmp_mac, ETH_ALEN); +} + +static inline void swap_udp(struct udphdr *udp) { + uint16_t tmp_port; /* not touching endianness */ + tmp_port = udp->source; + udp->source = udp->dest; + udp->dest = tmp_port; +} + +static inline void swap_ipv6(struct ipv6hdr *ipv6) { + struct in6_addr tmp_ip; + memcpy(&tmp_ip, &ipv6->saddr, sizeof(tmp_ip)); + memcpy(&ipv6->saddr, &ipv6->daddr, sizeof(tmp_ip)); + memcpy(&ipv6->daddr, &tmp_ip, sizeof(tmp_ip)); +} + +static inline void swap_ipv4(struct iphdr *ipv4) { + struct in_addr tmp_ip; + memcpy(&tmp_ip, &ipv4->saddr, sizeof(tmp_ip)); + memcpy(&ipv4->saddr, &ipv4->daddr, sizeof(tmp_ip)); + memcpy(&ipv4->daddr, &tmp_ip, sizeof(tmp_ip)); +} + +static inline void *parse_udp(struct udphdr *udp) { + if (ntohs(udp->dest) != DNS_PORT) + return NULL; + + return (void *)(udp + 1); +} + +static inline void *parse_ipv6(struct ipv6hdr *ipv6) { + if (ipv6->nexthdr != IPPROTO_UDP) + return NULL; + + return (void *)(ipv6 + 1); +} + +static inline void *parse_ipv4(struct iphdr *ipv4) { + if (ipv4->protocol != IPPROTO_UDP) + return NULL; + + return (void *)(ipv4 + 1); +} + +static uint32_t parse_dns(struct nsd* nsd, uint32_t dnslen, + struct query *q, sa_family_t ai_family) { + /* TODO: implement DNSTAP, PROXYv2, ...? */ + uint32_t now = 0; + + /* set the size of the dns message and move position to start */ + buffer_skip(q->packet, dnslen); + buffer_flip(q->packet); + + if (query_process(q, nsd, &now) != QUERY_DISCARDED) { + if (RCODE(q->packet) == RCODE_OK && !AA(q->packet)) { + STATUP(nsd, nona); + ZTATUP(nsd, q->zone, nona); + } + +#ifdef USE_ZONE_STATS + if (ai_family == AF_INET) { + ZTATUP(nsd, q->zone, qudp); + } else if (ai_family == AF_INET6) { + ZTATUP(nsd, q->zone, qudp6); + } +#endif /* USE_ZONE_STATS */ + + query_add_optional(q, nsd, &now); + + buffer_flip(q->packet); + +#ifdef BIND8_STATS + /* Account the rcode & TC... */ + STATUP2(nsd, rcode, RCODE(q->packet)); + ZTATUP2(nsd, q->zone, rcode, RCODE(q->packet)); + if (TC(q->packet)) { + STATUP(nsd, truncated); + ZTATUP(nsd, q->zone, truncated); + } +#endif /* BIND8_STATS */ + + /* return new dns message length */ + return (uint32_t) buffer_remaining(q->packet); + } else { + query_reset(q, UDP_MAX_MESSAGE_LEN, 0); + STATUP(nsd, dropped); + ZTATUP(nsd, q->zone, dropped); + return 0; + } +} + +static int +process_packet(struct xdp_server *xdp, uint8_t *pkt, + uint32_t *len, struct query *query) { + /* log_msg(LOG_INFO, "xdp: received packet with len %d", *len); */ + + uint32_t dnslen = *len; + uint32_t data_before_dnshdr_len = 0; + + struct ethhdr *eth = (struct ethhdr *)pkt; + struct ipv6hdr *ipv6 = NULL; + struct iphdr *ipv4 = NULL; + struct udphdr *udp = NULL; + void *dnshdr = NULL; + + /* doing the check here, so that the packet/frame is large enough to contain + * at least an ethernet header, an ipv4 header (ipv6 header is larger), and + * a udp header. + */ + if (*len < (sizeof(*eth) + sizeof(struct iphdr) + sizeof(*udp))) + return -1; + + data_before_dnshdr_len = sizeof(*eth) + sizeof(*udp); + + switch (ntohs(eth->h_proto)) { + case ETH_P_IPV6: { + ipv6 = (struct ipv6hdr *)(eth + 1); + + if (*len < (sizeof(*eth) + sizeof(*ipv6) + sizeof(*udp))) + return -2; + if (!(udp = parse_ipv6(ipv6))) + return -3; + + dnslen -= (uint32_t) (sizeof(*eth) + sizeof(*ipv6) + sizeof(*udp)); + data_before_dnshdr_len += sizeof(*ipv6); + + if (!dest_ip_allowed6(xdp, ipv6)) + return -4; + + break; + } case ETH_P_IP: { + ipv4 = (struct iphdr *)(eth + 1); + + if (!(udp = parse_ipv4(ipv4))) + return -5; + + dnslen -= (uint32_t) (sizeof(*eth) + sizeof(*ipv4) + sizeof(*udp)); + data_before_dnshdr_len += sizeof(*ipv4); + + if (!dest_ip_allowed4(xdp, ipv4)) + return -6; + + break; + } + + /* TODO: vlan? */ + /* case ETH_P_8021AD: case ETH_P_8021Q: */ + /* if (*len < (sizeof(*eth) + sizeof(*vlan))) */ + /* break; */ + default: + return -7; + } + + if (!(dnshdr = parse_udp(udp))) + return -8; + + query_set_buffer_data(query, dnshdr, XDP_FRAME_SIZE - data_before_dnshdr_len); + + if(ipv6) { +#ifdef INET6 + struct sockaddr_in6* sock6 = (struct sockaddr_in6*)&query->remote_addr; + sock6->sin6_family = AF_INET6; + sock6->sin6_port = udp->dest; + sock6->sin6_flowinfo = 0; + sock6->sin6_scope_id = 0; + memcpy(&sock6->sin6_addr, &ipv6->saddr, sizeof(ipv6->saddr)); + query->remote_addrlen = (socklen_t)sizeof(struct sockaddr_in6); +#else + return 0; /* no inet6 no network */ +#endif /* INET6 */ +#ifdef BIND8_STATS + STATUP(xdp->nsd, qudp6); +#endif /* BIND8_STATS */ + } else { + struct sockaddr_in* sock4 = (struct sockaddr_in*)&query->remote_addr; + sock4->sin_family = AF_INET; + sock4->sin_port = udp->dest; + sock4->sin_addr.s_addr = ipv4->saddr; + query->remote_addrlen = (socklen_t)sizeof(struct sockaddr_in); +#ifdef BIND8_STATS + STATUP(xdp->nsd, qudp); +#endif /* BIND8_STATS */ + } + + query->client_addr = query->remote_addr; + query->client_addrlen = query->remote_addrlen; + query->is_proxied = 0; + + dnslen = parse_dns(xdp->nsd, dnslen, query, query->remote_addr.ss_family); + if (!dnslen) { + return -9; + } + + // Not verifying the packet length (that it fits in an IP packet), as + // parse_dns truncates too long response messages. + udp->len = htons((uint16_t) (sizeof(*udp) + dnslen)); + + swap_eth(eth); + swap_udp(udp); + + if (ipv4) { + swap_ipv4(ipv4); + __be16 ipv4_old_len = ipv4->tot_len; + 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); + } else if (ipv6) { + swap_ipv6(ipv6); + ipv6->payload_len = udp->len; + udp->check = calc_csum_udp6(udp, ipv6); + } else { + log_msg(LOG_ERR, "xdp: we forgot to implement something... oops"); + return 0; + } + + /* log_msg(LOG_INFO, "xdp: done with processing the packet"); */ + + *len = data_before_dnshdr_len + dnslen; + return 1; +} + +void xdp_handle_recv_and_send(struct xdp_server *xdp) { + struct xsk_socket_info *xsk = &xdp->xsks[xdp->queue_index]; + unsigned int recvd, i, reserved, to_send = 0; + uint32_t idx_rx = 0; + int ret; + + recvd = xsk_ring_cons__peek(&xsk->rx, XDP_RX_BATCH_SIZE, &idx_rx); + if (!recvd) { + /* no data available */ + return; + } + + fill_fq(xsk); + + /* Process received packets */ + for (i = 0; i < recvd; ++i) { + uint64_t addr = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx)->addr; + uint32_t len = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx++)->len; + + uint8_t *pkt = xsk_umem__get_data(xsk->umem->buffer, addr); + if ((ret = process_packet(xdp, pkt, &len, xdp->queries[i])) <= 0) { + /* drop packet */ + xsk_free_umem_frame(xsk, addr); + } else { + umem_ptrs[to_send].addr = addr; + umem_ptrs[to_send].len = len; + ++to_send; + } + /* we can reset the query directly after each packet processing, + * because the reset does not delete the underlying buffer/data. + * However, if we, in future, need to access data from the query + * struct when sending the answer, this needs to change. + * This also means, that currently a single query instance (and + * not an array) would suffice for this implementation. */ + query_reset(xdp->queries[i], UDP_MAX_MESSAGE_LEN, 0); + + /* xsk->stats.rx_bytes += len; */ + } + + xsk_ring_cons__release(&xsk->rx, recvd); + /* 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); + // if we can't reserve to_send frames, we'll get 0 frames, so + // no need to "un-reserve" + if (reserved != to_send) { + // not enough tx slots available, drop packets + log_msg(LOG_ERR, "xdp: not enough TX frames available, dropping " + "whole batch"); + for (i = 0; i < to_send; ++i) { + xsk_free_umem_frame(xsk, umem_ptrs[i].addr); + umem_ptrs[i].addr = XDP_INVALID_UMEM_FRAME; + umem_ptrs[i].len = 0; + } +#ifdef BIND8_STATS + xdp->nsd->st->txerr += to_send; +#endif /* BIND8_STATS */ + to_send = 0; + } + + for (i = 0; i < to_send; ++i) { + uint64_t addr = umem_ptrs[i].addr; + uint32_t len = umem_ptrs[i].len; + xsk_ring_prod__tx_desc(&xsk->tx, tx_idx)->addr = addr; + xsk_ring_prod__tx_desc(&xsk->tx, tx_idx)->len = len; + tx_idx++; + xsk->outstanding_tx++; + umem_ptrs[i].addr = XDP_INVALID_UMEM_FRAME; + umem_ptrs[i].len = 0; + } + + xsk_ring_prod__submit(&xsk->tx, to_send); + + /* wake up kernel for tx if needed and collect completed tx buffers */ + handle_tx(xsk); + /* TODO: maybe call fill_fq(xsk) here as well? */ +} + +static void drain_cq(struct xsk_socket_info *xsk) { + uint32_t completed, idx_cq; + + /* free completed TX buffers */ + completed = xsk_ring_cons__peek(&xsk->umem->cq, + XSK_RING_CONS__NUM_DESCS, + &idx_cq); + + if (completed > 0) { + for (uint32_t i = 0; i < completed; i++) { + xsk_free_umem_frame(xsk, *xsk_ring_cons__comp_addr(&xsk->umem->cq, + idx_cq++)); + } + + xsk_ring_cons__release(&xsk->umem->cq, completed); + xsk->outstanding_tx -= completed < xsk->outstanding_tx ? + completed : xsk->outstanding_tx; + } +} + +static void handle_tx(struct xsk_socket_info *xsk) { + if (!xsk->outstanding_tx) + return; + + if (xsk_ring_prod__needs_wakeup(&xsk->tx)) + sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); + + drain_cq(xsk); + + // Update TX-queue pointers + // This is not needed, because prod__reserve calls this function too, + // and therefore, if not enough frames are free on the cached pointers, + // it will update the real pointers. + /* xsk_prod_nb_free(&xsk->tx, XSK_RING_PROD__NUM_DESCS/4); */ +} + +#endif /* USE_XDP */ Index: xdp-server.h =================================================================== RCS file: xdp-server.h diff -N xdp-server.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xdp-server.h 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,109 @@ +/* + * xdp-server.h -- integration of AF_XDP into nsd + * + * Copyright (c) 2024, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ + +#ifndef XDP_SERVER_H +#define XDP_SERVER_H + +#include +#include + +#include "region-allocator.h" + +/* TODO: check if number is sensible */ +#define XDP_NUM_FRAMES 8192*2 +#define XDP_FRAME_SIZE XSK_UMEM__DEFAULT_FRAME_SIZE // 4096 bytes as of Oct 2024 +#define XDP_BUFFER_SIZE XDP_NUM_FRAMES * XDP_FRAME_SIZE +#define XDP_RX_BATCH_SIZE 64 +#define XDP_INVALID_UMEM_FRAME UINT64_MAX +/* ring sizes need tweeking */ +#define XSK_RING_PROD__NUM_DESCS 8192 +#define XSK_RING_CONS__NUM_DESCS 8192 +#define XSK_UMEM_FRAME_HEADROOM XSK_UMEM__DEFAULT_FRAME_HEADROOM +#define XSK_UMEM_FLAGS XSK_UMEM__DEFAULT_FLAGS + +struct nsd; /* avoid recursive header include */ + +struct xsk_umem_info { + struct xsk_ring_prod fq; + struct xsk_ring_cons cq; + struct xsk_umem *umem; + void *buffer; + + uint64_t umem_frame_addr[XDP_NUM_FRAMES]; + uint32_t umem_frame_free; +}; + +struct xsk_socket_info { + struct xsk_ring_cons rx; + struct xsk_ring_prod tx; + struct xsk_umem_info *umem; + struct xsk_socket *xsk; + + uint32_t outstanding_tx; +}; + +struct xdp_ip_address { + struct xdp_ip_address *next; + struct sockaddr_storage addr; +}; + +struct xdp_server { + /* NSD global settings */ + region_type *region; + char const *interface_name; + char const *bpf_prog_filename; + char const *bpf_bpffs_path; + int bpf_prog_should_load; + int force_copy; + + /* track bpf objects and file descriptors */ + int xsk_map_fd; + int bpf_prog_fd; + uint32_t bpf_prog_id; + struct bpf_map *xsk_map; + struct xdp_program *bpf_prog; + + uint32_t interface_index; + uint32_t queue_count; + uint32_t queue_index; + + struct xdp_ip_address *ip_addresses; + + struct query **queries; + struct nsd *nsd; + + /* these items/arrays are shared between processes */ + /* the number of sockets corresponds to the queue_count */ + /* these are allocated using mmap and are automatically unmapped on exit */ + struct xsk_umem_info *umems; + struct xsk_socket_info *xsks; +}; + +/* + * Handle reading and writing packets via XDP + */ +void xdp_handle_recv_and_send(struct xdp_server *xdp); + +/* + * Initialize NSD global XDP settings + * + * - load XDP program if configured + * - set limits + */ +int xdp_server_init(struct xdp_server *xdp); + +/* + * Cleanup NSD global XDP settings + * + * - unload XDP program if loaded by NSD + * - unpin BPF map if pinned and loaded by NSD + */ +void xdp_server_cleanup(struct xdp_server *xdp); + +#endif /* XDP_SERVER_H */ Index: xdp-util.c =================================================================== RCS file: xdp-util.c diff -N xdp-util.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xdp-util.c 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,113 @@ +/* + * xdp-util.h -- set of xdp related helpers + * + * Copyright (c) 2024, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ + +#include "config.h" + +#ifdef USE_XDP + +#include +#include +#include +#include +#include +#include +#include + +/* for the capability modifications */ +/* inspired by https://stackoverflow.com/questions/13183327/drop-root-uid-while-retaining-cap-sys-nice#13186076 */ +#include + +#include "xdp-util.h" + +int ethtool_channels_get(char const *ifname) { + struct ethtool_channels channels; + struct ifreq ifr; + int fd, rc; + uint32_t queue_count = 0; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + return -1; + } + + channels.cmd = ETHTOOL_GCHANNELS; + ifr.ifr_data = (void *)&channels; + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + rc = ioctl(fd, SIOCETHTOOL, &ifr); + if (rc != 0) { + if (errno != EOPNOTSUPP) { + close(fd); + return -errno; + } + } + + if (errno == EOPNOTSUPP) { + queue_count = 1; + } else { + /* ethtool_channels offers + * max_{rx,tx,other,combined} and + * {rx,tx,other,combined}_count + * + * Maybe check for different variations of rx/tx and combined + * queues in the future? */ + if (channels.combined_count > 0) { + queue_count = channels.combined_count; + } else if (channels.rx_count > 0) { + queue_count = channels.rx_count; + } else { + queue_count = 1; + } + } + + close(fd); + return (int) queue_count; +} + +/* CAPABILITY SHENANIGANS */ + +void set_caps(int unset_setid_caps) { +#define NUM_CAPS_ALL 4 +#define NUM_CAPS_NEEDED 2 + cap_t caps; + const cap_value_t cap_list[NUM_CAPS_ALL] = { + CAP_BPF, + /* CAP_SYS_ADMIN, [> SYS_ADMIN needed for xdp_multiprog__get_from_ifindex <] */ + /* CAP_SYS_RESOURCE, */ + CAP_NET_ADMIN, + /* CAP_NET_RAW, */ + CAP_SETUID, + CAP_SETGID + }; + + if (!(caps = cap_init())) + goto out; + + /* set all above capabilities in permitted and effective sets */ + if (cap_set_flag(caps, CAP_EFFECTIVE, NUM_CAPS_ALL, cap_list, CAP_SET)) + goto out; + if (cap_set_flag(caps, CAP_PERMITTED, NUM_CAPS_ALL, cap_list, CAP_SET)) + goto out; + + /* unset unneeded capabilities */ + if (unset_setid_caps) { + if (cap_set_flag(caps, CAP_EFFECTIVE, NUM_CAPS_NEEDED, cap_list + NUM_CAPS_NEEDED, CAP_CLEAR)) + goto out; + if (cap_set_flag(caps, CAP_PERMITTED, NUM_CAPS_NEEDED, cap_list + NUM_CAPS_NEEDED, CAP_CLEAR)) + goto out; + } + + /* set capabilities as configured above to current process */ + if (cap_set_proc(caps)) + goto out; + +out: + cap_free(caps); +} + +#endif /* USE_XDP */ Index: xdp-util.h =================================================================== RCS file: xdp-util.h diff -N xdp-util.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xdp-util.h 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,127 @@ +/* + * xdp-util.h -- set of xdp related helpers + * + * Copyright (c) 2024, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ + +#ifndef XDP_UTIL_H +#define XDP_UTIL_H + +#include +#include +#include +#include + +/* + * Get number of combined or rx queues available on ifname. + */ +int ethtool_channels_get(char const *ifname); + +/* + * Set capabilities to only include the ones needed for using AF_XDP/ + */ +void set_caps(int unset_setid_caps); + +/* + * Add u16 to checksum value and preserve one's complement sum. + */ +static inline __sum16 csum16_add(__sum16 csum, __be16 addend) { + uint16_t res = (uint16_t)csum; + + res += (__u16)addend; + return (__sum16)(res + (res < (__u16)addend)); +} + +/* + * Subtract u16 from checksum value and preserve one's complement sum. + */ +static inline __sum16 csum16_sub(__sum16 csum, __be16 addend) { + return csum16_add(csum, ~addend); +} + +/* + * Replace u16 from checksum value and preserve one's complement sum. + */ +static inline void csum16_replace(__sum16 *sum, __be16 old, __be16 new) { + *sum = ~csum16_add(csum16_sub(~(*sum), old), new); +} + +/* + * Sum up _data_len amount of 16-bit words in _data and add to result. + */ +static inline void csum_add_data(uint32_t *result, + const void *_data, + uint32_t len) { + const uint16_t *data = _data; + while (len > 1) { + *result += *data++; + len -= 2; + } + if (len) + *result += *data & 0xff; + // *result += *(uint8_t *)data; +} + +/* + * Add single 16-bit words to result. + */ +static inline void csum_add_u16(uint32_t *result, uint16_t x) { *result += x; } + +/* + * Apply one's complement to result. + */ +static inline void csum_reduce(uint32_t *result) { + while (*result >> 16) + *result = (*result & 0xffff) + (*result >> 16); +} + +/* + * Calculate UDP checksum with IPv6 pseudo-header + */ +static inline uint16_t calc_csum_udp6(struct udphdr *udp, struct ipv6hdr *ipv6) { + uint32_t sum = 0; + sum += udp->len; + sum += htons(IPPROTO_UDP); + csum_add_data(&sum, &ipv6->saddr, sizeof(ipv6->saddr)); + csum_add_data(&sum, &ipv6->daddr, sizeof(ipv6->daddr)); + + udp->check = 0; + csum_add_data(&sum, udp, ntohs(udp->len)); + /* maybe restore previous checksum to remove side effects? */ + + // reduces sum to 16bit + csum_reduce(&sum); + + if (sum != 0xffff) + return (uint16_t) ~sum; + else + return (uint16_t) sum; +} + +/* + * Calculate UDP checksum with IPv4 pseudo-header + */ +static inline uint16_t calc_csum_udp4(struct udphdr *udp, struct iphdr *ipv4) { + uint32_t sum = 0; + sum += udp->len; + sum += htons(IPPROTO_UDP); + csum_add_data(&sum, &ipv4->saddr, sizeof(ipv4->saddr)); + csum_add_data(&sum, &ipv4->daddr, sizeof(ipv4->daddr)); + + udp->check = 0; + csum_add_data(&sum, udp, ntohs(udp->len)); + /* maybe restore previous checksum to remove side effects? */ + + // reduces sum to 16bit + csum_reduce(&sum); + + if (sum != 0xffff) + return (uint16_t) ~sum; + else + return (uint16_t) sum; +} + +#endif /* XDP_UTIL_H */ Index: xfrd-catalog-zones.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/xfrd-catalog-zones.c,v diff -u -p -r1.2 xfrd-catalog-zones.c --- xfrd-catalog-zones.c 3 Sep 2025 18:46:48 -0000 1.2 +++ xfrd-catalog-zones.c 3 Sep 2025 19:38:50 -0000 @@ -324,7 +324,7 @@ label_plus_dname(const char* label, cons memmove(name.bytes + dname->label_count + 1 /* label_count increases by one */ + 1 /* label type/length byte for label */ + ll, - ((void*)dname) + sizeof(dname_type) + dname->label_count, + ((char*)dname) + sizeof(dname_type) + dname->label_count, dname->name_size); memcpy(name.bytes + dname->label_count + 1 /* label_count increases by one */ Index: xfrd-tcp.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/xfrd-tcp.c,v diff -u -p -r1.31 xfrd-tcp.c --- xfrd-tcp.c 3 Sep 2025 18:46:48 -0000 1.31 +++ xfrd-tcp.c 3 Sep 2025 19:38:50 -0000 @@ -24,13 +24,104 @@ #include "xfrd.h" #include "xfrd-disk.h" #include "util.h" -#ifdef HAVE_TLS_1_3 +#ifdef HAVE_SSL #include #include +#include +#include #endif -#ifdef HAVE_TLS_1_3 +#ifdef HAVE_SSL void log_crypto_err(const char* str); /* in server.c */ + +/* Extract certificate information for logging */ +void +get_cert_info(SSL* ssl, region_type* region, char** cert_serial, + char** key_id, char** cert_algorithm, char** tls_version) +{ + X509* cert = NULL; + ASN1_INTEGER* serial = NULL; + EVP_PKEY* pkey = NULL; + unsigned char key_fingerprint[EVP_MAX_MD_SIZE]; + unsigned int key_fingerprint_len = 0; + const EVP_MD* md = EVP_sha256(); + const char* pkey_name = NULL; + const char* version_name = NULL; + int i; + char temp_buffer[1024]; /* Temporary buffer for serial number */ + + *cert_serial = NULL; + *key_id = NULL; + *cert_algorithm = NULL; + *tls_version = NULL; + +#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE + cert = SSL_get1_peer_certificate(ssl); +#else + cert = SSL_get_peer_certificate(ssl); +#endif + + if (!cert) { + return; + } + + /* Get certificate serial number */ + serial = X509_get_serialNumber(cert); + if (serial) { + BIGNUM* bn = ASN1_INTEGER_to_BN(serial, NULL); + if (bn) { + char* hex_serial = BN_bn2hex(bn); + if (hex_serial) { + snprintf(temp_buffer, sizeof(temp_buffer), "%s", hex_serial); + *cert_serial = region_strdup(region, temp_buffer); + OPENSSL_free(hex_serial); + } + BN_free(bn); + } + } + + /* Get public key identifier (SHA-256 fingerprint) */ + if (X509_pubkey_digest(cert, md, key_fingerprint, &key_fingerprint_len) == 1 && key_fingerprint_len >= 8) { + size_t id_len = 8; /* Use first 8 bytes as key identifier */ + char key_id_buffer[17]; /* 8 bytes * 2 hex chars + null terminator */ + for (i = 0; i < (int)id_len; i++) { + snprintf(key_id_buffer + (i * 2), sizeof(key_id_buffer) - (i * 2), "%02x", key_fingerprint[i]); + } + *key_id = region_strdup(region, key_id_buffer); + } + + /* Get certificate algorithm using OpenSSL's native functions */ + pkey = X509_get_pubkey(cert); + if (pkey) { +#ifdef HAVE_EVP_PKEY_GET0_TYPE_NAME + pkey_name = EVP_PKEY_get0_type_name(pkey); +#else + pkey_name = OBJ_nid2sn(EVP_PKEY_type(EVP_PKEY_id(pkey))); +#endif + if (pkey_name) { + *cert_algorithm = region_strdup(region, pkey_name); + } else { + int pkey_type = EVP_PKEY_id(pkey); + char algo_buffer[32]; + snprintf(algo_buffer, sizeof(algo_buffer), "Unknown(%d)", pkey_type); + *cert_algorithm = region_strdup(region, algo_buffer); + } + EVP_PKEY_free(pkey); + } + + /* Get TLS version using OpenSSL's native function */ + version_name = SSL_get_version(ssl); + if (version_name) { + *tls_version = region_strdup(region, version_name); + } else { + int version = SSL_version(ssl); + char version_buffer[16]; + snprintf(version_buffer, sizeof(version_buffer), "Unknown(%d)", version); + *tls_version = region_strdup(region, version_buffer); + } + + X509_free(cert); +} static SSL_CTX* create_ssl_context() Index: xfrd-tcp.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/xfrd-tcp.h,v diff -u -p -r1.5 xfrd-tcp.h --- xfrd-tcp.h 3 Sep 2025 18:46:48 -0000 1.5 +++ xfrd-tcp.h 3 Sep 2025 19:38:50 -0000 @@ -250,4 +250,9 @@ struct xfrd_tcp_pipeline* xfrd_tcp_pipel /* pick num uint16_t values, from 0..max-1, store in array */ void pick_id_values(uint16_t* array, int num, int max); +#ifdef HAVE_SSL +void get_cert_info(SSL* ssl, region_type* region, char** cert_serial, + char** key_id, char** cert_algorithm, char** tls_version); +#endif + #endif /* XFRD_TCP_H */ Index: xfrd.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/xfrd.c,v diff -u -p -r1.34 xfrd.c --- xfrd.c 3 Sep 2025 18:46:48 -0000 1.34 +++ xfrd.c 3 Sep 2025 19:38:50 -0000 @@ -35,11 +35,20 @@ #ifdef USE_DNSTAP #include "dnstap/dnstap_collector.h" #endif +#ifdef USE_METRICS +#include "metrics.h" +#endif /* USE_METRICS */ #ifdef HAVE_SYSTEMD #include #endif +#ifdef HAVE_SSL +#include +#include +#include +#endif + #define XFRD_UDP_TIMEOUT 10 /* seconds, before a udp request times out */ #define XFRD_NO_IXFR_CACHE 172800 /* 48h before retrying ixfr's after notimpl */ #define XFRD_MAX_ROUNDS 1 /* max number of rounds along the masters */ @@ -212,6 +221,10 @@ xfrd_init(int socket, struct nsd* nsd, i daemon_remote_attach(xfrd->nsd->rc, xfrd); +#ifdef USE_METRICS + daemon_metrics_attach(xfrd->nsd->metrics, xfrd); +#endif /* USE_METRICS */ + xfrd->tcp_set = xfrd_tcp_set_create(xfrd->region, nsd->options->tls_cert_bundle, nsd->options->xfrd_tcp_max, nsd->options->xfrd_tcp_pipeline); xfrd->tcp_set->tcp_timeout = nsd->tcp_timeout; #if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM) @@ -427,8 +440,17 @@ xfrd_shutdown() if (xfrd->nsd->tls_ctx) SSL_CTX_free(xfrd->nsd->tls_ctx); # ifdef HAVE_TLS_1_3 - if (xfrd->tcp_set->ssl_ctx) + if (xfrd->tcp_set->ssl_ctx) { + int i; + for(i=0; itcp_set->tcp_max; i++) { + if(xfrd->tcp_set->tcp_state[i] && + xfrd->tcp_set->tcp_state[i]->ssl) { + SSL_free(xfrd->tcp_set->tcp_state[i]->ssl); + xfrd->tcp_set->tcp_state[i]->ssl = NULL; + } + } SSL_CTX_free(xfrd->tcp_set->ssl_ctx); + } # endif #endif #ifdef USE_DNSTAP @@ -816,10 +838,12 @@ xfrd_process_soa_info_task(struct task_l if(!xfr->sent) continue; assert(xfr->acquired <= before); - /* skip non-applied updates */ - if(!soa_ptr || - soa_ptr->serial != htonl(xfr->msg_new_serial)) - continue; + } + if(hint == soainfo_ok && soa_ptr) { + /* soa_ptr should be true if soainfo_ok. If no + * soa_ptr or soa_info_bad or gone delete all + * the transfers. */ + /* updates are applied in-order, acquired time of most-recent update is used as baseline */ if(!acquired) { @@ -836,7 +860,9 @@ xfrd_process_soa_info_task(struct task_l xfrd->nsd, xfr->xfrfilenumber); return; } - if(consumer_zone && dbzone) + if(consumer_zone && dbzone && + /* Call consumer apply for most recent update*/ + (soa_ptr && soa_ptr->serial == htonl(xfr->msg_new_serial))) apply_xfrs_to_consumer_zone( consumer_zone, dbzone, xfr); } @@ -2523,6 +2549,57 @@ xfrd_handle_received_xfr_packet(xfrd_zon buffer_printf(packet, " TSIG verified with key %s", zone->master->key_options->name); } + + if(zone->master->tls_auth_options && zone->master->tls_auth_options->auth_domain_name) { + buffer_printf(packet, " TLS authenticated with domain %s", + zone->master->tls_auth_options->auth_domain_name); +#ifdef HAVE_TLS_1_3 + /* Get certificate information from the TLS connection */ + if (zone->tcp_conn != -1) { + struct xfrd_tcp_pipeline* tp = NULL; + struct region* tmpregion = region_create(xalloc, free); + char *cert_serial=NULL, *key_id=NULL, + *cert_algorithm=NULL, *tls_version=NULL; + /* Find the pipeline for this zone */ + for (int i = 0; i < xfrd->tcp_set->tcp_max; i++) { + struct xfrd_tcp_pipeline* test_tp = xfrd->tcp_set->tcp_state[i]; + if (test_tp && test_tp->ssl && test_tp->handshake_done) { + /* Check if this pipeline is handling our zone */ + struct xfrd_tcp_pipeline_id* zid; + RBTREE_FOR(zid, struct xfrd_tcp_pipeline_id*, test_tp->zone_per_id) { + if (zid->zone == zone) { + tp = test_tp; + break; + } + } + if (tp) break; + } + } + if(!tmpregion) + tp = NULL; + if(tp && tp->ssl) { + get_cert_info(tp->ssl, tmpregion, &cert_serial, + &key_id, &cert_algorithm, &tls_version); + } else { + tp = NULL; + } + + if (tp && cert_serial && cert_serial[0] != '\0') { + buffer_printf(packet, " cert-serial:%s", cert_serial); + } + if (tp && key_id && key_id[0] != '\0') { + buffer_printf(packet, " key-id:%s", key_id); + } + if (tp && cert_algorithm && cert_algorithm[0] != '\0') { + buffer_printf(packet, " cert-algo:%s", cert_algorithm); + } + if (tp && tls_version && tls_version[0] != '\0') { + buffer_printf(packet, " tls-version:%s", tls_version); + } + region_destroy(tmpregion); + } +#endif + } buffer_flip(packet); diff_write_commit(zone->apex_str, zone->latest_xfr->msg_old_serial, zone->latest_xfr->msg_new_serial, zone->latest_xfr->msg_seq_nr, 1, @@ -2619,7 +2696,7 @@ static void xfrd_handle_reload(int ATTR_UNUSED(fd), short event, void* ATTR_UNUSED(arg)) { /* reload timeout */ - assert(event & EV_TIMEOUT); + assert((event & EV_TIMEOUT)); (void)event; /* timeout wait period after this request is sent */ xfrd->reload_added = 0; @@ -2941,7 +3018,7 @@ static void xfrd_handle_write_timer(int ATTR_UNUSED(fd), short event, void* ATTR_UNUSED(arg)) { /* timeout for write events */ - assert(event & EV_TIMEOUT); + assert((event & EV_TIMEOUT)); (void)event; if(xfrd->nsd->options->zonefiles_write == 0) return; @@ -2978,7 +3055,7 @@ static void xfrd_write_timer_set() static void xfrd_handle_child_timer(int ATTR_UNUSED(fd), short event, void* ATTR_UNUSED(arg)) { - assert(event & EV_TIMEOUT); + assert((event & EV_TIMEOUT)); (void)event; /* only used to wakeup the process to reap children, note the * event is no longer registered */ Index: zonec.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/zonec.h,v diff -u -p -r1.14 zonec.h --- zonec.h 3 Sep 2025 18:46:48 -0000 1.14 +++ zonec.h 3 Sep 2025 19:38:50 -0000 @@ -21,6 +21,11 @@ #define IPSECKEY_IP6 2 #define IPSECKEY_DNAME 3 +#define AMTRELAY_NOGATEWAY 0 /* RFC 8777 */ +#define AMTRELAY_IP4 1 +#define AMTRELAY_IP6 2 +#define AMTRELAY_DNAME 3 + #define LINEBUFSZ 1024 #define DEFAULT_TTL 3600 Index: dnstap/dnstap.m4 =================================================================== RCS file: /cvs/src/usr.sbin/nsd/dnstap/dnstap.m4,v diff -u -p -r1.4 dnstap.m4 --- dnstap/dnstap.m4 1 Apr 2021 09:56:12 -0000 1.4 +++ dnstap/dnstap.m4 3 Sep 2025 19:38:50 -0000 @@ -6,9 +6,9 @@ AC_DEFUN([dt_DNSTAP], [ AC_ARG_ENABLE([dnstap], - AS_HELP_STRING([--enable-dnstap], - [Enable dnstap support (requires fstrm, protobuf-c)]), - [opt_dnstap=$enableval], [opt_dnstap=no]) + AS_HELP_STRING([--disable-dnstap], + [Disable dnstap support (requires fstrm, protobuf-c)]), + [opt_dnstap=$enableval], [opt_dnstap=yes]) AC_ARG_WITH([dnstap-socket-path], AS_HELP_STRING([--with-dnstap-socket-path=pathname], @@ -16,10 +16,41 @@ AC_DEFUN([dt_DNSTAP], [opt_dnstap_socket_path=$withval], [opt_dnstap_socket_path="$1"]) if test "x$opt_dnstap" != "xno"; then - AC_PATH_PROG([PROTOC_C], [protoc-c]) + AC_PATH_PROG([PROTOC], [protoc]) + # 'protoc-c' is deprecated. We use 'protoc' instead. If it can not be + # found, try 'protoc-c'. + if test -z "$PROTOC"; then + AC_PATH_PROG([PROTOC_C], [protoc-c]) + else + PROTOC_C="$PROTOC" + fi if test -z "$PROTOC_C"; then - AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!]) + AC_MSG_ERROR([[The protoc or protoc-c program was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c to provide protoc or protoc-c]]) + fi + + # Check for protoc-gen-c plugin + AC_PATH_PROG([PROTOC_GEN_C], [protoc-gen-c]) + if test -z "$PROTOC_GEN_C"; then + AC_MSG_ERROR([[The protoc-gen-c plugin was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c-compiler to provide protoc-gen-c]]) + fi + + # Test that protoc-gen-c actually works + AC_MSG_CHECKING([if protoc-gen-c plugin works]) + cat > conftest.proto << EOF +syntax = "proto2"; +message TestMessage { + optional string test_field = 1; +} +EOF + if $PROTOC_C --c_out=. conftest.proto >/dev/null 2>&1; then + AC_MSG_RESULT([yes]) + rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h + else + AC_MSG_RESULT([no]) + rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h + AC_MSG_ERROR([[The protoc-gen-c plugin is not working properly. Please ensure protobuf-c-compiler is properly installed]]) fi + AC_ARG_WITH([protobuf-c], AS_HELP_STRING([--with-protobuf-c=path], [Path where protobuf-c is installed, for dnstap]), [ # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0 @@ -46,9 +77,9 @@ AC_DEFUN([dt_DNSTAP], LDFLAGS="$LDFLAGS -L$withval/lib" ]) AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [], - AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!])) + AC_MSG_ERROR([[The fstrm library 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. Please install 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 else $3 Index: doc/ChangeLog =================================================================== RCS file: /cvs/src/usr.sbin/nsd/doc/ChangeLog,v diff -u -p -r1.19 ChangeLog --- doc/ChangeLog 3 Sep 2025 18:46:48 -0000 1.19 +++ doc/ChangeLog 3 Sep 2025 19:38:50 -0000 @@ -1,3 +1,216 @@ +03 September 2025: Jannik + - Fix zonestatfd check + +18 August 2025: Willem + - Merge #455: --with-dbdir option for configure to set the base + directory for the xfrd zone timer state file, the zone list file + and the cookie secrets file. Thanks Simon Josefsson. + +18 August 2025: Willem + - Merge #456: Spelling fixes in metrics.c. Thanks Simon Josefsson. + +05 August 2025: Jannik + - Merge #425: Add experimental XDP (AF_XDP) support for UDP traffic + +5 August 2025: Wouter + - Merge #454 from jaredmauch: handle rare case but seen in + production where data->query is NULL. + - Fix code analyzer warning, and bail out of handle_tcp_writing + and handle_tls_writing early when data->query is NULL. + +18 July 2025: Wouter + - Merge #449: Add useful logging for XoT transfers. + +17 July 2025: Wouter + - Disable TLSv1.2 if TLSv1.3 is available. + +9 July 2025: Wouter + - Update simdzone with support for --enable-pie. + +8 July 2025: Wouter + - Merge #447: Minimize disruptions on reconfig. + - For #447: Updated simdzone to latest commit. With the padding + test changes. + - For #447: use need_to_send_reload to detect if a reload is issued. + - For #447: acl_list_equal already tests for TSIG key changes, so + removed the duplicate checks. + - For #447: log crypto error with the SSL_write error. + +7 July 2025: Willem + - Merge #448: Report larger transfer sizes correctly, also on 32bit + systems. Thanks to Niek Willems for reporting. + +4 July 2025: Wouter + - Fix #446 nsd_size_db_in_mem_bytes (size.db.mem) metric not + updated on reload. + - For #446, remove unused edit. + +13 June 2025: Wouter + - Merge #445: contrib/nsd.openrc.in: use supervise-daemon and + add `need net`. + +11 June 2025: Wouter + - Fix bitwise operators in conditional expressions with parentheses. + - Fix conditional expressions with parentheses for bitwise and. + +22 May 2025: Wouter + - make depend. + +19 May 2025: Wouter + - Fix to remove shell assignment operator from Makefile for DATE. + +13 May 2025: Wouter + - Change default for send-buffer-size to 4m, to mitigate a + cross-layer issue where the UDP socket send buffers are + exhausted waiting for ARP/NDP resolution. Thanks to Reflyable + for the report. + +6 May 2025: Wouter + - Fix #441: SystemD script for NSD prevents using chroot. + - Fix to add checks for compression pointers and too long dnames in + internal dname routines, dname_make and ixfr dname_length. + +30 April 2025: Wouter + - Fix to provide doc for --enable-systemd. + - Fix to remove debug printout for configure dnstap header. + +29 April 2025: Wouter + - The --enable-bind8-stats feature, was already enabled by default, + is described as enabled by default in usage. + - Fix contrib/nsd.spec to omit configure flags that are default or + that do not exist. + - The --enable-zone-stats feature is enabled by default. It can be + turned on with config like `zonestats: "%s"`. + - Fix to remove mention of obsolete root-server option. + - The --enable-ratelimit feature is enabled by default. The + ratelimit value is off by default. It can be turned on with + config like `rrl-ratelimit: 200`. + - Fix mention of draft-rrtypes and root-server configure options. + - The --enable-dnstap feature is enabled by default. If fstrm-devel + or protobuf-c are not found by configure it prints an error. + It can be turned on with config like `dnstap-enable: yes`. + - Fix ci workflow for enable dnstap. + - Fix to remove use of sprintf from metrics. + - Fix for fstrm and protobuf-c for ci workflow coverity-scan. + - Fix for parallel build of dnstap protoc-c output. + - Fix to remove unneeded mkdir from Makefile. + - Fix dnstap to use protoc and keep dnstap_config.h unchanged if + possible. + +25 April 2025: Yorgos + - Prometheus metrics tests require --enable-zone-stats. + - Use '(all)' and '(none)' for the socket server affinity + log output instead of '*' and '-'. + - Add unit test for socket server affinity log output. + - Move xfrd-tcp unit test to its own file. + +25 April 2025: Wouter + - Fix punctuation of nsd -h output for the -a option. + - Fix checkconf unit test for when metrics are not enabled. + - make depend + +24 April 2025: Jannik + - The main branch continues with version 4.12.1 in development. + +17 April 2025: Wouter + - Add autoconf files to gitignore. + +8 April 2025: Wouter + - Fix nsd-checkzone ixfr create cleanup on exit. + +4 April 2025: Wouter + - Fix to update common.sh for speed of kill_pid. + +1 April 2025: Wouter + - Fix escape more characters when printing an RR type with an + unquoted string. + - Fix memory leak in the process of addzone. + +27 March 2025: Wouter + - Fix test checkconf for metrics options. + - Updated simdzone to include fixes for NSAP-PTR, LOC, + uninitialized reads, and comment nit. + - Fix #436: Fix print of RR type NSAP-PTR. + - Fix unit test call to zone_parse_string and initialize padding. + +26 March 2025: Wouter + - Fix multiple zone transfers in one reload so that xfrd does not + check the update as failed and restart the transfer. + - Test for the multiple transfer failure, xfr_over_notify. + - Fix read of ixfr file with rdata subdomain. + - Test for the ixfr rdata subdomain, ixfrout_deldomain. + - Fix note in ixfrout_deldomain test. + +25 March 2025: Wouter + - Fix to please sanitizer for ixfr store of data in cancelled state. + +24 March 2025: Jannik + - Merge #429: Add prometheus metrics + +14 March 2025: Wouter + - Fix log print assert in server sockets for printing '-' empty. + - Fix notify_fmt test for xfrd file location. + - Fix sanitizer warnings in read_uint32. + - Fix sanitizer warning in tsig write of zero length mac and otherdata. + +13 March 2025: Wouter + - Fix ixfr file read to manage numlist in temp domains. + - Fix nsd-mem to clean ixfr storage. + +12 March 2025: Wouter + - Fix ixfr read routine for use after the temp region is freed of rr. + +11 March 2025: Wouter + - Fix in nsd-mem for a zone with ixfr data. + +3 March 2025: Wouter + - Fix that nsec3 prehash after a full transfer can create the nsec3 + zone trees if they are needed. + +19 February 2025: Wouter + - Fix for #430: Confusing documentation: word "outgoing". Add wording + to tcp-count, xfrd-tcp-max, xfrd-tcp-pipeline options. + +18 February 2025: Wouter + - Fix for #430: Confusing documentation: word "outgoing". + +11 February 2025: Willem + - Merge #420: Zones get state "old-serial" with + `nsd-control zonestatus` when the served serial is older than + the one received by the transfer daemon. + +23 January 2025: Willem + - Merge #418: Support for DSYNC, EID, NIMLOC, SINK, TALINK, DOA, + AMTRELAY and IPN resource record types. + +22 January 2025: Wouter + - Fix #426: nsd crashes with patterns in config_apply_pattern. + +20 January 2025: Willem + - code repository continues with 4.11.2 under development. + - Fix re-enable to configure dns-cookies from config file, which + was accidentally removed with the 4.11.1 release. + +19 January 2025: Willem + - NSD 4.11.1 emergency quick-fix release + +17 January 2025: Willem + - Fix #424: Stalled updates after corrupt transfer. + +15 January 2025: Wouter + - Fix whitespace in comment. + +7 January 2025: Willem + - Fix #421: old-main can quit before the reload process received + from old-main that it is done on the reload_listener pipe. + Thanks Otto Retter. + +3 January 2025: Willem + - Fix #414: XoT interoperability with BIND and Knot + +23 December 2024: Willem + - Fix #415: Fix out of tree builds. Thanks Florian Obser (@fobser). + 5 December 2024: Willem - The tag for the 4.11.0rc1 release became the release 4.11.0, on 12 December 2024, the code repository continues with 4.11.1 under Index: doc/README =================================================================== RCS file: /cvs/src/usr.sbin/nsd/doc/README,v diff -u -p -r1.9 README --- doc/README 3 Sep 2025 18:46:48 -0000 1.9 +++ doc/README 3 Sep 2025 19:38:50 -0000 @@ -21,7 +21,7 @@ 1.0 Introduction -This is NSD Name Server Daemon (NSD) version 4.11.0. +This is NSD Name Server Daemon (NSD) version 4.13.0. 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.11.0.tar.gz +Step 1: Unpack the source with gtar -xzvf nsd-4.13.0.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.11.0.tar.gz +$ gtar -xzvf nsd-4.13.0.tar.gz -will unpack the source into the ./nsd-4.11.0 directory... +will unpack the source into the ./nsd-4.13.0 directory... 2.2 Configuring NSD @@ -150,12 +150,6 @@ addition to standard configure options, Specify additional libraries to link with. - --enable-root-server - - Configure NSD as a root server. Unless this option is - specified, NSD will refuse to serve the ``.'' zone as a - misconfiguration safeguard. - --disable-ipv6 Disables IPv6 support in NSD. @@ -169,17 +163,32 @@ addition to standard configure options, This will instruct NSD to be stricter when validating its input. This could lead to a reduced service level. - --enable-bind8-stats + --disable-bind8-stats + + Disable BIND8-like statistics. + + --disable-zone-stats + + Disable per-zone statistics gathering (if enabled, it needs + bind8-stats). - Enables BIND8-like statistics. + --disable-ratelimit - --enable-ratelimit + Disables ratelimiting, based on query name, type and source. - Enables ratelimiting, based on query name, type and source. + --disable-ratelimit-default-is-off - --enable-draft-rrtypes + Disable this to set default of ratelimit to on (this controls + the default, ratelimits can be enabled and disabled in nsd.conf). - Enables draft RRtypes. + --disable-dnstap + + Disable dnstap support (requires fstrm-devel, protobuf-c). + + --enable-systemd + + Compile with systemd support, and then the server notifies libsystemd + when the server is up (it needs pkg-config and systemd-devel). --with-configdir=dir @@ -361,9 +370,6 @@ is not suited for running a . cache. The the . zone you have to make sure that the complete root zone is timely and fully updated. -To prevent misconfiguration, NSD configure has the --enable-root-server -switch, that is by default disabled. - In the config file, you can use patterns. A pattern can have the same configuration statements that a zone can have. And then you can include-pattern: in a zone (or in another pattern) @@ -920,4 +926,4 @@ larger and regular donations please cont see http://www.nlnetlabs.nl/labs/contributors/. -$Id: README,v 1.9 2025/09/03 18:46:48 sthen Exp $ +$Id$ Index: doc/RELNOTES =================================================================== RCS file: /cvs/src/usr.sbin/nsd/doc/RELNOTES,v diff -u -p -r1.17 RELNOTES --- doc/RELNOTES 3 Sep 2025 18:46:48 -0000 1.17 +++ doc/RELNOTES 3 Sep 2025 19:38:50 -0000 @@ -1,5 +1,128 @@ NSD RELEASE NOTES +4.13.0 +================ +FEATURES: + - Use '(all)' and '(none)' for the socket server affinity + log output instead of '*' and '-'. + - The --enable-bind8-stats feature, was already enabled by default, + is described as enabled by default in usage. + - The --enable-zone-stats feature is enabled by default. It can be + turned on with config like `zonestats: "%s"`. + - The --enable-ratelimit feature is enabled by default. The + ratelimit value is off by default. It can be turned on with + config like `rrl-ratelimit: 200`. + - The --enable-dnstap feature is enabled by default. If fstrm-devel + or protobuf-c are not found by configure it prints an error. + It can be turned on with config like `dnstap-enable: yes`. + - Change default for send-buffer-size to 4m, to mitigate a + cross-layer issue where the UDP socket send buffers are + exhausted waiting for ARP/NDP resolution. Thanks to Reflyable + for the report. + - Disable TLSv1.2 if TLSv1.3 is available. + - Merge #449: Add useful logging for XoT transfers. + - Merge #425: Add experimental XDP (AF_XDP) support for UDP traffic + - Merge #455: --with-dbdir option for configure to set the base + directory for the xfrd zone timer state file, the zone list file + and the cookie secrets file. Thanks Simon Josefsson. + - Merge #456: Spelling fixes in metrics.c. Thanks Simon Josefsson. + + +BUG FIXES: + - Fix punctuation of nsd -h output for the -a option. + - Fix checkconf unit test for when metrics are not enabled. + - Prometheus metrics tests require --enable-zone-stats. + - Add unit test for socket server affinity log output. + - Move xfrd-tcp unit test to its own file. + - Fix contrib/nsd.spec to omit configure flags that are default or + that do not exist. + - Fix to remove mention of obsolete root-server option. + - Fix mention of draft-rrtypes and root-server configure options. + - Fix ci workflow for enable dnstap. + - Fix to remove use of sprintf from metrics. + - Fix for fstrm and protobuf-c for ci workflow coverity-scan. + - Fix for parallel build of dnstap protoc-c output. + - Fix to remove unneeded mkdir from Makefile. + - Fix dnstap to use protoc and keep dnstap_config.h unchanged if + possible. + - Fix to provide doc for --enable-systemd. + - Fix to remove debug printout for configure dnstap header. + - Fix #441: SystemD script for NSD prevents using chroot. + - Fix to add checks for compression pointers and too long dnames in + internal dname routines, dname_make and ixfr dname_length. + - Fix to remove shell assignment operator from Makefile for DATE. + - make depend. + - Fix bitwise operators in conditional expressions with parentheses. + - Fix conditional expressions with parentheses for bitwise and. + - Merge #445: contrib/nsd.openrc.in: use supervise-daemon and + add `need net`. + - Fix #446 nsd_size_db_in_mem_bytes (size.db.mem) metric not + updated on reload. + - Merge #447: Minimize disruptions on reconfig. + - For #447: Updated simdzone to latest commit. With the padding + test changes. + - For #447: use need_to_send_reload to detect if a reload is issued. + - For #447: acl_list_equal already tests for TSIG key changes, so + removed the duplicate checks. + - For #447: log crypto error with the SSL_write error. + - Update simdzone with support for --enable-pie. + - Merge #454 from jaredmauch: handle rare case but seen in + production where data->query is NULL. + +4.12.0 +================ +FEATURES: + - Merge #418: Support for DSYNC, EID, NIMLOC, SINK, TALINK, DOA, + AMTRELAY and IPN resource record types. + - Merge #420: Zones get state "old-serial" with + `nsd-control zonestatus` when the served serial is older than + the one received by the transfer daemon. + - Merge #429: Add prometheus metrics + +BUG FIXES: + - Fix re-enable to configure dns-cookies from config file, which was + accidentally removed with the 4.11.1 release. + - Fix #426: nsd crashes with patterns in config_apply_pattern. + - Fix for #430: Confusing documentation: word "outgoing". + - Fix for #430: Confusing documentation: word "outgoing". Add wording + to tcp-count, xfrd-tcp-max, xfrd-tcp-pipeline options. + - Fix that nsec3 prehash after a full transfer can create the nsec3 + zone trees if they are needed. + - Fix in nsd-mem for a zone with ixfr data. + - Fix ixfr read routine for use after the temp region is freed of rr. + - Fix ixfr file read to manage numlist in temp domains. + - Fix nsd-mem to clean ixfr storage. + - Fix log print assert in server sockets for printing '-' empty. + - Fix notify_fmt test for xfrd file location. + - Fix sanitizer warnings in read_uint32. + - Fix sanitizer warning in tsig write of zero length mac and otherdata. + - Fix to please sanitizer for ixfr store of data in cancelled state. + - Fix multiple zone transfers in one reload so that xfrd does not + check the update as failed and restart the transfer. + - Fix read of ixfr file with rdata subdomain. + - Fix test checkconf for metrics options. + - Updated simdzone to include fixes for NSAP-PTR, LOC, + uninitialized reads, and comment nit. + - Fix #436: Fix print of RR type NSAP-PTR. + - Fix unit test call to zone_parse_string and initialize padding. + - Fix escape more characters when printing an RR type with an + unquoted string. + - Fix memory leak in the process of addzone. + - Fix to update common.sh for speed of kill_pid. + - Fix nsd-checkzone ixfr create cleanup on exit. + + +4.11.1 +================ +BUG FIXES: + - Fix #415: Fix out of tree builds. Thanks Florian Obser (@fobser). + - Fix #414: XoT interoperability with BIND and Knot + - Fix #421: old-main can quit before the reload process received + from old-main that it is done on the reload_listener pipe. + Thanks Otto Retter. + - Fix whitespace in comment. + - Fix #424: Stalled updates after corrupt transfer. + 4.11.0 ================ FEATURES: Index: simdzone/CHANGELOG.md =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/CHANGELOG.md,v diff -u -p -r1.1.1.1 CHANGELOG.md --- simdzone/CHANGELOG.md 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/CHANGELOG.md 3 Sep 2025 19:38:50 -0000 @@ -5,6 +5,40 @@ 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.3] - 2025-09-03 + +### Added + +- check_pie: match nsd support (#253). + +### Fixed + +- Fix tests to initialize padding (#252). +- Fix for #253, add acx_nlnetlabs.m4 in the repo and allow CFLAGS passed to + configure to set the flags. + +## [0.2.2] - 2025-04-24 + +### Added + +- Support for EID, NIMLOC, SINK, TALINK, DSYNC, DOA, AMTRELAY and IPN RR types. + +### Fixed + +- Empty base16 and base64 in CDS and CDNSKEY can be represented with a '0'. + As specified in Section 4 of RFC 8078. +- Initialise padding after the file buffer (#249). +- Fix type NSAP-PTR (#250). +- Fix LOC poweroften lookup (#251). + +## [0.2.1] - 2025-01-17 + +### Fixed + +- Cleanup westmere and haswell object files (#244) Thanks @fobser +- Out of tree builds (NLnetLabs/nsd#415) +- Fix function declarations for fallback detection routine in isadetection.h. + ## [0.2.0] - 2024-12-12 ### Added Index: simdzone/Makefile.in =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/Makefile.in,v diff -u -p -r1.2 Makefile.in --- simdzone/Makefile.in 3 Sep 2025 18:46:48 -0000 1.2 +++ simdzone/Makefile.in 3 Sep 2025 19:38:50 -0000 @@ -9,7 +9,7 @@ WESTMERE = @HAVE_WESTMERE@ HASWELL = @HAVE_HASWELL@ CC = @CC@ -CPPFLAGS = @CPPFLAGS@ -Iinclude -I$(SOURCE)/include -Isrc -I$(SOURCE)/src -I. +CPPFLAGS = @CPPFLAGS@ -Iinclude -I$(SOURCE)/include -I$(SOURCE)/src -I. CFLAGS = @CFLAGS@ DEPFLAGS = @DEPFLAGS@ VPATH = @srcdir@ @@ -43,6 +43,7 @@ all: libzone.a clean: @rm -f .depend @rm -f libzone.a $(OBJECTS) $(EXPORT_HEADER) + @rm -f $($(WESTMERE)_OBJECTS) $($(HASWELL)_OBJECTS) distclean: clean @rm -f Makefile config.h config.log config.status @@ -55,22 +56,22 @@ maintainer-clean: realclean devclean: realclean @rm -rf config.h.in configure -libzone.a: $(OBJECTS) $($(WESTMERE)_OBJECTS) $($(HASWELL)_OBJECTS) +libzone.a: $(OBJECTS) $($(WESTMERE)_OBJECTS) $($(HASWELL)_OBJECTS) Makefile $(AR) rcs libzone.a $(OBJECTS) $($(WESTMERE)_OBJECTS) $($(HASWELL)_OBJECTS) $(EXPORT_HEADER): @mkdir -p include/zone @echo "#define ZONE_EXPORT" > $(EXPORT_HEADER) -$(WESTMERE_OBJECTS): $(EXPORT_HEADER) .depend +$(WESTMERE_OBJECTS): $(EXPORT_HEADER) .depend Makefile @mkdir -p src/westmere $(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) -march=westmere -o $@ -c $(SOURCE)/$(@:.o=.c) -$(HASWELL_OBJECTS): $(EXPORT_HEADER) .depend +$(HASWELL_OBJECTS): $(EXPORT_HEADER) .depend Makefile @mkdir -p src/haswell $(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) -march=haswell -o $@ -c $(SOURCE)/$(@:.o=.c) -$(OBJECTS): $(EXPORT_HEADER) .depend +$(OBJECTS): $(EXPORT_HEADER) .depend Makefile @mkdir -p src/fallback $(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -c $(SOURCE)/$(@:.o=.c) @touch $@ Index: simdzone/acx_nlnetlabs.m4 =================================================================== RCS file: simdzone/acx_nlnetlabs.m4 diff -N simdzone/acx_nlnetlabs.m4 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ simdzone/acx_nlnetlabs.m4 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,1544 @@ +# acx_nlnetlabs.m4 - common macros for configure checks +# Copyright 2009, Wouter Wijngaards, NLnet Labs. +# BSD licensed. +# +# Version 48 +# 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. +# 2023-05-04 fix to remove unused whitespace. +# 2023-01-26 fix -Wstrict-prototypes. +# 2022-09-01 fix checking if nonblocking sockets work on OpenBSD. +# 2021-08-17 fix sed script in ssldir split handling. +# 2021-08-17 fix for openssl to detect split version, with ssldir_include +# and ssldir_lib output directories. +# 2021-07-30 fix for openssl use of lib64 directory. +# 2021-06-14 fix nonblocking test to use host instead of target for mingw test. +# 2021-05-17 fix nonblocking socket test from grep on mingw32 to mingw for +# 64bit compatibility. +# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS. +# 2021-01-05 fix defun for aclocal +# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE +# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0). +# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0. +# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0). +# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20 +# 2015-12-11 FLTO check for new OSX, clang. +# 2015-11-18 spelling check fix. +# 2015-11-05 ACX_SSL_CHECKS no longer adds -ldl needlessly. +# 2015-08-28 ACX_CHECK_PIE and ACX_CHECK_RELRO_NOW added. +# 2015-03-17 AHX_CONFIG_REALLOCARRAY added +# 2013-09-19 FLTO help text improved. +# 2013-07-18 Enable ACX_CHECK_COMPILER_FLAG to test for -Wstrict-prototypes +# 2013-06-25 FLTO has --disable-flto option. +# 2013-05-03 Update W32_SLEEP for newer mingw that links but not defines it. +# 2013-03-22 Fix ACX_RSRC_VERSION for long version numbers. +# 2012-02-09 Fix AHX_MEMCMP_BROKEN with undef in compat/memcmp.h. +# 2012-01-20 Fix COMPILER_FLAGS_UNBOUND for gcc 4.6.2 assigned-not-used-warns. +# 2011-12-05 Fix getaddrinfowithincludes on windows with fedora16 mingw32-gcc. +# Fix ACX_MALLOC for redefined malloc error. +# Fix GETADDRINFO_WITH_INCLUDES to add -lws2_32 +# 2011-11-10 Fix FLTO test to not drop a.out in current directory. +# 2011-11-01 Fix FLTO test for llvm on Lion. +# 2011-08-01 Fix nonblock test (broken at v13). +# 2011-08-01 Fix autoconf 2.68 warnings +# 2011-06-23 Add ACX_CHECK_FLTO to check -flto. +# 2010-08-16 Fix FLAG_OMITTED for AS_TR_CPP changes in autoconf-2.66. +# 2010-07-02 Add check for ss_family (for minix). +# 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS. +# 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end. +# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS separate, -ldl +# 2010-02-01 added ACX_CHECK_MEMCMP_SIGNED, AHX_MEMCMP_BROKEN +# 2010-01-20 added AHX_COONFIG_STRLCAT +# 2009-07-14 U_CHAR detection improved for windows crosscompile. +# added ACX_FUNC_MALLOC +# fixup some #if to #ifdef +# NONBLOCKING test for mingw crosscompile. +# 2009-07-13 added ACX_WITH_SSL_OPTIONAL +# 2009-07-03 fixup LDFLAGS for empty ssl dir. +# +# Automates some of the checking constructs. Aims at portability for POSIX. +# Documentation for functions is below. +# +# the following macro's are provided in this file: +# (see below for details on each macro). +# +# ACX_ESCAPE_BACKSLASH - escape backslashes in var for C-preproc. +# ACX_RSRC_VERSION - create windows resource version number. +# ACX_CHECK_COMPILER_FLAG - see if cc supports a flag. +# ACX_CHECK_ERROR_FLAGS - see which flag is -werror (used below). +# ACX_CHECK_COMPILER_FLAG_NEEDED - see if flags make the code compile cleanly. +# 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_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. +# ACX_TYPE_U_CHAR - u_char type. +# ACX_TYPE_RLIM_T - rlim_t type. +# ACX_TYPE_SOCKLEN_T - socklen_t type. +# ACX_TYPE_IN_ADDR_T - in_addr_t type. +# ACX_TYPE_IN_PORT_T - in_port_t type. +# ACX_ARG_RPATH - add --disable-rpath option. +# ACX_WITH_SSL - add --with-ssl option, link -lcrypto. +# ACX_WITH_SSL_OPTIONAL - add --with-ssl option, link -lcrypto, +# where --without-ssl is also accepted +# ACX_LIB_SSL - setup to link -lssl. +# ACX_SYS_LARGEFILE - improved sys_largefile, fseeko, >2G files. +# ACX_CHECK_GETADDRINFO_WITH_INCLUDES - find getaddrinfo, portably. +# ACX_FUNC_DEPRECATED - see if func is deprecated. +# ACX_CHECK_NONBLOCKING_BROKEN - see if nonblocking sockets really work. +# ACX_MKDIR_ONE_ARG - determine mkdir(2) number of arguments. +# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably. +# ACX_FUNC_MALLOC - check malloc, define replacement . +# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format. +# 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. +# AHX_CONFIG_MAXHOSTNAMELEN - define MAXHOSTNAMELEN if needed. +# AHX_CONFIG_IPV6_MIN_MTU - define IPV6_MIN_MTU if needed. +# AHX_CONFIG_SNPRINTF - snprintf compat prototype +# AHX_CONFIG_INET_PTON - inet_pton compat prototype +# AHX_CONFIG_INET_NTOP - inet_ntop compat prototype +# AHX_CONFIG_INET_ATON - inet_aton compat prototype +# AHX_CONFIG_MEMMOVE - memmove compat prototype +# AHX_CONFIG_STRLCAT - strlcat compat prototype +# AHX_CONFIG_STRLCPY - strlcpy compat prototype +# AHX_CONFIG_GMTIME_R - gmtime_r compat prototype +# AHX_CONFIG_W32_SLEEP - w32 compat for sleep +# AHX_CONFIG_W32_USLEEP - w32 compat for usleep +# AHX_CONFIG_W32_RANDOM - w32 compat for random +# AHX_CONFIG_W32_SRANDOM - w32 compat for srandom +# AHX_CONFIG_W32_FD_SET_T - w32 detection of FD_SET_T. +# ACX_CFLAGS_STRIP - strip one flag from CFLAGS +# ACX_STRIP_EXT_FLAGS - strip extension flags from CFLAGS +# AHX_CONFIG_FLAG_OMITTED - define omitted flag +# AHX_CONFIG_FLAG_EXT - define omitted extension flag +# AHX_CONFIG_EXT_FLAGS - define the stripped extension flags +# ACX_CHECK_MEMCMP_SIGNED - check if memcmp uses signed characters. +# AHX_MEMCMP_BROKEN - replace memcmp func for CHECK_MEMCMP_SIGNED. +# ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family +# ACX_CHECK_PIE - add --enable-pie option and check if works +# ACX_CHECK_RELRO_NOW - add --enable-relro-now option and check it +# + +dnl Escape backslashes as \\, for C:\ paths, for the C preprocessor defines. +dnl for example, ACX_ESCAPE_BACKSLASH($from_var, to_var) +dnl $1: the text to change. +dnl $2: the result. +AC_DEFUN([ACX_ESCAPE_BACKSLASH], [$2="`echo $1 | sed -e 's/\\\\/\\\\\\\\/g'`" +]) + +dnl Calculate comma separated windows-resource numbers from package version. +dnl Picks the first three(,0) or four numbers out of the name. +dnl $1: variable for the result +AC_DEFUN([ACX_RSRC_VERSION], +[$1=[`echo $PACKAGE_VERSION | sed -e 's/^[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\).*$/\1,\2,\3,\4/' -e 's/^[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9]*$/\1,\2,\3,0/' `] +]) + +dnl Routine to help check for compiler flags. +dnl Checks if the compiler will accept the flag. +dnl $1: the flag without a - in front, so g to check -g. +dnl $2: executed if yes +dnl $3: executed if no +AC_DEFUN([ACX_CHECK_COMPILER_FLAG], +[ +AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(whether $CC supports -$1) +cache=`echo $1 | sed 'y%.=/+-%___p_%'` +AC_CACHE_VAL(cv_prog_cc_flag_$cache, +[ +echo 'void f(void){}' >conftest.c +if test -z "`$CC $CPPFLAGS $CFLAGS -$1 -c conftest.c 2>&1`"; then +eval "cv_prog_cc_flag_$cache=yes" +else +eval "cv_prog_cc_flag_$cache=no" +fi +rm -f conftest conftest.o conftest.c +]) +if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then +AC_MSG_RESULT(yes) +: +$2 +else +AC_MSG_RESULT(no) +: +$3 +fi +]) + +dnl setup flags for ACX_CHECK_COMPILER_FLAG_NEEDED +dnl ERRFLAG: result, compiler flag to turn warnings into errors +AC_DEFUN([ACX_CHECK_ERROR_FLAGS], +[ +ACX_CHECK_COMPILER_FLAG(Werror, [ERRFLAG="-Werror"], [ERRFLAG="-errwarn"]) +ACX_CHECK_COMPILER_FLAG(Wall, [ERRFLAG="$ERRFLAG -Wall"], + [ERRFLAG="$ERRFLAG -errfmt"]) +]) + +dnl Routine to help check for needed compiler flags. +dnl $1: flags for CC +dnl $2: the includes and code +dnl $3: if the given code only compiles with the flag, execute argument 3 +dnl $4: if the given code compiles without the flag, execute argument 4 +dnl $5: with and without flag the compile fails, execute argument 5. +AC_DEFUN([ACX_CHECK_COMPILER_FLAG_NEEDED], +[ +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([ACX_CHECK_ERROR_FLAGS]) +AC_MSG_CHECKING(whether we need $1 as a flag for $CC) +cache=AS_TR_SH($1) +dnl cache=`echo $1 | sed 'y%.=/+- %___p__%'` +AC_CACHE_VAL(cv_prog_cc_flag_needed_$cache, +[ +echo '$2' > conftest.c +echo 'void f(void){}' >>conftest.c +if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then +eval "cv_prog_cc_flag_needed_$cache=no" +else +[ +if test -z "`$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1`"; then +eval "cv_prog_cc_flag_needed_$cache=yes" +else +eval "cv_prog_cc_flag_needed_$cache=fail" +#echo 'Test with flag fails too!' +#cat conftest.c +#echo "$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1" +#echo `$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1` +#exit 1 +fi +] +fi +rm -f conftest conftest.c conftest.o +]) +if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then +AC_MSG_RESULT(yes) +: +$3 +else +if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then +AC_MSG_RESULT(no) +#echo 'Test with flag is no!' +#cat conftest.c +#echo "$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1" +#echo `$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1` +#exit 1 +: +$4 +else +AC_MSG_RESULT(failed) +: +$5 +fi +fi +]) + +dnl Check for CC dependency flag +dnl DEPFLAG: set to flag that generates dependencies. +AC_DEFUN([ACX_DEPFLAG], +[ +AC_MSG_CHECKING([$CC dependency flag]) +echo 'void f(void){}' >conftest.c +if test "`$CC -MM conftest.c 2>&1`" = "conftest.o: conftest.c"; then + DEPFLAG="-MM" +else + if test "`$CC -xM1 conftest.c 2>&1`" = "conftest.o: conftest.c"; then + DEPFLAG="-xM1" + else + DEPFLAG="-MM" # dunno do something + fi +fi +AC_MSG_RESULT($DEPFLAG) +rm -f conftest.c +AC_SUBST(DEPFLAG) +]) + +dnl Determine flags that gives POSIX and BSD functionality. +dnl CFLAGS is modified for the result. +AC_DEFUN([ACX_DETERMINE_EXT_FLAGS_UNBOUND], +[ +ACX_CHECK_COMPILER_FLAG(std=c99, [C99FLAG="-std=c99"]) +ACX_CHECK_COMPILER_FLAG(xc99, [C99FLAG="-xc99"]) + +AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT]) + +ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE, +[ +#include "confdefs.h" +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif + +int test(void) { + int a; + char **opts = NULL; + struct timeval tv; + char *t; + time_t time = 0; + char *buf = NULL; + const char* str = NULL; + struct msghdr msg; + msg.msg_control = 0; + t = ctime_r(&time, buf); + tv.tv_usec = 10; + srandom(32); + a = getopt(2, opts, "a"); + a = isascii(32); + str = gai_strerror(0); + if(str && t && tv.tv_usec && msg.msg_control) + a = 0; + return a; +} +], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"]) + +ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE, +[ +#include "confdefs.h" +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif + +int test(void) { + int a; + char **opts = NULL; + struct timeval tv; + char *t; + time_t time = 0; + char *buf = NULL; + const char* str = NULL; + struct msghdr msg; + msg.msg_control = 0; + t = ctime_r(&time, buf); + tv.tv_usec = 10; + srandom(32); + a = getopt(2, opts, "a"); + a = isascii(32); + str = gai_strerror(0); + if(str && t && tv.tv_usec && msg.msg_control) + a = 0; + return a; +} +], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"]) + +ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG, +[ +#include +#include +int test(void) { + int a = 0; + return a; +} +], [CFLAGS="$CFLAGS $C99FLAG"]) + +ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE -D_DEFAULT_SOURCE, +[ +#include + +int test(void) { + int a; + a = isascii(32); + return a; +} +], [CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE"]) + +ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE, +[ +#include + +int test(void) { + struct in6_pktinfo inf; + int a = (int)sizeof(inf); + return a; +} +], [CFLAGS="$CFLAGS -D_GNU_SOURCE"]) + +# check again for GNU_SOURCE for setresgid. May fail if setresgid +# is not available at all. -D_FRSRESGID is to make this check unique. +# otherwise we would get the previous cached result. +ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE -D_FRSRESGID, +[ +#include + +int test(void) { + int a = setresgid(0,0,0); + a = setresuid(0,0,0); + return a; +} +], [CFLAGS="$CFLAGS -D_GNU_SOURCE"]) + +ACX_CHECK_COMPILER_FLAG_NEEDED(-D_POSIX_C_SOURCE=200112, +[ +#include "confdefs.h" +#ifdef HAVE_TIME_H +#include +#endif +#include + +int test(void) { + int a = 0; + char *t; + time_t time = 0; + char *buf = NULL; + const char* str = NULL; + t = ctime_r(&time, buf); + str = gai_strerror(0); + if(t && str) + a = 0; + return a; +} +], [CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112"]) + +ACX_CHECK_COMPILER_FLAG_NEEDED(-D__EXTENSIONS__, +[ +#include "confdefs.h" +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif +#include +#ifdef HAVE_GETOPT_H +#include +#endif + +int test(void) { + int a; + char **opts = NULL; + struct timeval tv; + tv.tv_usec = 10; + srandom(32); + a = getopt(2, opts, "a"); + a = isascii(32); + if(tv.tv_usec) + a = 0; + return a; +} +], [CFLAGS="$CFLAGS -D__EXTENSIONS__"]) + +])dnl End of ACX_DETERMINE_EXT_FLAGS_UNBOUND + +dnl Check if CC supports -flto. +dnl in a way that supports clang and suncc (that flag does something else, +dnl but fails to link). It sets it in CFLAGS if it works. +AC_DEFUN([ACX_CHECK_FLTO], [ + AC_ARG_ENABLE([flto], AS_HELP_STRING([--disable-flto], [Disable link-time optimization (gcc specific option)])) + AS_IF([test "x$enable_flto" != "xno"], [ + AC_MSG_CHECKING([if $CC supports -flto]) + BAKCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -flto" + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ + if $CC $CFLAGS -o conftest conftest.c 2>&1 | $GREP -e "warning: no debug symbols in executable" -e "warning: object" >/dev/null; then + CFLAGS="$BAKCFLAGS" + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi + rm -f conftest conftest.c conftest.o + ], [CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)]) + ]) +]) + +dnl Check the printf-format attribute (if any) +dnl result in HAVE_ATTR_FORMAT. +dnl Make sure you also include the AHX_CONFIG_FORMAT_ATTRIBUTE. +AC_DEFUN([ACX_CHECK_FORMAT_ATTRIBUTE], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute) +AC_CACHE_VAL(ac_cv_c_format_attribute, +[ac_cv_c_format_attribute=no +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +void f (char *format, ...) __attribute__ ((format (printf, 1, 2))); +void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2))); +]], [[ + f ("%s", "str"); +]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"]) +]) + +AC_MSG_RESULT($ac_cv_c_format_attribute) +if test $ac_cv_c_format_attribute = yes; then + AC_DEFINE(HAVE_ATTR_FORMAT, 1, [Whether the C compiler accepts the "format" attribute]) +fi +])dnl End of ACX_CHECK_FORMAT_ATTRIBUTE + +dnl Setup ATTR_FORMAT config.h parts. +dnl make sure you call ACX_CHECK_FORMAT_ATTRIBUTE also. +AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE], +[ +#ifdef HAVE_ATTR_FORMAT +# define ATTR_FORMAT(archetype, string_index, first_to_check) \ + __attribute__ ((format (archetype, string_index, first_to_check))) +#else /* !HAVE_ATTR_FORMAT */ +# define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */ +#endif /* !HAVE_ATTR_FORMAT */ +]) + +dnl Check how to mark function arguments as 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]) +AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute) +AC_CACHE_VAL(ac_cv_c_unused_attribute, +[ac_cv_c_unused_attribute=no +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +void f (char *u __attribute__((unused))); +]], [[ + f ("x"); +]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"]) +]) + +dnl Setup ATTR_UNUSED config.h parts. +dnl make sure you call ACX_CHECK_UNUSED_ATTRIBUTE also. +AC_DEFUN([AHX_CONFIG_UNUSED_ATTRIBUTE], +[ +#if defined(DOXYGEN) +# define ATTR_UNUSED(x) x +#elif defined(__cplusplus) +# define ATTR_UNUSED(x) +#elif defined(HAVE_ATTR_UNUSED) +# define ATTR_UNUSED(x) x __attribute__((unused)) +#else /* !HAVE_ATTR_UNUSED */ +# define ATTR_UNUSED(x) x +#endif /* !HAVE_ATTR_UNUSED */ +]) + +AC_MSG_RESULT($ac_cv_c_unused_attribute) +if test $ac_cv_c_unused_attribute = yes; then + AC_DEFINE(HAVE_ATTR_UNUSED, 1, [Whether the C compiler accepts the "unused" 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. +AC_DEFUN([AC_PROG_F77], [:]) +AC_DEFUN([AC_PROG_FC], [:]) +AC_DEFUN([AC_PROG_CXX], [:]) +AC_DEFUN([AC_PROG_CXXCPP], [:]) +AC_DEFUN([AC_PROG_OBJC], [:]) +AC_DEFUN([AC_PROG_OBJCCPP], [:]) +AC_DEFUN([AC_LIBTOOL_CXX], [:]) +AC_DEFUN([AC_LIBTOOL_F77], [:]) +# always use ./libtool unless override from commandline (libtool=mylibtool) +if test -z "$libtool"; then + libtool="./libtool" +fi +AC_SUBST(libtool) +# avoid libtool max commandline length test on systems that fork slowly. +AC_CANONICAL_HOST +if echo "$host_os" | grep "sunos4" >/dev/null; then + lt_cv_sys_max_cmd_len=32750; +fi +AC_PATH_TOOL(AR, ar, [false]) +if test $AR = false; then + AC_MSG_ERROR([Cannot find 'ar', please extend PATH to include it]) +fi +]) + +dnl Perform libtool check, portably, only for C +AC_DEFUN([ACX_LIBTOOL_C_ONLY], [ +dnl as a requirement so that is gets called before LIBTOOL +dnl because libtools 'AC_REQUIRE' names are right after this one, before +dnl this function contents. +AC_REQUIRE([ACX_LIBTOOL_C_PRE]) +LT_INIT +]) + +dnl Detect if u_char type is defined, otherwise define it. +AC_DEFUN([ACX_TYPE_U_CHAR], +[AC_CHECK_TYPE([u_char], , + [AC_DEFINE([u_char], [unsigned char], [Define to 'unsigned char if not defined])], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_WINSOCK2_H +# include +#endif +]) ]) + +dnl Detect if rlim_t type is defined, otherwise define it. +AC_DEFUN([ACX_TYPE_RLIM_T], +[AC_CHECK_TYPE(rlim_t, , + [AC_DEFINE([rlim_t], [unsigned long], [Define to 'int' if not defined])], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif +]) ]) + +dnl Detect if socklen_t type is defined, otherwise define it. +AC_DEFUN([ACX_TYPE_SOCKLEN_T], +[ +AC_CHECK_TYPE(socklen_t, , + [AC_DEFINE([socklen_t], [int], [Define to 'int' if not defined])], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_WS2TCPIP_H +# include +#endif +]) ]) + +dnl Detect if in_addr_t type is defined, otherwise define it. +AC_DEFUN([ACX_TYPE_IN_ADDR_T], +[ AC_CHECK_TYPE(in_addr_t, [], [AC_DEFINE([in_addr_t], [uint32_t], [in_addr_t])], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +]) ]) + +dnl Detect if in_port_t type is defined, otherwise define it. +AC_DEFUN([ACX_TYPE_IN_PORT_T], +[ AC_CHECK_TYPE(in_port_t, [], [AC_DEFINE([in_port_t], [uint16_t], [in_port_t])], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +]) ]) + +dnl Add option to disable the evil rpath. Check whether to use rpath or not. +dnl Adds the --disable-rpath option. Uses trick to edit the ./libtool. +AC_DEFUN([ACX_ARG_RPATH], +[ +AC_ARG_ENABLE(rpath, + [ --disable-rpath disable hardcoded rpath (default=enabled)], + enable_rpath=$enableval, enable_rpath=yes) +if test "x$enable_rpath" = xno; then + dnl AC_MSG_RESULT([Fixing libtool for -rpath problems.]) + AC_CONFIG_COMMANDS([disable-rpath], [ + sed < libtool > libtool-2 \ + 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_RPATH_SED__ "/' + mv libtool-2 libtool + chmod 755 libtool + libtool="./libtool" + ]) +fi +]) + +dnl Add a -R to the RUNTIME_PATH. Only if rpath is enabled and it is +dnl an absolute path. +dnl $1: the pathname to add. +AC_DEFUN([ACX_RUNTIME_PATH_ADD], [ + if test "x$enable_rpath" = xyes; then + if echo "$1" | grep "^/" >/dev/null; then + RUNTIME_PATH="$RUNTIME_PATH -R$1" + fi + fi +]) + +dnl Common code for both ACX_WITH_SSL and ACX_WITH_SSL_OPTIONAL +dnl Takes one argument; the withval checked in those 2 functions +dnl sets up the environment for the given openssl path +AC_DEFUN([ACX_SSL_CHECKS], [ + withval=$1 + if test x_$withval != x_no; then + AC_MSG_CHECKING(for SSL) + if test -n "$withval"; then + dnl look for openssl install with different version, eg. + dnl in /usr/include/openssl11/openssl/ssl.h + dnl and /usr/lib64/openssl11/libssl.so + dnl with the --with-ssl=/usr/include/openssl11 + if test ! -f "$withval/include/openssl/ssl.h" -a -f "$withval/openssl/ssl.h"; then + ssldir="$withval" + found_ssl="yes" + withval="" + ssldir_include="$ssldir" + dnl find the libdir + ssldir_lib=`echo $ssldir | sed -e 's/include/lib/'` + if test -f "$ssldir_lib/libssl.a" -o -f "$ssldir_lib/libssl.so"; then + : # found here + else + ssldir_lib=`echo $ssldir | sed -e 's/include/lib64/'` + if test -f "$ssldir_lib/libssl.a" -o -f "$ssldir_lib/libssl.so"; then + : # found here + else + AC_MSG_ERROR([Could not find openssl lib file, $ssldir_lib/libssl.[so,a], pass like "/usr/local" or "/usr/include/openssl11"]) + fi + fi + fi + fi + if test x_$withval = x_ -o x_$withval = x_yes; then + withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr" + fi + for dir in $withval; do + ssldir="$dir" + if test -f "$dir/include/openssl/ssl.h"; then + found_ssl="yes" + ssldir_include="$ssldir/include" + if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then + ssldir_lib="$ssldir/lib64" + else + ssldir_lib="$ssldir/lib" + fi + break; + fi + done + if test x_$found_ssl != x_yes; then + AC_MSG_ERROR(Cannot find the SSL libraries in $withval) + else + AC_MSG_RESULT(found in $ssldir) + AC_DEFINE_UNQUOTED([HAVE_SSL], [], [Define if you have the SSL libraries installed.]) + HAVE_SSL=yes + dnl assume /usr is already in the include, lib and dynlib paths. + if test "$ssldir" != "/usr"; then + CPPFLAGS="$CPPFLAGS -I$ssldir_include" + LIBSSL_CPPFLAGS="$LIBSSL_CPPFLAGS -I$ssldir_include" + LDFLAGS="$LDFLAGS -L$ssldir_lib" + LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir_lib" + ACX_RUNTIME_PATH_ADD([$ssldir_lib]) + fi + + AC_MSG_CHECKING([for EVP_sha256 in -lcrypto]) + LIBS="$LIBS -lcrypto" + LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int EVP_sha256(void); + (void)EVP_sha256(); + ]])],[ + AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_EVP_SHA256], 1, + [If you have EVP_sha256]) + ],[ + AC_MSG_RESULT(no) + # check if -lwsock32 or -lgdi32 are needed. + BAKLIBS="$LIBS" + BAKSSLLIBS="$LIBSSL_LIBS" + LIBS="$LIBS -lgdi32 -lws2_32" + LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32" + AC_MSG_CHECKING([if -lcrypto needs -lgdi32]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int EVP_sha256(void); + (void)EVP_sha256(); + ]])],[ + AC_DEFINE([HAVE_EVP_SHA256], 1, + [If you have EVP_sha256]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + LIBS="$BAKLIBS" + LIBSSL_LIBS="$BAKSSLLIBS" + + LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32" + LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32" + AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int EVP_sha256(void); + (void)EVP_sha256(); + ]])],[ + AC_DEFINE([HAVE_EVP_SHA256], 1, + [If you have EVP_sha256]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + LIBS="$BAKLIBS" + LIBSSL_LIBS="$BAKSSLLIBS" + + LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a" + LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a" + AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int EVP_sha256(void); + (void)EVP_sha256(); + ]])],[ + AC_DEFINE([HAVE_EVP_SHA256], 1, + [If you have EVP_sha256]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + LIBS="$BAKLIBS" + LIBSSL_LIBS="$BAKSSLLIBS" + + LIBS="$LIBS -ldl" + LIBSSL_LIBS="$LIBSSL_LIBS -ldl" + AC_MSG_CHECKING([if -lcrypto needs -ldl]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int EVP_sha256(void); + (void)EVP_sha256(); + ]])],[ + AC_DEFINE([HAVE_EVP_SHA256], 1, + [If you have EVP_sha256]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + LIBS="$BAKLIBS" + LIBSSL_LIBS="$BAKSSLLIBS" + LIBS="$LIBS -ldl -pthread" + LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread" + AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ + int EVP_sha256(void); + (void)EVP_sha256(); + ]])],[ + AC_DEFINE([HAVE_EVP_SHA256], 1, + [If you have EVP_sha256]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required]) + ]) + ]) + ]) + ]) + ]) + ]) + fi + AC_SUBST(HAVE_SSL) + AC_SUBST(RUNTIME_PATH) + fi +AC_CHECK_HEADERS([openssl/ssl.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([openssl/err.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([openssl/rand.h],,, [AC_INCLUDES_DEFAULT]) +])dnl End of ACX_SSL_CHECKS + +dnl Check for SSL, where SSL is mandatory +dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found +dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS. +dnl Checks main header files of SSL. +dnl +AC_DEFUN([ACX_WITH_SSL], +[ +AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl + /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr or specify like /usr/include/openssl11)]),[ + ],[ + withval="yes" + ]) + if test x_$withval = x_no; then + AC_MSG_ERROR([Need SSL library to do digital signature cryptography]) + fi + ACX_SSL_CHECKS($withval) +])dnl End of ACX_WITH_SSL + +dnl Check for SSL, where ssl is optional (--without-ssl is allowed) +dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found +dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS. +dnl Checks main header files of SSL. +dnl +AC_DEFUN([ACX_WITH_SSL_OPTIONAL], +[ +AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl + /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr or specify like /usr/include/openssl11)]),[ + ],[ + withval="yes" + ]) + ACX_SSL_CHECKS($withval) +])dnl End of ACX_WITH_SSL_OPTIONAL + +dnl Setup to use -lssl +dnl To use -lcrypto, use the ACX_WITH_SSL setup (before this one). +AC_DEFUN([ACX_LIB_SSL], +[ +# check if libssl needs libdl +BAKLIBS="$LIBS" +LIBS="-lssl $LIBS" +AC_MSG_CHECKING([if libssl needs libdl]) +AC_TRY_LINK_FUNC([SSL_CTX_new], [ + AC_MSG_RESULT([no]) + LIBS="$BAKLIBS" +] , [ + AC_MSG_RESULT([yes]) + LIBS="$BAKLIBS" + AC_SEARCH_LIBS([dlopen], [dl]) +]) ])dnl End of ACX_LIB_SSL + +dnl Setup to use very large files (>2Gb). +dnl setups fseeko and its own +AC_DEFUN([ACX_SYS_LARGEFILE], +[ +AC_SYS_LARGEFILE +dnl try to see if an additional _LARGEFILE_SOURCE 1 is needed to get fseeko +ACX_CHECK_COMPILER_FLAG_NEEDED(-D_LARGEFILE_SOURCE=1, +[ +#include +int test(void) { + int a = fseeko(stdin, 0, 0); + return a; +} +], [CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE=1"]) +]) + +dnl Check getaddrinfo. +dnl Works on linux, solaris, bsd and windows(links winsock). +dnl defines HAVE_GETADDRINFO, USE_WINSOCK. +AC_DEFUN([ACX_CHECK_GETADDRINFO_WITH_INCLUDES], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(for getaddrinfo) +ac_cv_func_getaddrinfo=no +AC_LINK_IFELSE( +[AC_LANG_SOURCE([[ +#ifdef __cplusplus +extern "C" +{ +#endif +char* getaddrinfo(); +char* (*f) () = getaddrinfo; +#ifdef __cplusplus +} +#endif +int main(void) { + ; + return 0; +} +]])], +dnl this case on linux, solaris, bsd +[ac_cv_func_getaddrinfo="yes" +dnl see if on windows +if test "$ac_cv_header_windows_h" = "yes"; then + AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) + USE_WINSOCK="1" + if echo "$LIBS" | grep 'lws2_32' >/dev/null; then + : + else + LIBS="$LIBS -lws2_32" + fi +fi +], +dnl no quick getaddrinfo, try mingw32 and winsock2 library. +dnl perhaps getaddrinfo needs only the include +AC_LINK_IFELSE( +[AC_LANG_PROGRAM( +[ +#ifdef HAVE_WS2TCPIP_H +#include +#endif +], +[ + (void)getaddrinfo(NULL, NULL, NULL, NULL); +] +)], +[ +ac_cv_func_getaddrinfo="yes" +AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) +USE_WINSOCK="1" +], + +ORIGLIBS="$LIBS" +LIBS="$LIBS -lws2_32" +AC_LINK_IFELSE( +[AC_LANG_PROGRAM( +[ +#ifdef HAVE_WS2TCPIP_H +#include +#endif +], +[ + (void)getaddrinfo(NULL, NULL, NULL, NULL); +] +)], +[ +ac_cv_func_getaddrinfo="yes" +dnl already: LIBS="$LIBS -lws2_32" +AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) +USE_WINSOCK="1" +], +[ +ac_cv_func_getaddrinfo="no" +LIBS="$ORIGLIBS" +]) +) +) + +AC_MSG_RESULT($ac_cv_func_getaddrinfo) +if test $ac_cv_func_getaddrinfo = yes; then + AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether getaddrinfo is available]) +fi +])dnl Endof AC_CHECK_GETADDRINFO_WITH_INCLUDES + +dnl check if a function is deprecated. defines DEPRECATED_func in config.h. +dnl $1: function name +dnl $2: C-statement that calls the function. +dnl $3: includes for the program. +dnl $4: executes if yes +dnl $5: executes if no +AC_DEFUN([ACX_FUNC_DEPRECATED], +[ +AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(if $1 is deprecated) +cache=`echo $1 | sed 'y%.=/+-%___p_%'` +AC_CACHE_VAL(cv_cc_deprecated_$cache, +[ +echo '$3' >conftest.c +echo 'void f(void){ $2 }' >>conftest.c +if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then +eval "cv_cc_deprecated_$cache=no" +else +eval "cv_cc_deprecated_$cache=yes" +fi +rm -f conftest conftest.o conftest.c +]) +if eval "test \"`echo '$cv_cc_deprecated_'$cache`\" = yes"; then +AC_MSG_RESULT(yes) +AC_DEFINE_UNQUOTED(AS_TR_CPP([DEPRECATED_$1]), 1, [Whether $1 is deprecated]) +: +$4 +else +AC_MSG_RESULT(no) +: +$5 +fi +])dnl end of ACX_FUNC_DEPRECATED + +dnl check if select and nonblocking sockets actually work. +dnl Needs fork(2) and select(2). +dnl defines NONBLOCKING_IS_BROKEN, and if that is true multiple reads from +dnl a nonblocking socket do not work, a new call to select is necessary. +AC_DEFUN([ACX_CHECK_NONBLOCKING_BROKEN], +[ +AC_MSG_CHECKING([if nonblocking sockets work]) +if echo $host | grep mingw >/dev/null; then + AC_MSG_RESULT([no (windows)]) + AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).]) +else +AC_RUN_IFELSE([ +AC_LANG_SOURCE([[ +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif + +int main(void) +{ + int port; + int sfd, cfd; + int num = 10; + int i, p; + struct sockaddr_in a; + /* test if select and nonblocking reads work well together */ + /* open port. + fork child to send 10 messages. + select to read. + then try to nonblocking read the 10 messages + then, nonblocking read must give EAGAIN + */ + + port = 12345 + (time(0)%32); + sfd = socket(PF_INET, SOCK_DGRAM, 0); + if(sfd == -1) { + perror("socket"); + return 1; + } + memset(&a, 0, sizeof(a)); + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr("127.0.0.1"); + if(bind(sfd, (struct sockaddr*)&a, sizeof(a)) < 0) { + perror("bind"); + return 1; + } + if(fcntl(sfd, F_SETFL, O_NONBLOCK) == -1) { + perror("fcntl"); + return 1; + } + + cfd = socket(PF_INET, SOCK_DGRAM, 0); + if(cfd == -1) { + perror("client socket"); + return 1; + } + a.sin_port = 0; + if(bind(cfd, (struct sockaddr*)&a, sizeof(a)) < 0) { + perror("client bind"); + return 1; + } + a.sin_port = htons(port); + + /* no handler, causes exit in 10 seconds */ + alarm(10); + + /* send and receive on the socket */ + if((p=fork()) == 0) { + for(i=0; i +#include +#ifdef HAVE_WINSOCK2_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +]], [[ + (void)mkdir("directory"); +]])],[AC_MSG_RESULT(yes) +AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.]) +],[AC_MSG_RESULT(no) +]) +])dnl end of ACX_MKDIR_ONE_ARG + +dnl Check for ioctlsocket function. works on mingw32 too. +AC_DEFUN([ACX_FUNC_IOCTLSOCKET], +[ +# check ioctlsocket +AC_MSG_CHECKING(for ioctlsocket) +AC_LINK_IFELSE([AC_LANG_PROGRAM([ +#ifdef HAVE_WINSOCK2_H +#include +#endif +], [ + (void)ioctlsocket(0, 0, NULL); +])], [ +AC_MSG_RESULT(yes) +AC_DEFINE(HAVE_IOCTLSOCKET, 1, [if the function 'ioctlsocket' is available]) +],[AC_MSG_RESULT(no)]) +])dnl end of ACX_FUNC_IOCTLSOCKET + +dnl detect malloc and provide malloc compat prototype. +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( +[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H +#include +#else +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.])] ) +]) + +dnl Define fallback for fseeko and ftello if needed. +AC_DEFUN([AHX_CONFIG_FSEEKO], +[ +#ifndef HAVE_FSEEKO +#define fseeko fseek +#define ftello ftell +#endif /* HAVE_FSEEKO */ +]) + +dnl Define RAND_MAX if not defined +AC_DEFUN([AHX_CONFIG_RAND_MAX], +[ +#ifndef RAND_MAX +#define RAND_MAX 2147483647 +#endif +]) + +dnl Define MAXHOSTNAMELEN if not defined +AC_DEFUN([AHX_CONFIG_MAXHOSTNAMELEN], +[ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif +]) + +dnl Define IPV6_MIN_MTU if not defined +AC_DEFUN([AHX_CONFIG_IPV6_MIN_MTU], +[ +#ifndef IPV6_MIN_MTU +#define IPV6_MIN_MTU 1280 +#endif /* IPV6_MIN_MTU */ +]) + +dnl provide snprintf, vsnprintf compat prototype +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_SNPRINTF], +[ +#ifndef HAVE_SNPRINTF +#define snprintf snprintf_$1 +#define vsnprintf vsnprintf_$1 +#include +int snprintf (char *str, size_t count, const char *fmt, ...); +int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); +#endif /* HAVE_SNPRINTF */ +]) + +dnl provide inet_pton compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_INET_PTON], +[ +#ifndef HAVE_INET_PTON +#define inet_pton inet_pton_$1 +int inet_pton(int af, const char* src, void* dst); +#endif /* HAVE_INET_PTON */ +]) + +dnl provide inet_ntop compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_INET_NTOP], +[ +#ifndef HAVE_INET_NTOP +#define inet_ntop inet_ntop_$1 +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif +]) + +dnl provide inet_aton compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_INET_ATON], +[ +#ifndef HAVE_INET_ATON +#define inet_aton inet_aton_$1 +int inet_aton(const char *cp, struct in_addr *addr); +#endif +]) + +dnl provide memmove compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_MEMMOVE], +[ +#ifndef HAVE_MEMMOVE +#define memmove memmove_$1 +void *memmove(void *dest, const void *src, size_t n); +#endif +]) + +dnl provide strlcat compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_STRLCAT], +[ +#ifndef HAVE_STRLCAT +#define strlcat strlcat_$1 +size_t strlcat(char *dst, const char *src, size_t siz); +#endif +]) + +dnl provide strlcpy compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_STRLCPY], +[ +#ifndef HAVE_STRLCPY +#define strlcpy strlcpy_$1 +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif +]) + +dnl provide gmtime_r compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_GMTIME_R], +[ +#ifndef HAVE_GMTIME_R +#define gmtime_r gmtime_r_$1 +struct tm *gmtime_r(const time_t *timep, struct tm *result); +#endif +]) + +dnl provide reallocarray compat prototype. +dnl $1: unique name for compat code +AC_DEFUN([AHX_CONFIG_REALLOCARRAY], +[ +#ifndef HAVE_REALLOCARRAY +#define reallocarray reallocarray$1 +void* reallocarray(void *ptr, size_t nmemb, size_t size); +#endif +]) + +dnl provide w32 compat definition for sleep +AC_DEFUN([AHX_CONFIG_W32_SLEEP], +[ +#if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H) +#define sleep(x) Sleep((x)*1000) /* on win32 */ +#endif /* HAVE_SLEEP */ +]) + +dnl provide w32 compat definition for usleep +AC_DEFUN([AHX_CONFIG_W32_USLEEP], +[ +#ifndef HAVE_USLEEP +#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */ +#endif /* HAVE_USLEEP */ +]) + +dnl provide w32 compat definition for random +AC_DEFUN([AHX_CONFIG_W32_RANDOM], +[ +#ifndef HAVE_RANDOM +#define random rand /* on win32, for tests only (bad random) */ +#endif /* HAVE_RANDOM */ +]) + +dnl provide w32 compat definition for srandom +AC_DEFUN([AHX_CONFIG_W32_SRANDOM], +[ +#ifndef HAVE_SRANDOM +#define srandom(x) srand(x) /* on win32, for tests only (bad random) */ +#endif /* HAVE_SRANDOM */ +]) + +dnl provide w32 compat definition for FD_SET_T +AC_DEFUN([AHX_CONFIG_W32_FD_SET_T], +[ +/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */ +#ifdef HAVE_WINSOCK2_H +#define FD_SET_T (u_int) +#else +#define FD_SET_T +#endif +]) + +dnl Remove an extension flag from CFLAGS, define replacement to be made. +dnl Used by ACX_STRIP_EXT_FLAGS. +dnl $1: the name of the flag, for example -D_GNU_SOURCE. +AC_DEFUN([ACX_CFLAGS_STRIP], +[ + if echo $CFLAGS | grep " $1" >/dev/null 2>&1; then + CFLAGS="`echo $CFLAGS | sed -e 's/ $1//g'`" + AC_DEFINE(m4_bpatsubst(OMITTED_$1,[[-=]],_), 1, Put $1 define in config.h) + fi +]) + +dnl Remove EXT flags from the CFLAGS and set them to be defined in config.h +dnl use with ACX_DETERMINE_EXT_FLAGS. +AC_DEFUN([ACX_STRIP_EXT_FLAGS], +[ + AC_MSG_NOTICE([Stripping extension flags...]) + ACX_CFLAGS_STRIP(-D_GNU_SOURCE) + ACX_CFLAGS_STRIP(-D_BSD_SOURCE) + ACX_CFLAGS_STRIP(-D_DEFAULT_SOURCE) + ACX_CFLAGS_STRIP(-D__EXTENSIONS__) + ACX_CFLAGS_STRIP(-D_POSIX_C_SOURCE=200112) + ACX_CFLAGS_STRIP(-D_XOPEN_SOURCE=600) + ACX_CFLAGS_STRIP(-D_XOPEN_SOURCE_EXTENDED=1) + ACX_CFLAGS_STRIP(-D_ALL_SOURCE) + ACX_CFLAGS_STRIP(-D_LARGEFILE_SOURCE=1) +]) dnl End of ACX_STRIP_EXT_FLAGS + +dnl define one omitted flag for config.h +dnl $1: flag name. -D_GNU_SOURCE +dnl $2: replacement define. _GNU_SOURCE +dnl $3: define value, 1 +AC_DEFUN([AHX_CONFIG_FLAG_OMITTED], +[#if defined($1) && !defined($2) +#define $2 $3 +[#]endif]) + +dnl Wrapper for AHX_CONFIG_FLAG_OMITTED for -D style flags +dnl $1: the -DNAME or -DNAME=value string. +AC_DEFUN([AHX_CONFIG_FLAG_EXT], +[AHX_CONFIG_FLAG_OMITTED(m4_bpatsubst(OMITTED_$1,[[-=]],_),m4_bpatsubst(m4_bpatsubst($1,-D,),=.*$,),m4_if(m4_bregexp($1,=),-1,1,m4_bpatsubst($1,^.*=,))) +]) + +dnl config.h part to define omitted cflags, use with ACX_STRIP_EXT_FLAGS. +AC_DEFUN([AHX_CONFIG_EXT_FLAGS], +[AHX_CONFIG_FLAG_EXT(-D_GNU_SOURCE) +AHX_CONFIG_FLAG_EXT(-D_BSD_SOURCE) +AHX_CONFIG_FLAG_EXT(-D_DEFAULT_SOURCE) +AHX_CONFIG_FLAG_EXT(-D__EXTENSIONS__) +AHX_CONFIG_FLAG_EXT(-D_POSIX_C_SOURCE=200112) +AHX_CONFIG_FLAG_EXT(-D_XOPEN_SOURCE=600) +AHX_CONFIG_FLAG_EXT(-D_XOPEN_SOURCE_EXTENDED=1) +AHX_CONFIG_FLAG_EXT(-D_ALL_SOURCE) +AHX_CONFIG_FLAG_EXT(-D_LARGEFILE_SOURCE=1) +]) + +dnl check if memcmp is using signed characters and replace if so. +AC_DEFUN([ACX_CHECK_MEMCMP_SIGNED], +[AC_MSG_CHECKING([if memcmp compares unsigned]) +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include +int main(void) +{ + char a = 255, b = 0; + if(memcmp(&a, &b, 1) < 0) + return 1; + return 0; +} +]])], [AC_MSG_RESULT([yes]) ], +[ AC_MSG_RESULT([no]) + AC_DEFINE([MEMCMP_IS_BROKEN], [1], [Define if memcmp() does not compare unsigned bytes]) + AC_LIBOBJ([memcmp]) +], [ AC_MSG_RESULT([cross-compile no]) + AC_DEFINE([MEMCMP_IS_BROKEN], [1], [Define if memcmp() does not compare unsigned bytes]) + AC_LIBOBJ([memcmp]) +]) ]) + +dnl define memcmp to its replacement, pass unique id for program as arg +AC_DEFUN([AHX_MEMCMP_BROKEN], [ +#ifdef MEMCMP_IS_BROKEN +#include "compat/memcmp.h" +#define memcmp memcmp_$1 +int memcmp(const void *x, const void *y, size_t n); +#endif +]) + +dnl ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family +AC_DEFUN([ACX_CHECK_SS_FAMILY], +[AC_CHECK_MEMBER([struct sockaddr_storage.ss_family], [], [ + AC_CHECK_MEMBER([struct sockaddr_storage.__ss_family], [ + AC_DEFINE([ss_family], [__ss_family], [Fallback member name for socket family in struct sockaddr_storage]) + ],, [AC_INCLUDES_DEFAULT +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + ]) +], [AC_INCLUDES_DEFAULT +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +]) ]) + +dnl Check if CC and linker support -fPIE and -pie. +dnl If so, sets them in CFLAGS / LDFLAGS. +AC_DEFUN([ACX_CHECK_PIE], [ + AC_ARG_ENABLE([pie], AS_HELP_STRING([--enable-pie], [Enable Position-Independent Executable (eg. to fully benefit from ASLR, small performance penalty)])) + AS_IF([test "x$enable_pie" = "xyes"], [ + AC_MSG_CHECKING([if $CC supports PIE]) + BAKLDFLAGS="$LDFLAGS" + BAKCFLAGS="$CFLAGS" + LDFLAGS="$LDFLAGS -pie" + CFLAGS="$CFLAGS -fPIE" + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ + if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then + LDFLAGS="$BAKLDFLAGS" + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi + rm -f conftest conftest.c conftest.o + ], [LDFLAGS="$BAKLDFLAGS" ; CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)]) + ]) +]) + +dnl Check if linker supports -Wl,-z,relro,-z,now. +dnl If so, adds it to LDFLAGS. +AC_DEFUN([ACX_CHECK_RELRO_NOW], [ + AC_ARG_ENABLE([relro_now], AS_HELP_STRING([--enable-relro-now], [Enable full relocation binding at load-time (RELRO NOW, to protect GOT and .dtor areas)])) + AS_IF([test "x$enable_relro_now" = "xyes"], [ + AC_MSG_CHECKING([if $CC supports -Wl,-z,relro,-z,now]) + BAKLDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now" + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ + if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then + LDFLAGS="$BAKLDFLAGS" + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi + rm -f conftest conftest.c conftest.o + ], [LDFLAGS="$BAKLDFLAGS" ; AC_MSG_RESULT(no)]) + ]) +]) + +dnl End of file Index: simdzone/config.guess =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/config.guess,v diff -u -p -r1.1.1.1 config.guess --- simdzone/config.guess 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/config.guess 3 Sep 2025 19:38:50 -0000 @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2023 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-09' +timestamp='2023-08-22' # 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-2022 Free Software Foundation, Inc. +Copyright 1992-2023 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,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -169,6 +172,7 @@ 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" @@ -459,7 +463,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 ;; @@ -904,7 +908,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +970,37 @@ 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:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + 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 ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1066,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + 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:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1151,16 +1190,27 @@ EOF ;; x86_64:Linux:*:*) set_cc_for_build + CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then - 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 + 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 fi - GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC @@ -1180,7 +1230,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 ;; @@ -1321,7 +1371,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 GUESS=i586-unisys-sysv4 ;; @@ -1367,8 +1417,11 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; - x86_64:Haiku:*:*) - GUESS=x86_64-unknown-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 ;; 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.1 config.h.in --- simdzone/config.h.in 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/config.h.in 3 Sep 2025 19:38:50 -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 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 header file. */ @@ -72,7 +72,7 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Define to 1 if all of the C90 standard headers exist (not just the ones +/* Define to 1 if all of the C89 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.1 config.sub --- simdzone/config.sub 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/config.sub 3 Sep 2025 19:38:50 -0000 @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2023 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2023-09-19' # 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 &2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ 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*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,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) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1199,45 +1200,23 @@ 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 | loongarchx32 \ + | loongarch32 | loongarch64 \ | 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 | 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 \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ @@ -1285,7 +1264,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 @@ -1306,11 +1285,12 @@ 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 @@ -1341,6 +1321,10 @@ 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 @@ -1506,10 +1490,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=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. ;; @@ -1528,12 +1518,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1536,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1586,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; mips*-*) - os=elf + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1612,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1694,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,7 +1717,8 @@ esac fi -# Now, validate our (potentially fixed-up) OS. +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). + case $os in # Sometimes we do "kernel-libc", so those need to count as OSes. musl* | newlib* | relibc* | uclibc*) @@ -1720,6 +1729,9 @@ 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. @@ -1728,7 +1740,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* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1737,11 +1749,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1754,7 +1766,7 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) @@ -1762,41 +1774,99 @@ 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"\': OS \`"$os"\' not recognized 1>&2 + 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 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 in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +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*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # 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 exit 1 ;; esac @@ -1879,7 +1949,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: Index: simdzone/configure =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/configure,v diff -u -p -r1.1.1.1 configure --- simdzone/configure 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/configure 3 Sep 2025 19:38:50 -0000 @@ -1,11 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for simdzone 0.2.0. +# Generated by GNU Autoconf 2.72 for simdzone 0.2.3. # # Report bugs to . # # -# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, # Inc. # # @@ -17,7 +17,6 @@ # 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 @@ -26,12 +25,13 @@ then : # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( +else case e in #( + e) 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,15 +133,14 @@ 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="as_nop=: -if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 + as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: @@ -149,12 +148,13 @@ then : # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else \$as_nop - case \`(set -o) 2>/dev/null\` in #( +else case e in #( + e) case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi " @@ -172,8 +172,9 @@ as_fn_ret_failure && { exitcode=1; echo if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : -else \$as_nop - exitcode=1; echo positional parameters were not saved. +else case e in #( + e) exitcode=1; echo positional parameters were not saved. ;; +esac fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) @@ -186,14 +187,15 @@ test -x / || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes -else $as_nop - as_have_required=no +else case e in #( + e) as_have_required=no ;; +esac fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do @@ -226,12 +228,13 @@ IFS=$as_save_IFS if $as_found then : -else $as_nop - if { test -f "$SHELL" || test -f "$SHELL.exe"; } && +else case e in #( + e) 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 +fi ;; +esac fi @@ -253,7 +256,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 @@ -273,7 +276,8 @@ $0: message. Then install a modern shell $0: the script under such a shell if you do have one." fi exit 1 -fi +fi ;; +esac fi fi SHELL=${CONFIG_SHELL-/bin/sh} @@ -312,14 +316,6 @@ 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 # ------------- @@ -388,11 +384,12 @@ then : { eval $1+=\$2 }' -else $as_nop - as_fn_append () +else case e in #( + e) as_fn_append () { eval $1=\$$1\$2 - } + } ;; +esac fi # as_fn_append # as_fn_arith ARG... @@ -406,21 +403,14 @@ then : { as_val=$(( $* )) }' -else $as_nop - as_fn_arith () +else case e in #( + e) 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] # ---------------------------------------- @@ -494,6 +484,8 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits /[$]LINENO/= ' <$as_myself | sed ' + t clear + :clear s/[$]LINENO.*/&-/ t lineno b @@ -542,7 +534,6 @@ 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 @@ -554,9 +545,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 @@ -581,10 +572,12 @@ as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +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 # Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated test -n "$DJDIR" || exec 7<&0 /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 @@ -859,7 +853,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 @@ -1072,7 +1066,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 @@ -1088,7 +1082,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 @@ -1118,8 +1112,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" ;; *=*) @@ -1127,7 +1121,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 ;; @@ -1177,7 +1171,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 @@ -1245,7 +1239,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)` @@ -1273,7 +1267,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.0 to adapt to many kinds of systems. +'configure' configures simdzone 0.2.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1287,11 +1281,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 @@ -1299,10 +1293,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. @@ -1340,7 +1334,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of simdzone 0.2.0:";; + short | recursive ) echo "Configuration of simdzone 0.2.3:";; esac cat <<\_ACEOF @@ -1348,6 +1342,8 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-pie Enable Position-Independent Executable (eg. to fully + benefit from ASLR, small performance penalty) --disable-westmere Disable Westmere (SSE4.2) kernel --disable-haswell Disable Haswell (AVX2) kernel @@ -1360,7 +1356,7 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory -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 . @@ -1427,10 +1423,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -simdzone configure 0.2.0 -generated by GNU Autoconf 2.71 +simdzone configure 0.2.3 +generated by GNU Autoconf 2.72 -Copyright (C) 2021 Free Software Foundation, Inc. +Copyright (C) 2023 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1469,17 +1465,66 @@ printf "%s\n" "$ac_try_echo"; } >&5 } && test -s conftest.$ac_objext then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 ;; +esac fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 ;; +esac +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in @@ -1492,8 +1537,8 @@ printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> @@ -1501,10 +1546,12 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -1526,8 +1573,8 @@ printf %s "checking whether $as_decl_nam if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` +else case e in #( + e) 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 @@ -1551,12 +1598,14 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" ;; +esac 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 @@ -1565,53 +1614,6 @@ printf "%s\n" "$ac_res" >&6; } } # ac_fn_check_decl -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - } -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - 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 - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -1623,15 +1625,15 @@ printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. */ + which can conflict with char $2 (void); below. */ #include #undef $2 @@ -1642,7 +1644,7 @@ else $as_nop #ifdef __cplusplus extern "C" #endif -char $2 (); +char $2 (void); /* 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. */ @@ -1661,11 +1663,13 @@ _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext + conftest$ac_exeext conftest.$ac_ext ;; +esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -1697,8 +1701,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.0, which was -generated by GNU Autoconf 2.71. Invocation command line was +It was created by simdzone $as_me 0.2.3, which was +generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -1944,10 +1948,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 @@ -1983,9 +1987,7 @@ 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 (p, i) - char **p; - int i; +static char *e (char **p, int i) { return p[i]; } @@ -1999,6 +2001,21 @@ 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 @@ -2026,16 +2043,19 @@ 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 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 @@ -2085,7 +2105,6 @@ 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) @@ -2151,6 +2170,8 @@ 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 = { @@ -2172,7 +2193,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 @@ -2364,8 +2385,9 @@ IFS=$as_save_IFS if $as_found then : -else $as_nop - as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 ;; +esac fi @@ -2393,12 +2415,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=: ;; ,);; *) @@ -2407,18 +2429,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. @@ -2434,11 +2456,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 ## -------------------- ## @@ -2458,6 +2480,236 @@ ac_config_headers="$ac_config_headers co ac_config_files="$ac_config_files Makefile" +# acx_nlnetlabs.m4 - common macros for configure checks +# Copyright 2009, Wouter Wijngaards, NLnet Labs. +# BSD licensed. +# +# Version 48 +# 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. +# 2023-05-04 fix to remove unused whitespace. +# 2023-01-26 fix -Wstrict-prototypes. +# 2022-09-01 fix checking if nonblocking sockets work on OpenBSD. +# 2021-08-17 fix sed script in ssldir split handling. +# 2021-08-17 fix for openssl to detect split version, with ssldir_include +# and ssldir_lib output directories. +# 2021-07-30 fix for openssl use of lib64 directory. +# 2021-06-14 fix nonblocking test to use host instead of target for mingw test. +# 2021-05-17 fix nonblocking socket test from grep on mingw32 to mingw for +# 64bit compatibility. +# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS. +# 2021-01-05 fix defun for aclocal +# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE +# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0). +# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0. +# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0). +# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20 +# 2015-12-11 FLTO check for new OSX, clang. +# 2015-11-18 spelling check fix. +# 2015-11-05 ACX_SSL_CHECKS no longer adds -ldl needlessly. +# 2015-08-28 ACX_CHECK_PIE and ACX_CHECK_RELRO_NOW added. +# 2015-03-17 AHX_CONFIG_REALLOCARRAY added +# 2013-09-19 FLTO help text improved. +# 2013-07-18 Enable ACX_CHECK_COMPILER_FLAG to test for -Wstrict-prototypes +# 2013-06-25 FLTO has --disable-flto option. +# 2013-05-03 Update W32_SLEEP for newer mingw that links but not defines it. +# 2013-03-22 Fix ACX_RSRC_VERSION for long version numbers. +# 2012-02-09 Fix AHX_MEMCMP_BROKEN with undef in compat/memcmp.h. +# 2012-01-20 Fix COMPILER_FLAGS_UNBOUND for gcc 4.6.2 assigned-not-used-warns. +# 2011-12-05 Fix getaddrinfowithincludes on windows with fedora16 mingw32-gcc. +# Fix ACX_MALLOC for redefined malloc error. +# Fix GETADDRINFO_WITH_INCLUDES to add -lws2_32 +# 2011-11-10 Fix FLTO test to not drop a.out in current directory. +# 2011-11-01 Fix FLTO test for llvm on Lion. +# 2011-08-01 Fix nonblock test (broken at v13). +# 2011-08-01 Fix autoconf 2.68 warnings +# 2011-06-23 Add ACX_CHECK_FLTO to check -flto. +# 2010-08-16 Fix FLAG_OMITTED for AS_TR_CPP changes in autoconf-2.66. +# 2010-07-02 Add check for ss_family (for minix). +# 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS. +# 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end. +# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS separate, -ldl +# 2010-02-01 added ACX_CHECK_MEMCMP_SIGNED, AHX_MEMCMP_BROKEN +# 2010-01-20 added AHX_COONFIG_STRLCAT +# 2009-07-14 U_CHAR detection improved for windows crosscompile. +# added ACX_FUNC_MALLOC +# fixup some #if to #ifdef +# NONBLOCKING test for mingw crosscompile. +# 2009-07-13 added ACX_WITH_SSL_OPTIONAL +# 2009-07-03 fixup LDFLAGS for empty ssl dir. +# +# Automates some of the checking constructs. Aims at portability for POSIX. +# Documentation for functions is below. +# +# the following macro's are provided in this file: +# (see below for details on each macro). +# +# ACX_ESCAPE_BACKSLASH - escape backslashes in var for C-preproc. +# ACX_RSRC_VERSION - create windows resource version number. +# ACX_CHECK_COMPILER_FLAG - see if cc supports a flag. +# ACX_CHECK_ERROR_FLAGS - see which flag is -werror (used below). +# ACX_CHECK_COMPILER_FLAG_NEEDED - see if flags make the code compile cleanly. +# 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_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. +# ACX_TYPE_U_CHAR - u_char type. +# ACX_TYPE_RLIM_T - rlim_t type. +# ACX_TYPE_SOCKLEN_T - socklen_t type. +# ACX_TYPE_IN_ADDR_T - in_addr_t type. +# ACX_TYPE_IN_PORT_T - in_port_t type. +# ACX_ARG_RPATH - add --disable-rpath option. +# ACX_WITH_SSL - add --with-ssl option, link -lcrypto. +# ACX_WITH_SSL_OPTIONAL - add --with-ssl option, link -lcrypto, +# where --without-ssl is also accepted +# ACX_LIB_SSL - setup to link -lssl. +# ACX_SYS_LARGEFILE - improved sys_largefile, fseeko, >2G files. +# ACX_CHECK_GETADDRINFO_WITH_INCLUDES - find getaddrinfo, portably. +# ACX_FUNC_DEPRECATED - see if func is deprecated. +# ACX_CHECK_NONBLOCKING_BROKEN - see if nonblocking sockets really work. +# ACX_MKDIR_ONE_ARG - determine mkdir(2) number of arguments. +# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably. +# ACX_FUNC_MALLOC - check malloc, define replacement . +# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format. +# 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. +# AHX_CONFIG_MAXHOSTNAMELEN - define MAXHOSTNAMELEN if needed. +# AHX_CONFIG_IPV6_MIN_MTU - define IPV6_MIN_MTU if needed. +# AHX_CONFIG_SNPRINTF - snprintf compat prototype +# AHX_CONFIG_INET_PTON - inet_pton compat prototype +# AHX_CONFIG_INET_NTOP - inet_ntop compat prototype +# AHX_CONFIG_INET_ATON - inet_aton compat prototype +# AHX_CONFIG_MEMMOVE - memmove compat prototype +# AHX_CONFIG_STRLCAT - strlcat compat prototype +# AHX_CONFIG_STRLCPY - strlcpy compat prototype +# AHX_CONFIG_GMTIME_R - gmtime_r compat prototype +# AHX_CONFIG_W32_SLEEP - w32 compat for sleep +# AHX_CONFIG_W32_USLEEP - w32 compat for usleep +# AHX_CONFIG_W32_RANDOM - w32 compat for random +# AHX_CONFIG_W32_SRANDOM - w32 compat for srandom +# AHX_CONFIG_W32_FD_SET_T - w32 detection of FD_SET_T. +# ACX_CFLAGS_STRIP - strip one flag from CFLAGS +# ACX_STRIP_EXT_FLAGS - strip extension flags from CFLAGS +# AHX_CONFIG_FLAG_OMITTED - define omitted flag +# AHX_CONFIG_FLAG_EXT - define omitted extension flag +# AHX_CONFIG_EXT_FLAGS - define the stripped extension flags +# ACX_CHECK_MEMCMP_SIGNED - check if memcmp uses signed characters. +# AHX_MEMCMP_BROKEN - replace memcmp func for CHECK_MEMCMP_SIGNED. +# ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family +# ACX_CHECK_PIE - add --enable-pie option and check if works +# ACX_CHECK_RELRO_NOW - add --enable-relro-now option and check it +# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== @@ -2498,6 +2750,8 @@ ac_config_files="$ac_config_files Makefi +CFLAGS="$CFLAGS" + @@ -2519,8 +2773,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2542,7 +2796,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -2564,8 +2819,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) 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 @@ -2587,7 +2842,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -2622,8 +2878,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2645,7 +2901,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -2667,8 +2924,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no @@ -2707,7 +2964,8 @@ if test $ac_prog_rejected = yes; then ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -2731,8 +2989,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2754,7 +3012,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -2780,8 +3039,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) 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 @@ -2803,7 +3062,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -2841,8 +3101,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2864,7 +3124,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -2886,8 +3147,8 @@ printf %s "checking for $ac_word... " >& if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) 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 @@ -2909,7 +3170,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -2938,10 +3200,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 @@ -3013,8 +3275,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. @@ -3034,7 +3296,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. @@ -3045,8 +3307,9 @@ do done test "$ac_cv_exeext" = no && ac_cv_exeext= -else $as_nop - ac_file='' +else case e in #( + e) ac_file='' ;; +esac fi if test -z "$ac_file" then : @@ -3055,13 +3318,14 @@ 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 $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +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 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; } @@ -3085,10 +3349,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 @@ -3098,11 +3362,12 @@ for ac_file in conftest.exe conftest con * ) break;; esac done -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;} +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;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3118,6 +3383,8 @@ int main (void) { FILE *f = fopen ("conftest.out", "w"); + if (!f) + return 1; return ferror (f) || fclose (f) != 0; ; @@ -3157,26 +3424,27 @@ 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.out +rm -f conftest.$ac_ext conftest$ac_cv_exeext \ + conftest.o conftest.obj 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 $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -3208,16 +3476,18 @@ then : break;; esac done -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) 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; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext +rm -f conftest.$ac_cv_objext conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } @@ -3228,8 +3498,8 @@ printf %s "checking whether the compiler if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -3246,12 +3516,14 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no +else case e in #( + e) ac_compiler_gnu=no ;; +esac 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; } @@ -3269,8 +3541,8 @@ printf %s "checking whether $CC accepts if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_c_werror_flag=$ac_c_werror_flag +else case e in #( + e) ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" @@ -3288,8 +3560,8 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes -else $as_nop - CFLAGS="" +else case e in #( + e) CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -3304,8 +3576,8 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - ac_c_werror_flag=$ac_save_c_werror_flag +else case e in #( + e) ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -3322,12 +3594,15 @@ 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 +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag + ac_c_werror_flag=$ac_save_c_werror_flag ;; +esac 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; } @@ -3354,8 +3629,8 @@ printf %s "checking for $CC option to en if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c11=no +else case e in #( + e) ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -3372,25 +3647,28 @@ 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 +CC=$ac_save_CC ;; +esac 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 $as_nop - if test "x$ac_cv_prog_cc_c11" = x +else case e in #( + e) 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 $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +else case e in #( + e) { 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" + CC="$CC $ac_cv_prog_cc_c11" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 - ac_prog_cc_stdc=c11 + ac_prog_cc_stdc=c11 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -3400,8 +3678,8 @@ printf %s "checking for $CC option to en if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c99=no +else case e in #( + e) ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -3418,25 +3696,28 @@ 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 +CC=$ac_save_CC ;; +esac 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 $as_nop - if test "x$ac_cv_prog_cc_c99" = x +else case e in #( + e) 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 $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +else case e in #( + e) { 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" + CC="$CC $ac_cv_prog_cc_c99" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 - ac_prog_cc_stdc=c99 + ac_prog_cc_stdc=c99 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -3446,8 +3727,8 @@ printf %s "checking for $CC option to en if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c89=no +else case e in #( + e) ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -3464,25 +3745,28 @@ 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 +CC=$ac_save_CC ;; +esac 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 $as_nop - if test "x$ac_cv_prog_cc_c89" = x +else case e in #( + e) 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 $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +else case e in #( + e) { 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" + CC="$CC $ac_cv_prog_cc_c89" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 - ac_prog_cc_stdc=c89 + ac_prog_cc_stdc=c89 ;; +esac fi fi @@ -3493,6 +3777,126 @@ ac_link='$CC -o conftest$ac_exeext $CFLA ac_compiler_gnu=$ac_cv_c_compiler_gnu +# allow user to override the -g -O2 flags. +if test "x$CFLAGS" = "x" ; then + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -g" >&5 +printf %s "checking whether $CC supports -g... " >&6; } +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) +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" +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 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +: +CFLAGS="$CFLAGS -g" +else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +: + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -O2" >&5 +printf %s "checking whether $CC supports -O2... " >&6; } +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) +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" +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 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +: +CFLAGS="$CFLAGS -O2" +else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +: + +fi + + + + # Check whether --enable-pie was given. +if test ${enable_pie+y} +then : + enableval=$enable_pie; +fi + + if test "x$enable_pie" = "xyes" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports PIE" >&5 +printf %s "checking if $CC supports PIE... " >&6; } + BAKLDFLAGS="$LDFLAGS" + BAKCFLAGS="$CFLAGS" + LDFLAGS="$LDFLAGS -pie" + CFLAGS="$CFLAGS -fPIE" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then + LDFLAGS="$BAKLDFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +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 +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi + +fi ac_header= ac_cache= for ac_item in $ac_header_c_list @@ -3543,8 +3947,8 @@ printf %s "checking for $CC options need if test ${ac_cv_c_undeclared_builtin_options+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_CFLAGS=$CFLAGS +else case e in #( + e) 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" @@ -3563,8 +3967,8 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - # This test program should compile successfully. +else case e in #( + e) # 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 @@ -3592,26 +3996,29 @@ then : if test x"$ac_arg" = x then : ac_cv_c_undeclared_builtin_options='none needed' -else $as_nop - ac_cv_c_undeclared_builtin_options=$ac_arg +else case e in #( + e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; +esac fi break fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac 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='' ;; #( *) : @@ -3631,8 +4038,9 @@ $ac_includes_default if test "x$ac_cv_have_decl_bswap16" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_BSWAP16 $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "bswap32" "ac_cv_have_decl_bswap32" " @@ -3648,8 +4056,9 @@ $ac_includes_default if test "x$ac_cv_have_decl_bswap32" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_BSWAP32 $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "bswap64" "ac_cv_have_decl_bswap64" " @@ -3665,8 +4074,9 @@ $ac_includes_default if test "x$ac_cv_have_decl_bswap64" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_BSWAP64 $ac_have_decl" >>confdefs.h @@ -3699,8 +4109,8 @@ printf %s "checking whether C compiler a if test ${ax_cv_check_cflags___MMD+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -MMD" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3717,19 +4127,22 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags___MMD=yes -else $as_nop - ax_cv_check_cflags___MMD=no +else case e in #( + e) ax_cv_check_cflags___MMD=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac 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 $as_nop - : +else case e in #( + e) : ;; +esac fi # Oracle Developer Studio (no -MP) @@ -3738,8 +4151,8 @@ printf %s "checking whether C compiler a if test ${ax_cv_check_cflags___xMMD+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -xMMD" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3756,19 +4169,22 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags___xMMD=yes -else $as_nop - ax_cv_check_cflags___xMMD=no +else case e in #( + e) ax_cv_check_cflags___xMMD=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac 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 $as_nop - : +else case e in #( + e) : ;; +esac fi @@ -3787,15 +4203,16 @@ printf %s "checking build system type... if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_build_alias=$build_alias +else case e in #( + e) 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; } @@ -3822,14 +4239,15 @@ printf %s "checking host system type... if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "x$host_alias" = x; then +else case e in #( + e) 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; } @@ -3856,14 +4274,15 @@ printf %s "checking target system type.. if test ${ac_cv_target+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "x$target_alias" = x; then +else case e in #( + e) 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; } @@ -3917,8 +4336,8 @@ printf %s "checking whether C compiler a if test ${ax_cv_check_cflags__Werror__march_westmere+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -Werror -march=westmere" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3935,19 +4354,22 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags__Werror__march_westmere=yes -else $as_nop - ax_cv_check_cflags__Werror__march_westmere=no +else case e in #( + e) ax_cv_check_cflags__Werror__march_westmere=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac 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 $as_nop - : +else case e in #( + e) : ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -march=haswell" >&5 @@ -3955,8 +4377,8 @@ printf %s "checking whether C compiler a if test ${ax_cv_check_cflags__Werror__march_haswell+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -Werror -march=haswell" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3973,19 +4395,22 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags__Werror__march_haswell=yes -else $as_nop - ax_cv_check_cflags__Werror__march_haswell=no +else case e in #( + e) ax_cv_check_cflags__Werror__march_haswell=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac 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 $as_nop - : +else case e in #( + e) : ;; +esac fi @@ -4024,11 +4449,12 @@ printf "%s\n" "#define HAVE_WESTMERE 1" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - +else case e in #( + e) { 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" @@ -4069,11 +4495,12 @@ printf "%s\n" "#define HAVE_HASWELL 1" > { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - +else case e in #( + e) { 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" @@ -4088,8 +4515,9 @@ if test "x$ac_cv_func_realpath" = xyes then : printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h -else $as_nop - as_fn_error $? "realpath is not available" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "realpath is not available" "$LINENO" 5 ;; +esac fi done @@ -4110,8 +4538,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 @@ -4141,14 +4569,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 | @@ -4238,7 +4666,6 @@ 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 @@ -4247,12 +4674,13 @@ then : # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( +else case e in #( + e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi @@ -4324,7 +4752,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 @@ -4353,7 +4781,6 @@ as_fn_error () } # as_fn_error - # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -4393,11 +4820,12 @@ then : { eval $1+=\$2 }' -else $as_nop - as_fn_append () +else case e in #( + e) as_fn_append () { eval $1=\$$1\$2 - } + } ;; +esac fi # as_fn_append # as_fn_arith ARG... @@ -4411,11 +4839,12 @@ then : { as_val=$(( $* )) }' -else $as_nop - as_fn_arith () +else case e in #( + e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` - } + } ;; +esac fi # as_fn_arith @@ -4498,9 +4927,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 @@ -4581,10 +5010,12 @@ as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +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 # Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated exec 6>&1 @@ -4599,8 +5030,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.0, which was -generated by GNU Autoconf 2.71. Invocation command line was +This file was extended by simdzone $as_me 0.2.3, which was +generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -4631,7 +5062,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. @@ -4663,11 +5094,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.0 -configured by $0, generated by GNU Autoconf 2.71, +simdzone config.status 0.2.3 +configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" -Copyright (C) 2021 Free Software Foundation, Inc. +Copyright (C) 2023 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -4726,8 +5157,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 \ @@ -4735,8 +5166,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 ;; @@ -4787,7 +5218,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 @@ -4806,7 +5237,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= @@ -4830,7 +5261,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 @@ -4988,13 +5419,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. @@ -5104,7 +5535,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 @@ -5126,19 +5557,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 '` @@ -5262,7 +5693,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 @@ -5291,9 +5722,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.1 configure.ac --- simdzone/configure.ac 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/configure.ac 3 Sep 2025 19:38:50 -0000 @@ -10,13 +10,23 @@ # 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.0],[https://github.com/NLnetLabs/simdzone/issues]) +AC_INIT([simdzone],[0.2.3],[https://github.com/NLnetLabs/simdzone/issues]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) +sinclude(acx_nlnetlabs.m4) m4_include(m4/ax_check_compile_flag.m4) + +CFLAGS="$CFLAGS" m4_version_prereq([2.70], [AC_PROG_CC], [AC_PROG_CC_STDC]) + +# allow user to override the -g -O2 flags. +if test "x$CFLAGS" = "x" ; then +ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="$CFLAGS -g"]) +ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"]) +ACX_CHECK_PIE +fi AC_CHECK_HEADERS([endian.h sys/endian.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS([bswap16,bswap32,bswap64], [], [], [ Index: simdzone/include/zone.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/include/zone.h,v diff -u -p -r1.1.1.1 zone.h --- simdzone/include/zone.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/include/zone.h 3 Sep 2025 19:38:50 -0000 @@ -119,8 +119,14 @@ extern "C" { #define ZONE_TYPE_LOC (29u) /** Next domain @rfc{3755} @rfc{2535} @obsolete */ #define ZONE_TYPE_NXT (30u) +/** Endpoint Identifier */ +#define ZONE_TYPE_EID (31u) +/** Nimrod Locator */ +#define ZONE_TYPE_NIMLOC (32u) /** Server Selection @rfc{2782} */ #define ZONE_TYPE_SRV (33u) +/** ATM Address */ +#define ZONE_TYPE_ATMA (34u) /** Naming Authority Pointer @rfc{2915} @rfc{2168} @rfc{3403} */ #define ZONE_TYPE_NAPTR (35u) /** Key Exchanger @rfc{2230} */ @@ -131,6 +137,8 @@ extern "C" { #define ZONE_TYPE_A6 (38u) /** DNAME @rfc{6672} */ #define ZONE_TYPE_DNAME (39u) +/** SINK @draft{eastlake, kitchen-sink} */ +#define ZONE_TYPE_SINK (40u) /** Address Prefix List @rfc{3123} */ #define ZONE_TYPE_APL (42u) /** Delegation Signer @rfc{4034} @rfc{3658} */ @@ -161,6 +169,8 @@ extern "C" { #define ZONE_TYPE_NINFO (56u) /** RKEY */ #define ZONE_TYPE_RKEY (57u) +/** Trust Anchor LINK @draft{ietf, dnsop-dnssec-trust-history} */ +#define ZONE_TYPE_TALINK (58u) /** Child DS @rfc{7344} */ #define ZONE_TYPE_CDS (59u) /** DNSKEY(s) the Child wants reflected in DS @rfc{7344} */ @@ -175,6 +185,8 @@ extern "C" { #define ZONE_TYPE_SVCB (64u) /** Service binding @rfc{9460} */ #define ZONE_TYPE_HTTPS (65u) +/** Endpoint discovery for delegation synchronization @draft{ietf, dnsop-generalized-notify} */ +#define ZONE_TYPE_DSYNC (66u) /** Sender Policy Framework @rfc{7208} */ #define ZONE_TYPE_SPF (99u) /** Node Identifier @rfc{6742} */ @@ -195,12 +207,18 @@ extern "C" { #define ZONE_TYPE_CAA (257u) /** DNS Authoritative Source (DNS-AS) */ #define ZONE_TYPE_AVC (258u) +/** Digital Object Architecture @draft{durand, doa-over-dns} */ +#define ZONE_TYPE_DOA (259u) +/** Automatic Multicast Tunneling Relay @rfc{8777} */ +#define ZONE_TYPE_AMTRELAY (260u) /** Resolver Information as Key/Value Pairs @rfc{9606} */ #define ZONE_TYPE_RESINFO (261u) /** Public wallet address */ #define ZONE_TYPE_WALLET (262u) /** BP Convergence Layer Adapter */ #define ZONE_TYPE_CLA (263u) +/** BP Node Number */ +#define ZONE_TYPE_IPN (264u) /** DNSSEC Trust Authorities */ #define ZONE_TYPE_TA (32768u) /** DNSSEC Lookaside Validation @rfc{4431} @obsolete */ Index: simdzone/src/isadetection.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/isadetection.h,v diff -u -p -r1.1.1.1 isadetection.h --- simdzone/src/isadetection.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/isadetection.h 3 Sep 2025 19:38:50 -0000 @@ -87,7 +87,7 @@ enum instruction_set { #if defined(__PPC64__) -static inline uint32_t detect_supported_architectures() { +static inline uint32_t detect_supported_architectures(void) { return ALTIVEC; } @@ -95,13 +95,13 @@ static inline uint32_t detect_supported_ #if defined(__ARM_NEON) -static inline uint32_t detect_supported_architectures() { +static inline uint32_t detect_supported_architectures(void) { return NEON; } #else // ARM without NEON -static inline uint32_t detect_supported_architectures() { +static inline uint32_t detect_supported_architectures(void) { return DEFAULT; } @@ -260,7 +260,7 @@ static inline uint32_t detect_supported_ } #else // fallback -static inline uint32_t detect_supported_architectures() { +static inline uint32_t detect_supported_architectures(void) { return DEFAULT; } Index: simdzone/src/zone.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/zone.c,v diff -u -p -r1.1.1.1 zone.c --- simdzone/src/zone.c 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/zone.c 3 Sep 2025 19:38:50 -0000 @@ -157,12 +157,12 @@ static void close_file( assert(!is_string || file == &parser->first); assert(!is_string || file->handle == NULL); (void)parser; - +#ifndef NDEBUG const bool is_stdin = file->name && file->name != not_a_file && strcmp(file->name, "-") == 0; assert(!is_stdin || (!file->handle || file->handle == stdin)); - +#endif if (file->buffer.data && !is_string) free(file->buffer.data); file->buffer.data = NULL; Index: simdzone/src/fallback/parser.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/fallback/parser.c,v diff -u -p -r1.1.1.1 parser.c --- simdzone/src/fallback/parser.c 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/fallback/parser.c 3 Sep 2025 19:38:50 -0000 @@ -35,6 +35,7 @@ #include "generic/apl.h" #include "generic/svcb.h" #include "generic/cert.h" +#include "generic/atma.h" #include "generic/algorithm.h" #include "generic/types.h" #include "generic/type.h" Index: simdzone/src/generic/atma.h =================================================================== RCS file: simdzone/src/generic/atma.h diff -N simdzone/src/generic/atma.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ simdzone/src/generic/atma.h 3 Sep 2025 19:38:50 -0000 @@ -0,0 +1,215 @@ +/* + * atma.h -- ATMA parser (see: https://web.archive.org/web/20190112072924/http://www.broadband-forum.org/ftp/pub/approved-specs/af-dans-0152.000.pdf ) + * + * Copyright (c) 2025, NLnet Labs. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef ATMA_H +#define ATMA_H + +static const uint8_t bad_atma_chars[256] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x00 - 0x07 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x08 - 0x0f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x10 - 0x17 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x18 - 0x1f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x20 - 0x27 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, // 0x28 - 0x2f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 - 0x37 + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x38 - 0x3f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x40 - 0x47 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x48 - 0x4f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x50 - 0x57 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x58 - 0x5f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x60 - 0x67 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x68 - 0x6f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x70 - 0x77 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x78 - 0x7f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x80 - 0x87 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x88 - 0x8f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x90 - 0x97 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x98 - 0x9f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xa0 - 0xa7 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xa8 - 0xaf + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xb0 - 0xb7 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xb8 - 0xbf + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xc0 - 0xc7 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xc8 - 0xcf + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xd0 - 0xd7 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xd8 - 0xdf + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xe0 - 0xe7 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xe0 - 0xe7 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xf8 - 0xff + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xf8 - 0xff +}; + +static const uint8_t atma_increment[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x01 - 0x07 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 - 0x0f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 - 0x17 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 - 0x1f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 - 0x27 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 - 0x2f + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x30 - 0x37 + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 - 0x3f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 - 0x47 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 - 0x5f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 - 0x67 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 - 0x7f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x87 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 - 0x8f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x97 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 - 0x9f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa0 - 0xa7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa8 - 0xaf + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0 - 0xb7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb8 - 0xbf + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 - 0xc7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc8 - 0xcf + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0 - 0xd7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd8 - 0xdf + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 - 0xe7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 - 0xe7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf8 - 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf8 - 0x00 +}; + + +nonnull_all +static really_inline int32_t parse_atma_e164( + parser_t *parser, + const type_info_t *type, + const rdata_info_t *field, + rdata_t *rdata, + const token_t *token) +{ + uint32_t bad_chars = 0; + for (size_t count=1; count < token->length; count++) { + const uint8_t octet = (uint8_t)token->data[count]; + *rdata->octets = octet; + rdata->octets += atma_increment[octet]; + bad_chars |= bad_atma_chars[octet]; + } + if (bad_chars) + SEMANTIC_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); + + return 0; +} + +nonnull((1,2,4,5)) +static really_inline int atma_stream_decode( + struct base16_state *state, + const char *src, + size_t srclen, + uint8_t *out, + size_t *outlen) +{ + int ret = 0; + const uint8_t *s = (const uint8_t *) src; + uint8_t *o = (uint8_t *) out; + uint32_t q; + + // Use local temporaries to avoid cache thrashing: + size_t olen = 0; + size_t slen = srclen; + struct base16_state st; + st.eof = state->eof; + st.bytes = state->bytes; + st.carry = state->carry; + + if (st.eof) { + *outlen = 0; + return ret; + } + + // Duff's device again: + switch (st.bytes) + { +#if defined(__SUNPRO_C) +#pragma error_messages(off, E_STATEMENT_NOT_REACHED) +#endif + for (;;) +#if defined(__SUNPRO_C) +#pragma error_messages(default, E_STATEMENT_NOT_REACHED) +#endif + { + case 0: + base16_dec_loop_generic_32(&s, &slen, &o, &olen); + if (slen-- == 0) { + ret = 1; + break; + } + if ((q = base16_table_dec_32bit_d0[*s++]) == 256) { + st.eof = BASE16_EOF; + break; + } else if (q == 257) { + continue; + } + st.carry = (uint8_t)q; + st.bytes = 1; + + // fallthrough + + case 1: + if (slen-- == 0) { + ret = 1; + break; + } + if ((q = base16_table_dec_32bit_d1[*s++]) == 256) { + st.eof = BASE16_EOF; + break; + } else if (q == 257) { + continue; + } + *o++ = st.carry | (uint8_t)q; + st.carry = 0; + st.bytes = 0; + olen++; + } + } + + state->eof = st.eof; + state->bytes = st.bytes; + state->carry = st.carry; + *outlen = olen; + return ret; +} + +nonnull((1,3,4)) +static really_inline int atma_decode( + const char *src, size_t srclen, uint8_t *out, size_t *outlen) +{ + struct base16_state state = { .eof = 0, .bytes = 0, .carry = 0 }; + return atma_stream_decode(&state, src, srclen, out, outlen) & !state.bytes; +} + +nonnull_all +static really_inline int32_t parse_atma( + parser_t *parser, + const type_info_t *type, + const rdata_info_t *field, + rdata_t *rdata, + const token_t *token) +{ + if (token->length && (char)*token->data == '+') { + *rdata->octets++ = 1; + if ((uintptr_t)rdata->limit - (uintptr_t)rdata->octets < token->length) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); + return parse_atma_e164(parser, type, field, rdata, token); + } + size_t length = token->length / 2; + if ((uintptr_t)rdata->limit - (uintptr_t)rdata->octets < length) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); + *rdata->octets++ = 0; + if (!atma_decode(token->data, token->length, rdata->octets, &length)) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); + rdata->octets += length; + return 0; +} + +#endif // ATMA_H Index: simdzone/src/generic/base16.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/generic/base16.h,v diff -u -p -r1.1.1.1 base16.h --- simdzone/src/generic/base16.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/generic/base16.h 3 Sep 2025 19:38:50 -0000 @@ -27,7 +27,7 @@ static const uint32_t base16_table_dec_3 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 257, 256, 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 256, 256, 256, 256, 256, 256, 256, 160, 176, 192, 208, 224, 240, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, @@ -52,7 +52,7 @@ static const uint32_t base16_table_dec_3 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 257, 256, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256, 256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, Index: simdzone/src/generic/loc.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/generic/loc.h,v diff -u -p -r1.1.1.1 loc.h --- simdzone/src/generic/loc.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/generic/loc.h 3 Sep 2025 19:38:50 -0000 @@ -235,7 +235,7 @@ static really_inline int32_t scan_precis return -1; // syntax error uint8_t exponent = 0; - while (centimeters >= poweroften[exponent+1] && exponent < 9) + while (exponent < 9 && centimeters >= poweroften[exponent+1]) exponent++; uint8_t mantissa = (uint8_t)(centimeters / poweroften[exponent]); Index: simdzone/src/generic/number.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/generic/number.h,v diff -u -p -r1.1.1.1 number.h --- simdzone/src/generic/number.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/generic/number.h 3 Sep 2025 19:38:50 -0000 @@ -69,6 +69,26 @@ static really_inline int32_t scan_int32( return sum <= 4294967295u; } +nonnull((1,3)) +static really_inline int32_t scan_int64( + const char *data, size_t length, uint64_t *number) +{ + uint64_t sum = (uint8_t)data[0] - '0'; + + if (sum > 9 || !length || length > 20) + return 0; + + for (size_t count=1; count < length; count++) { + const uint8_t digit = (uint8_t)data[count] - '0'; + sum = sum * 10 + digit; + if (digit > 9) + return 0; + } + + *number = sum; + return 1; /* TODO: detect overflow */ +} + nonnull_all static really_inline int32_t parse_int8( parser_t *parser, @@ -115,6 +135,23 @@ static really_inline int32_t parse_int32 number = htobe32(number); memcpy(rdata->octets, &number, 4); rdata->octets += 4; + return 0; +} + +nonnull_all +static really_inline int32_t parse_int64( + parser_t *parser, + const type_info_t *type, + const rdata_info_t *field, + rdata_t *rdata, + const token_t *token) +{ + uint64_t number; + if (!scan_int64(token->data, token->length, &number)) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); + number = htobe64(number); + memcpy(rdata->octets, &number, 8); + rdata->octets += 8; return 0; } Index: simdzone/src/generic/parser.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/generic/parser.h,v diff -u -p -r1.1.1.1 parser.h --- simdzone/src/generic/parser.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/generic/parser.h 3 Sep 2025 19:38:50 -0000 @@ -318,6 +318,11 @@ static int32_t refill(parser_t *parser) parser->file->buffer.length += (size_t)count; parser->file->buffer.data[parser->file->buffer.length] = '\0'; parser->file->end_of_file = feof(parser->file->handle) != 0; + + /* After the file, there is padding, that is used by vector instructions, + * initialise those bytes. */ + memset(parser->file->buffer.data+parser->file->buffer.length+1, 0, + ZONE_BLOCK_SIZE); return 0; } Index: simdzone/src/generic/type.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/generic/type.h,v diff -u -p -r1.1.1.1 type.h --- simdzone/src/generic/type.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/generic/type.h 3 Sep 2025 19:38:50 -0000 @@ -18,38 +18,38 @@ static const struct { const mnemonic_t *mnemonic; int32_t code; } types_and_classes[256] = { - V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(20), - T(3), V(0), V(0), V(0), V(0), T(261), V(0), V(0), - T(60), V(0), V(0), T(105), V(0), V(0), V(0), T(258), - V(0), V(0), V(0), V(0), T(30), V(0), T(28), V(0), - V(0), T(16), V(0), V(0), T(56), T(14), T(22), V(0), - V(0), T(13), V(0), T(47), T(21), V(0), T(65), T(27), - V(0), V(0), V(0), V(0), V(0), T(1), T(62), V(0), - V(0), C(1), V(0), T(44), V(0), V(0), T(33), V(0), - V(0), V(0), V(0), V(0), T(63), V(0), T(266), V(0), - C(3), T(99), T(37), V(0), V(0), V(0), C(2), T(43), - V(0), T(50), C(4), T(51), V(0), V(0), V(0), T(2), - T(49), T(42), T(19), T(23), V(0), T(6), V(0), V(0), - V(0), V(0), T(29), V(0), T(7), V(0), V(0), V(0), - V(0), T(57), V(0), V(0), V(0), V(0), V(0), T(36), - T(15), V(0), V(0), T(26), T(11), V(0), V(0), V(0), - V(0), V(0), V(0), V(0), T(104), V(0), T(8), V(0), - V(0), V(0), T(38), V(0), T(9), V(0), T(64), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), T(39), T(52), - T(24), V(0), T(5), T(106), V(0), V(0), V(0), V(0), - T(265), V(0), V(0), V(0), V(0), T(25), V(0), T(18), - T(48), V(0), T(53), V(0), V(0), V(0), T(59), V(0), - V(0), V(0), V(0), V(0), T(4), V(0), T(10), V(0), - V(0), V(0), V(0), V(0), V(0), T(55), V(0), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), - V(0), V(0), T(61), T(12), V(0), V(0), V(0), V(0), - V(0), T(108), V(0), V(0), T(257), V(0), V(0), V(0), - T(35), V(0), T(263), V(0), V(0), V(0), V(0), T(107), - V(0), V(0), V(0), V(0), T(17), V(0), T(45), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), T(46), V(0), - V(0), T(109), V(0), V(0), V(0), V(0), V(0), V(0), - V(0), V(0), V(0), V(0), T(262), V(0), T(256), V(0) + V(0), V(0), V(0), V(0), V(0), V(0), T(34), V(0), + V(0), V(0), T(30), V(0), V(0), T(57), V(0), T(16), + V(0), V(0), T(56), T(14), T(12), V(0), V(0), T(13), + T(61), V(0), T(105), V(0), V(0), V(0), T(32), T(258), + V(0), T(107), T(47), V(0), V(0), V(0), T(17), V(0), + T(257), V(0), V(0), V(0), V(0), V(0), V(0), V(0), + T(65), V(0), V(0), T(18), V(0), T(1), V(0), T(263), + V(0), V(0), V(0), V(0), T(51), V(0), V(0), T(106), + T(3), V(0), V(0), T(31), V(0), V(0), V(0), V(0), + V(0), T(50), T(44), T(104), T(10), V(0), V(0), V(0), + V(0), V(0), T(55), V(0), T(28), V(0), V(0), V(0), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(39), + T(35), V(0), V(0), T(5), T(29), T(262), V(0), V(0), + T(109), V(0), T(264), V(0), V(0), V(0), V(0), V(0), + V(0), T(21), V(0), V(0), V(0), V(0), V(0), V(0), + T(37), C(1), T(58), V(0), V(0), V(0), V(0), V(0), + V(0), V(0), V(0), C(3), V(0), T(52), T(11), T(20), + V(0), T(261), V(0), V(0), V(0), T(48), V(0), V(0), + V(0), T(25), C(2), T(43), V(0), V(0), C(4), T(60), + V(0), V(0), T(7), T(2), V(0), V(0), T(46), T(22), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(64), + V(0), T(260), V(0), V(0), V(0), V(0), T(38), V(0), + V(0), T(259), T(59), V(0), V(0), V(0), T(42), T(36), + T(8), T(15), V(0), T(26), T(27), T(6), V(0), T(99), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(53), + T(9), T(63), T(33), V(0), T(271), T(270), V(0), T(40), + V(0), V(0), T(24), T(19), V(0), V(0), V(0), V(0), + V(0), V(0), V(0), T(108), V(0), V(0), V(0), T(62), + V(0), V(0), V(0), V(0), V(0), T(66), T(4), V(0), + V(0), V(0), T(256), V(0), T(49), V(0), V(0), V(0), + V(0), V(0), T(45), V(0), V(0), T(23), V(0), V(0), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }; #undef V @@ -110,7 +110,7 @@ static really_inline uint8_t hash(uint64 prefix = le64toh(prefix); uint32_t value = (uint32_t)((prefix >> 32) ^ prefix); // magic value is generated using hash.c, rerun when adding types - return (uint8_t)((value * 3523548378ull) >> 32); + return (uint8_t)((value * 3537259401ull) >> 32); } nonnull_all 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.1 types.h --- simdzone/src/generic/types.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/generic/types.h 3 Sep 2025 19:38:50 -0000 @@ -87,6 +87,8 @@ static really_inline int32_t check_bytes #define check_int32(...) check_bytes(__VA_ARGS__, sizeof(uint32_t)) +#define check_int64(...) check_bytes(__VA_ARGS__, sizeof(uint64_t)) + #define check_ip4(...) check_bytes(__VA_ARGS__, 4) #define check_ip6(...) check_bytes(__VA_ARGS__, 16) @@ -732,7 +734,7 @@ static int32_t check_nsap_ptr_rr( const uint8_t *o = parser->rdata->octets; const rdata_info_t *f = type->rdata.fields; - if ((r = check(&c, check_name(parser, type, &f[0], o, n)))) + if ((r = check(&c, check_string(parser, type, &f[0], o, n)))) return r; if (c != n) @@ -774,9 +776,9 @@ static int32_t parse_nsap_ptr_rdata( int32_t code; const rdata_info_t *fields = type->rdata.fields; - if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0) return code; - if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0) + if ((code = parse_string(parser, type, &fields[0], rdata, token)) < 0) return code; if ((code = take_delimiter(parser, type, token)) < 0) return code; @@ -1113,6 +1115,27 @@ static int32_t parse_nxt_rdata( } nonnull_all +static int32_t check_eid_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets <= 0) + SYNTAX_ERROR(parser, "Invalid %s record", NAME(type)); + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t parse_eid_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + + if ((code = parse_base16_sequence(parser, type, &fields[1], rdata, token)) < 0) + return code; + return check_eid_rr(parser, type, rdata); +} + +nonnull_all static int32_t check_srv_rr( parser_t *parser, const type_info_t *type, const rdata_t *rdata) { @@ -1162,6 +1185,32 @@ static int32_t parse_srv_rdata( } nonnull_all +static int32_t check_atma_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + assert(rdata->octets >= parser->rdata->octets); + if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets > 2) + return accept_rr(parser, type, rdata); + SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); +} + +nonnull_all +static int32_t parse_atma_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + + if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + return code; + if ((code = parse_atma(parser, type, &fields[0], rdata, token)) < 0) + return code; + if ((code = take_delimiter(parser, type, token)) < 0) + return code; + return accept_rr(parser, type, rdata); +} + +nonnull_all static int32_t check_naptr_rr( parser_t *parser, const type_info_t *type, const rdata_t *rdata) { @@ -1246,6 +1295,41 @@ static int32_t parse_cert_rdata( } nonnull_all +static int32_t check_sink_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + // FIXME: implement actual checks + (void)type; + + assert(rdata->octets >= parser->rdata->octets); + if ((uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets < 3) + SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t parse_sink_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + + if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + return code; + if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) + return code; + if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) + return code; + if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) + return code; + take(parser, token); + if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) + return code; + + return accept_rr(parser, type, rdata); +} + +nonnull_all static int32_t check_apl_rr( parser_t *parser, const type_info_t *type, const rdata_t *rdata) { @@ -1312,7 +1396,7 @@ static int32_t check_ds_rr( SEMANTIC_ERROR(parser, "Invalid digest in %s", NAME(type)); } - if (c >= n) + if (c > n) SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); return accept_rr(parser, type, rdata); } @@ -1337,7 +1421,8 @@ static int32_t parse_ds_rdata( if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) return code; take(parser, token); - if ((code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0) + if (!(token->length == 1 && (char)*token->data == '0') + && (code = parse_base16_sequence(parser, type, &fields[3], rdata, token)) < 0) return code; const uint8_t digest_algorithm = parser->rdata->octets[3]; @@ -1707,7 +1792,7 @@ static int32_t check_dnskey_rr( (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) return r; - if (c >= n) + if (c > n) SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); return accept_rr(parser, type, rdata); } @@ -1732,7 +1817,8 @@ static int32_t parse_dnskey_rdata( if ((code = parse_algorithm(parser, type, &fields[2], rdata, token)) < 0) return code; take(parser, token); - if ((code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) + if (!(token->length == 1 && (char)*token->data == '0') + && (code = parse_base64_sequence(parser, type, &fields[3], rdata, token)) < 0) return code; return accept_rr(parser, type, rdata); @@ -2190,6 +2276,70 @@ static int32_t parse_https_rdata( } nonnull_all +static int32_t check_dsync_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + int32_t r; + size_t c = 0; + const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; + const uint8_t *o = parser->rdata->octets; + const rdata_info_t *f = type->rdata.fields; + + if ((r = check(&c, check_int16(parser, type, &f[0], o, n))) || + (r = check(&c, check_int8(parser, type, &f[1], o+c, n-c))) || + (r = check(&c, check_int16(parser, type, &f[2], o+c, n-c))) || + (r = check(&c, check_name(parser, type, &f[3], o+c, n-c)))) + return r; + + const uint8_t dsync_scheme = o[2]; + uint16_t dsync_type; + memcpy(&dsync_type, o, sizeof(dsync_type)); + dsync_type = be16toh(dsync_type); + if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS + && dsync_type != ZONE_TYPE_CSYNC) + SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type)); + + if (c > n) + SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t parse_dsync_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + + if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + return code; + if ((code = parse_type(parser, type, &fields[0], rdata, token)) < 0) + return code; + if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) + return code; + if ((code = parse_int8(parser, type, &fields[1], rdata, token)) < 0) + return code; + if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) + return code; + if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0) + return code; + if ((code = take_contiguous(parser, type, &fields[3], token)) < 0) + return code; + if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0) + return code; + + const uint8_t dsync_scheme = parser->rdata->octets[2]; + uint16_t dsync_type; + memcpy(&dsync_type, parser->rdata->octets, sizeof(dsync_type)); + dsync_type = be16toh(dsync_type); + if (dsync_scheme == 1 && dsync_type != ZONE_TYPE_CDS + && dsync_type != ZONE_TYPE_CSYNC) + SEMANTIC_ERROR(parser, "Wrong type for scheme 1 in %s", NAME(type)); + + return accept_rr(parser, type, rdata); +} + +nonnull_all static int32_t check_nid_rr( parser_t *parser, const type_info_t *type, const rdata_t *rdata) { @@ -2439,6 +2589,255 @@ static int32_t parse_caa_rdata( } nonnull_all +static int32_t check_doa_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + int32_t r; + size_t c = 0; + const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; + const uint8_t *o = parser->rdata->octets; + const rdata_info_t *f = type->rdata.fields; + + if ((r = check(&c, check_int32(parser, type, &f[0], o, n))) || + (r = check(&c, check_int32(parser, type, &f[1], o+c, n-c))) || + (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c))) || + (r = check(&c, check_string(parser, type, &f[3], o+c, n-c)))) + return r; + if (c > n) + SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t parse_doa_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + + if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + return code; + if ((code = parse_int32(parser, type, &fields[0], rdata, token)) < 0) + return code; + if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) + return code; + if ((code = parse_int32(parser, type, &fields[1], rdata, token)) < 0) + return code; + if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) + return code; + if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0) + return code; + if ((code = take_quoted_or_contiguous(parser, type, &fields[3], token)) < 0) + return code; + if ((code = parse_string(parser, type, &fields[3], rdata, token)) < 0) + return code; + take(parser, token); + if (!(token->length == 1 && ((char)*token->data == '0' || (char)*token->data == '-')) + && (code = parse_base64_sequence(parser, type, &fields[4], rdata, token)) < 0) + return code; + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t check_amtrelay_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata); + +nonnull_all +static int32_t parse_amtrelay_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token); + +diagnostic_push() +gcc_diagnostic_ignored(missing-field-initializers) +clang_diagnostic_ignored(missing-field-initializers) + +static const rdata_info_t amtrelay_ipv4_rdata_fields[] = { + FIELD("precedence"), + FIELD("discovery optional"), + FIELD("type"), + FIELD("relay") +}; + +static const type_info_t amtrelay_ipv4[] = { + TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_IN, FIELDS(amtrelay_ipv4_rdata_fields), + check_amtrelay_rr, parse_amtrelay_rdata), +}; + +static const rdata_info_t amtrelay_ipv6_rdata_fields[] = { + FIELD("precedence"), + FIELD("discovery optional"), + FIELD("type"), + FIELD("relay") +}; + +static const type_info_t amtrelay_ipv6[] = { + TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_IN, FIELDS(amtrelay_ipv6_rdata_fields), + check_amtrelay_rr, parse_amtrelay_rdata), +}; + +diagnostic_pop() + +nonnull_all +static int32_t check_amtrelay_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + int32_t r; + size_t c = 0; + const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; + const uint8_t *o = parser->rdata->octets; + const type_info_t *t = type; + const rdata_info_t *f = type->rdata.fields; + + if ((r = check(&c, check_int8(parser, type, &f[0], o, n))) || + (r = check(&c, check_int8(parser, type, &f[2], o+c, n-c)))) + return r; + + switch (parser->rdata->octets[1] & 0x7f) { + case 1: /* IPv4 address */ + t = (const type_info_t *)amtrelay_ipv4; + f = amtrelay_ipv4_rdata_fields; + if ((r = check(&c, check_ip4(parser, t, &f[3], o+c, n-c))) < 0) + return r; + break; + case 2: /* IPv6 address */ + t = (const type_info_t *)amtrelay_ipv6; + f = amtrelay_ipv6_rdata_fields; + if ((r = check(&c, check_ip6(parser, t, &f[3], o+c, n-c))) < 0) + return r; + break; + case 0: /* no gateway */ + break; + case 3: /* domain name */ + if ((r = check(&c, check_name(parser, t, &f[3], o+c, n-c))) < 0) + return r; + break; + default: + SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); + } + if (c < n) + SYNTAX_ERROR(parser, "Trailing data in %s", NAME(t)); + return accept_rr(parser, t, rdata); +} + +nonnull_all +static int32_t parse_amtrelay_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + uint8_t *octets = rdata->octets; + uint8_t D; + + if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + return code; + if ((code = parse_int8(parser, type, &fields[0], rdata, token)) < 0) + return code; + + if ((code = take_contiguous(parser, type, &fields[1], token)) < 0) + return code; + if (token->length != 1) + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type)); + switch((char)*token->data) { + case '0': + D = 0x00; + break; + case '1': + D = 0x80; + break; + default : + SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(&fields[1]), NAME(type)); + } + + if ((code = take_contiguous(parser, type, &fields[2], token)) < 0) + return code; + 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)); + } + } + octets[1] |= D; + if ((code = take_delimiter(parser, type, token)) < 0) + return code; + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t check_ipn_rr( + parser_t *parser, const type_info_t *type, const rdata_t *rdata) +{ + int32_t r; + size_t c = 0; + const size_t n = (uintptr_t)rdata->octets - (uintptr_t)parser->rdata->octets; + const uint8_t *o = parser->rdata->octets; + const rdata_info_t *f = type->rdata.fields; + + if ((r = check(&c, check_int64(parser, type, &f[0], o, n)))) + return r; + if (c > n) + SYNTAX_ERROR(parser, "Invalid %s", NAME(type)); + return accept_rr(parser, type, rdata); +} + +nonnull_all +static int32_t parse_ipn_rdata( + parser_t *parser, const type_info_t *type, rdata_t *rdata, token_t *token) +{ + int32_t code; + const rdata_info_t *fields = type->rdata.fields; + token_t left, right; + + /* draft-johnson-dns-ipn-cla-07 Section 3.1. IPN: + * Presentation format for these resource records are either a 64 bit + * unsigned decimal integer, or two 32 bit unsigned decimal integers + * delimited by a period with the most significant 32 bits first and least + * significant 32 bits last. + */ + if ((code = have_contiguous(parser, type, &fields[0], token)) < 0) + return code; + if (!(right.data = memchr(token->data, '.', token->length))) { + if ((code = parse_int64(parser, type, &fields[0], rdata, token)) < 0) + return code; + if ((code = take_delimiter(parser, type, token)) < 0) + return code; + return accept_rr(parser, type, rdata); + } + left.code = token->code; + left.data = token->data; + left.length = (size_t)(right.data - token->data); + right.code = token->code; + right.data += 1; + right.length = token->length - left.length - 1; + if ((code = parse_int32(parser, type, &fields[0], rdata, &left)) < 0) + return code; + if ((code = parse_int32(parser, type, &fields[0], rdata, &right)) < 0) + return code; + if ((code = take_delimiter(parser, type, token)) < 0) + return code; + return accept_rr(parser, type, rdata); +} + +nonnull_all static int32_t check_generic_rr( parser_t *parser, const type_info_t *type, const rdata_t *rdata) { @@ -2654,6 +3053,14 @@ static const rdata_info_t nxt_rdata_fiel FIELD("type bit map") }; +static const rdata_info_t eid_rdata_fields[] = { + FIELD("end point identifier") +}; + +static const rdata_info_t nimloc_rdata_fields[] = { + FIELD("nimrod locator") +}; + static const rdata_info_t srv_rdata_fields[] = { FIELD("priority"), FIELD("weight"), @@ -2661,6 +3068,10 @@ static const rdata_info_t srv_rdata_fiel FIELD("target") }; +static const rdata_info_t atma_rdata_fields[] = { + FIELD("address") +}; + static const rdata_info_t naptr_rdata_fields[] = { FIELD("order"), FIELD("preference"), @@ -2698,6 +3109,12 @@ static const rdata_info_t dname_rdata_fi FIELD("source") }; +static const rdata_info_t sink_rdata_fields[] = { + FIELD("coding"), + FIELD("subcoding"), + FIELD("data") +}; + static const rdata_info_t apl_rdata_fields[] = { FIELD("prefix") }; @@ -2818,6 +3235,12 @@ static const rdata_info_t rkey_rdata_fie FIELD("publickey") }; +// https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template +static const rdata_info_t talink_rdata_fields[] = { + FIELD("start or previous"), + FIELD("end or next") +}; + static const rdata_info_t openpgpkey_rdata_fields[] = { FIELD("key") }; @@ -2847,6 +3270,13 @@ static const rdata_info_t https_rdata_fi FIELD("params") }; +static const rdata_info_t dsync_rdata_fields[] = { + FIELD("rrtype"), + FIELD("scheme"), + FIELD("port"), + FIELD("target") +}; + static const rdata_info_t spf_rdata_fields[] = { FIELD("text") }; @@ -2899,6 +3329,25 @@ static const rdata_info_t avc_rdata_fiel FIELD("text") }; +// draft-durand-doa-over-dns-02 +static const rdata_info_t doa_rdata_fields[] = { + FIELD("enterprise"), + FIELD("type"), + FIELD("location"), + FIELD("media type"), + FIELD("data") +}; + +// RFC 8777 +// AMTRELAY is different because the rdata depends on the type +static const rdata_info_t amtrelay_rdata_fields[] = { + FIELD("precedence"), + FIELD("discovery optional"), + FIELD("type"), + FIELD("relay"), +}; + + // RFC 9606 static const rdata_info_t resinfo_rdata_fields[] = { FIELD("text") @@ -2914,6 +3363,12 @@ static const rdata_info_t cla_rdata_fiel FIELD("text") }; +// https://www.iana.org/assignments/dns-parameters/IPN/ipn-completed-template +// and https://datatracker.ietf.org/doc/draft-johnson-dns-ipn-cla/07/ +static const rdata_info_t ipn_rdata_fields[] = { + FIELD("CBHE Node Number") +}; + static const rdata_info_t ta_rdata_fields[] = { FIELD("key"), FIELD("algorithm"), @@ -2992,15 +3447,14 @@ static const type_info_t types[] = { check_loc_rr, parse_loc_rdata), TYPE("NXT", ZONE_TYPE_NXT, ZONE_CLASS_ANY, FIELDS(nxt_rdata_fields), // obsolete check_nxt_rr, parse_nxt_rdata), - - UNKNOWN_TYPE(31), - UNKNOWN_TYPE(32), - + TYPE("EID", ZONE_TYPE_EID, ZONE_CLASS_IN, FIELDS(eid_rdata_fields), + check_eid_rr, parse_eid_rdata), + TYPE("NIMLOC", ZONE_TYPE_NIMLOC, ZONE_CLASS_IN, FIELDS(nimloc_rdata_fields), + check_eid_rr, parse_eid_rdata), TYPE("SRV", ZONE_TYPE_SRV, ZONE_CLASS_IN, FIELDS(srv_rdata_fields), check_srv_rr, parse_srv_rdata), - - UNKNOWN_TYPE(34), - + TYPE("ATMA", ZONE_TYPE_ATMA, ZONE_CLASS_IN, FIELDS(atma_rdata_fields), + check_atma_rr, parse_atma_rdata), TYPE("NAPTR", ZONE_TYPE_NAPTR, ZONE_CLASS_IN, FIELDS(naptr_rdata_fields), check_naptr_rr, parse_naptr_rdata), TYPE("KX", ZONE_TYPE_KX, ZONE_CLASS_IN, FIELDS(kx_rdata_fields), @@ -3013,7 +3467,8 @@ static const type_info_t types[] = { TYPE("DNAME", ZONE_TYPE_DNAME, ZONE_CLASS_ANY, FIELDS(dname_rdata_fields), check_ns_rr, parse_ns_rdata), - UNKNOWN_TYPE(40), + TYPE("SINK", ZONE_TYPE_SINK, ZONE_CLASS_ANY, FIELDS(sink_rdata_fields), + check_sink_rr, parse_sink_rdata), UNKNOWN_TYPE(41), TYPE("APL", ZONE_TYPE_APL, ZONE_CLASS_IN, FIELDS(apl_rdata_fields), @@ -3048,10 +3503,9 @@ static const type_info_t types[] = { TYPE("NINFO", ZONE_TYPE_NINFO, ZONE_CLASS_ANY, FIELDS(ninfo_rdata_fields), check_txt_rr, parse_txt_rdata), TYPE("RKEY", ZONE_TYPE_RKEY, ZONE_CLASS_ANY, FIELDS(rkey_rdata_fields), - check_dnskey_rr, parse_dnskey_rdata), - - UNKNOWN_TYPE(58), - + check_dnskey_rr, parse_dnskey_rdata), + TYPE("TALINK", ZONE_TYPE_TALINK, ZONE_CLASS_ANY, FIELDS(talink_rdata_fields), + check_minfo_rr, parse_minfo_rdata), TYPE("CDS", ZONE_TYPE_CDS, ZONE_CLASS_ANY, FIELDS(cds_rdata_fields), check_ds_rr, parse_ds_rdata), TYPE("CDNSKEY", ZONE_TYPE_CDNSKEY, ZONE_CLASS_ANY, FIELDS(cdnskey_rdata_fields), @@ -3066,8 +3520,8 @@ static const type_info_t types[] = { check_svcb_rr, parse_svcb_rdata), TYPE("HTTPS", ZONE_TYPE_HTTPS, ZONE_CLASS_IN, FIELDS(https_rdata_fields), check_https_rr, parse_https_rdata), - - UNKNOWN_TYPE(66), + TYPE("DSYNC", ZONE_TYPE_DSYNC, ZONE_CLASS_ANY, FIELDS(dsync_rdata_fields), + check_dsync_rr, parse_dsync_rdata), UNKNOWN_TYPE(67), UNKNOWN_TYPE(68), UNKNOWN_TYPE(69), @@ -3275,23 +3729,29 @@ static const type_info_t types[] = { check_caa_rr, parse_caa_rdata), TYPE("AVC", ZONE_TYPE_AVC, ZONE_CLASS_ANY, FIELDS(avc_rdata_fields), check_txt_rr, parse_txt_rdata), - - UNKNOWN_TYPE(259), - UNKNOWN_TYPE(260), - + TYPE("DOA", ZONE_TYPE_DOA, ZONE_CLASS_ANY, FIELDS(doa_rdata_fields), + check_doa_rr, parse_doa_rdata), + TYPE("AMTRELAY", ZONE_TYPE_AMTRELAY, ZONE_CLASS_ANY, FIELDS(amtrelay_rdata_fields), + check_amtrelay_rr, parse_amtrelay_rdata), TYPE("RESINFO", ZONE_TYPE_RESINFO, ZONE_CLASS_ANY, FIELDS(resinfo_rdata_fields), check_txt_rr, parse_txt_rdata), TYPE("WALLET", ZONE_TYPE_WALLET, ZONE_CLASS_ANY, FIELDS(wallet_rdata_fields), check_txt_rr, parse_txt_rdata), TYPE("CLA", ZONE_TYPE_CLA, ZONE_CLASS_ANY, FIELDS(cla_rdata_fields), check_txt_rr, parse_txt_rdata), + TYPE("IPN", ZONE_TYPE_IPN, ZONE_CLASS_ANY, FIELDS(ipn_rdata_fields), + check_ipn_rr, parse_ipn_rdata), - UNKNOWN_TYPE(264), + UNKNOWN_TYPE(265), + UNKNOWN_TYPE(266), + UNKNOWN_TYPE(267), + UNKNOWN_TYPE(268), + UNKNOWN_TYPE(269), - /* Map 32768 in hash.c to 265 */ + /* Map 32768 in hash.c to 270 */ TYPE("TA", ZONE_TYPE_TA, ZONE_CLASS_ANY, FIELDS(ta_rdata_fields), // obsolete check_ds_rr, parse_ds_rdata), - /* Map 32769 in hash.c to 266 */ + /* Map 32769 in hash.c to 271 */ TYPE("DLV", ZONE_TYPE_DLV, ZONE_CLASS_ANY, FIELDS(dlv_rdata_fields), // obsolete check_ds_rr, parse_ds_rdata) }; Index: simdzone/src/haswell/parser.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/haswell/parser.c,v diff -u -p -r1.1.1.1 parser.c --- simdzone/src/haswell/parser.c 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/haswell/parser.c 3 Sep 2025 19:38:50 -0000 @@ -36,6 +36,7 @@ #include "generic/apl.h" #include "generic/svcb.h" #include "generic/cert.h" +#include "generic/atma.h" #include "generic/algorithm.h" #include "generic/types.h" #include "westmere/type.h" Index: simdzone/src/westmere/parser.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/westmere/parser.c,v diff -u -p -r1.1.1.1 parser.c --- simdzone/src/westmere/parser.c 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/westmere/parser.c 3 Sep 2025 19:38:50 -0000 @@ -36,6 +36,7 @@ #include "generic/apl.h" #include "generic/svcb.h" #include "generic/cert.h" +#include "generic/atma.h" #include "generic/algorithm.h" #include "generic/types.h" #include "westmere/type.h" Index: simdzone/src/westmere/type.h =================================================================== RCS file: /cvs/src/usr.sbin/nsd/simdzone/src/westmere/type.h,v diff -u -p -r1.1.1.1 type.h --- simdzone/src/westmere/type.h 3 Sep 2025 18:44:23 -0000 1.1.1.1 +++ simdzone/src/westmere/type.h 3 Sep 2025 19:38:50 -0000 @@ -18,38 +18,38 @@ static const struct { const mnemonic_t *mnemonic; int32_t code; } types_and_classes[256] = { - V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(20), - T(3), V(0), V(0), V(0), V(0), T(261), V(0), V(0), - T(60), V(0), V(0), T(105), V(0), V(0), V(0), T(258), - V(0), V(0), V(0), V(0), T(30), V(0), T(28), V(0), - V(0), T(16), V(0), V(0), T(56), T(14), T(22), V(0), - V(0), T(13), V(0), T(47), T(21), V(0), T(65), T(27), - V(0), V(0), V(0), V(0), V(0), T(1), T(62), V(0), - V(0), C(1), V(0), T(44), V(0), V(0), T(33), V(0), - V(0), V(0), V(0), V(0), T(63), V(0), T(266), V(0), - C(3), T(99), T(37), V(0), V(0), V(0), C(2), T(43), - V(0), T(50), C(4), T(51), V(0), V(0), V(0), T(2), - T(49), T(42), T(19), T(23), V(0), T(6), V(0), V(0), - V(0), V(0), T(29), V(0), T(7), V(0), V(0), V(0), - V(0), T(57), V(0), V(0), V(0), V(0), V(0), T(36), - T(15), V(0), V(0), T(26), T(11), V(0), V(0), V(0), - V(0), V(0), V(0), V(0), T(104), V(0), T(8), V(0), - V(0), V(0), T(38), V(0), T(9), V(0), T(64), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), T(39), T(52), - T(24), V(0), T(5), T(106), V(0), V(0), V(0), V(0), - T(265), V(0), V(0), V(0), V(0), T(25), V(0), T(18), - T(48), V(0), T(53), V(0), V(0), V(0), T(59), V(0), - V(0), V(0), V(0), V(0), T(4), V(0), T(10), V(0), - V(0), V(0), V(0), V(0), V(0), T(55), V(0), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), - V(0), V(0), T(61), T(12), V(0), V(0), V(0), V(0), - V(0), T(108), V(0), V(0), T(257), V(0), V(0), V(0), - T(35), V(0), T(263), V(0), V(0), V(0), V(0), T(107), - V(0), V(0), V(0), V(0), T(17), V(0), T(45), V(0), - V(0), V(0), V(0), V(0), V(0), V(0), T(46), V(0), - V(0), T(109), V(0), V(0), V(0), V(0), V(0), V(0), - V(0), V(0), V(0), V(0), T(262), V(0), T(256), V(0) + V(0), V(0), V(0), V(0), V(0), V(0), T(34), V(0), + V(0), V(0), T(30), V(0), V(0), T(57), V(0), T(16), + V(0), V(0), T(56), T(14), T(12), V(0), V(0), T(13), + T(61), V(0), T(105), V(0), V(0), V(0), T(32), T(258), + V(0), T(107), T(47), V(0), V(0), V(0), T(17), V(0), + T(257), V(0), V(0), V(0), V(0), V(0), V(0), V(0), + T(65), V(0), V(0), T(18), V(0), T(1), V(0), T(263), + V(0), V(0), V(0), V(0), T(51), V(0), V(0), T(106), + T(3), V(0), V(0), T(31), V(0), V(0), V(0), V(0), + V(0), T(50), T(44), T(104), T(10), V(0), V(0), V(0), + V(0), V(0), T(55), V(0), T(28), V(0), V(0), V(0), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(39), + T(35), V(0), V(0), T(5), T(29), T(262), V(0), V(0), + T(109), V(0), T(264), V(0), V(0), V(0), V(0), V(0), + V(0), T(21), V(0), V(0), V(0), V(0), V(0), V(0), + T(37), C(1), T(58), V(0), V(0), V(0), V(0), V(0), + V(0), V(0), V(0), C(3), V(0), T(52), T(11), T(20), + V(0), T(261), V(0), V(0), V(0), T(48), V(0), V(0), + V(0), T(25), C(2), T(43), V(0), V(0), C(4), T(60), + V(0), V(0), T(7), T(2), V(0), V(0), T(46), T(22), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(64), + V(0), T(260), V(0), V(0), V(0), V(0), T(38), V(0), + V(0), T(259), T(59), V(0), V(0), V(0), T(42), T(36), + T(8), T(15), V(0), T(26), T(27), T(6), V(0), T(99), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), T(53), + T(9), T(63), T(33), V(0), T(271), T(270), V(0), T(40), + V(0), V(0), T(24), T(19), V(0), V(0), V(0), V(0), + V(0), V(0), V(0), T(108), V(0), V(0), V(0), T(62), + V(0), V(0), V(0), V(0), V(0), T(66), T(4), V(0), + V(0), V(0), T(256), V(0), T(49), V(0), V(0), V(0), + V(0), V(0), T(45), V(0), V(0), T(23), V(0), V(0), + V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }; #undef V @@ -102,7 +102,7 @@ static really_inline uint8_t hash(uint64 { uint32_t value = (uint32_t)((prefix >> 32) ^ prefix); // magic value is generated using hash.c, rerun when adding types - return (uint8_t)((value * 3523548378ull) >> 32); + return (uint8_t)((value * 3537259401ull) >> 32); } nonnull_all