--- ObsoleteFiles.inc.orig +++ ObsoleteFiles.inc @@ -474,6 +474,16 @@ OLD_FILES+=usr/share/dtrace/watch_execve OLD_FILES+=usr/share/dtrace/watch_kill OLD_FILES+=usr/share/dtrace/watch_vop_remove +# 20180512: Rename Unbound tools +OLD_FILES+=usr/sbin/unbound +OLD_FILES+=usr/sbin/unbound-anchor +OLD_FILES+=usr/sbin/unbound-checkconf +OLD_FILES+=usr/sbin/unbound-control +OLD_FILES+=usr/share/man/man5/unbound.conf.5.gz +OLD_FILES+=usr/share/man/man8/unbound-anchor.8.gz +OLD_FILES+=usr/share/man/man8/unbound-checkconf.8.gz +OLD_FILES+=usr/share/man/man8/unbound-control.8.gz +OLD_FILES+=usr/share/man/man8/unbound.8.gz # 20180331: new clang import which bumps version from 5.0.1 to 6.0.0. OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/asan_interface.h --- contrib/unbound/.gitattributes.orig +++ contrib/unbound/.gitattributes @@ -0,0 +1 @@ +testdata/*.[0-9] linguist-documentation --- contrib/unbound/.github/FUNDING.yml.orig +++ contrib/unbound/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: ['https://nlnetlabs.nl/funding/'] --- contrib/unbound/.travis.yml.orig +++ contrib/unbound/.travis.yml @@ -0,0 +1,16 @@ +sudo: false +language: c +compiler: + - gcc +addons: + apt: + packages: + - libssl-dev + - libevent-dev + - libexpat-dev + - clang +script: + - ./configure --enable-debug --disable-flto + - make + - make test + - (cd testdata/clang-analysis.tdir; bash clang-analysis.test) --- contrib/unbound/Makefile.in.orig +++ contrib/unbound/Makefile.in @@ -23,6 +23,8 @@ CHECKLOCK_OBJ=@CHECKLOCK_OBJ@ DNSTAP_SRC=@DNSTAP_SRC@ DNSTAP_OBJ=@DNSTAP_OBJ@ +DNSCRYPT_SRC=@DNSCRYPT_SRC@ +DNSCRYPT_OBJ=@DNSCRYPT_OBJ@ WITH_PYTHONMODULE=@WITH_PYTHONMODULE@ WITH_PYUNBOUND=@WITH_PYUNBOUND@ PY_MAJOR_VERSION=@PY_MAJOR_VERSION@ @@ -55,7 +57,7 @@ CC=@CC@ CPPFLAGS=-I. @CPPFLAGS@ PYTHON_CPPFLAGS=-I. @PYTHON_CPPFLAGS@ -CFLAGS=@CFLAGS@ +CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@ LDFLAGS=@LDFLAGS@ LIBS=@LIBS@ LIBOBJS=@LIBOBJS@ @@ -81,7 +83,7 @@ # compat with OpenBSD LINTFLAGS+="-Dsigset_t=long" # FreeBSD -LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t" +LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t" "-D_Alignof(x)=x" "-D__aligned(x)=" "-D__requires_exclusive(x)=" "-D__requires_unlocked(x)=" "-D__locks_exclusive(x)=" "-D__trylocks_exclusive(x)=" "-D__unlocks(x)=" "-D__locks_shared(x)=" "-D__trylocks_shared(x)=" INSTALL=$(SHELL) $(srcdir)/install-sh @@ -95,6 +97,12 @@ PYUNBOUND_SRC= # libunbound_wrap.lo if python libunbound wrapper enabled. PYUNBOUND_OBJ=@PYUNBOUND_OBJ@ +SUBNET_SRC=edns-subnet/edns-subnet.c edns-subnet/subnetmod.c edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c +SUBNET_OBJ=@SUBNET_OBJ@ +SUBNET_HEADER=@SUBNET_HEADER@ +IPSECMOD_SRC=ipsecmod/ipsecmod.c ipsecmod/ipsecmod-whitelist.c +IPSECMOD_OBJ=@IPSECMOD_OBJ@ +IPSECMOD_HEADER=@IPSECMOD_HEADER@ COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \ util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \ util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \ @@ -101,30 +109,38 @@ iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \ iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \ iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \ -services/localzone.c services/mesh.c services/modstack.c \ +services/localzone.c services/mesh.c services/modstack.c services/view.c \ +services/rpz.c \ services/outbound_list.c services/outside_network.c util/alloc.c \ util/config_file.c util/configlexer.c util/configparser.c \ +util/shm_side/shm_main.c services/authzone.c \ util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \ util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \ -util/rtt.c util/storage/dnstree.c util/storage/lookup3.c \ -util/storage/lruhash.c util/storage/slabhash.c util/timehist.c util/tube.c \ +util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \ +util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \ +util/timehist.c util/tube.c \ util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \ validator/autotrust.c validator/val_anchor.c validator/validator.c \ validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \ validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \ -validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c cachedb/cachedb.c $(CHECKLOCK_SRC) \ -$(DNSTAP_SRC) +validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \ +edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \ +edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \ +cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \ +$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC) COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \ as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \ iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \ -iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo \ +iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \ outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \ -fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \ +fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \ random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \ -slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \ +slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \ +autotrust.lo val_anchor.lo rpz.lo \ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \ -val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo \ -$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) +val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \ +$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \ +$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \ outside_network.lo COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo @@ -133,7 +149,7 @@ COMPAT_SRC=compat/ctime_r.c compat/fake-rfc2553.c compat/gmtime_r.c \ compat/inet_aton.c compat/inet_ntop.c compat/inet_pton.c compat/malloc.c \ compat/memcmp.c compat/memmove.c compat/snprintf.c compat/strlcat.c \ -compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \ +compat/strlcpy.c compat/strptime.c compat/getentropy_freebsd.c compat/getentropy_linux.c \ compat/getentropy_osx.c compat/getentropy_solaris.c compat/getentropy_win.c \ compat/explicit_bzero.c compat/arc4random.c compat/arc4random_uniform.c \ compat/arc4_lock.c compat/sha512.c compat/reallocarray.c compat/isblank.c \ @@ -145,18 +161,21 @@ sldns/parseutil.c sldns/rrdef.c sldns/str2wire.c SLDNS_OBJ=keyraw.lo sbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \ str2wire.lo +SLDNS_ALLOCCHECK_EXTRA_OBJ=@SLDNS_ALLOCCHECK_EXTRA_OBJ@ UNITTEST_SRC=testcode/unitanchor.c testcode/unitdname.c \ testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \ testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \ -testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c +testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \ +testcode/unitecs.c testcode/unitauth.c UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \ unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \ -readhex.lo testpkts.lo unitldns.lo +readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \ $(COMPAT_OBJ) DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \ daemon/remote.c daemon/stats.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@ -DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo remote.lo stats.lo unbound.lo \ +DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo \ +shm_main.lo remote.lo stats.lo unbound.lo \ worker.lo @WIN_DAEMON_OBJ@ DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \ $(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@ @@ -170,17 +189,18 @@ $(SLDNS_OBJ) $(COMPAT_OBJ) @WIN_CONTROL_OBJ_LINK@ HOST_SRC=smallapp/unbound-host.c HOST_OBJ=unbound-host.lo -HOST_OBJ_LINK=$(HOST_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) @WIN_HOST_OBJ_LINK@ +HOST_OBJ_LINK=$(HOST_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) $(SLDNS_ALLOCCHECK_EXTRA_OBJ) @WIN_HOST_OBJ_LINK@ UBANCHOR_SRC=smallapp/unbound-anchor.c UBANCHOR_OBJ=unbound-anchor.lo UBANCHOR_OBJ_LINK=$(UBANCHOR_OBJ) parseutil.lo \ -$(COMPAT_OBJ_WITHOUT_CTIME) @WIN_UBANCHOR_OBJ_LINK@ +$(COMPAT_OBJ_WITHOUT_CTIME) $(SLDNS_ALLOCCHECK_EXTRA_OBJ) @WIN_UBANCHOR_OBJ_LINK@ TESTBOUND_SRC=testcode/testbound.c testcode/testpkts.c \ -daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \ +daemon/worker.c daemon/acl_list.c \ +daemon/daemon.c daemon/stats.c \ testcode/replay.c testcode/fake_event.c TESTBOUND_OBJ=testbound.lo replay.lo fake_event.lo TESTBOUND_OBJ_LINK=$(TESTBOUND_OBJ) testpkts.lo worker.lo acl_list.lo \ -daemon.lo stats.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \ +daemon.lo stats.lo shm_main.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \ $(COMPAT_OBJ) LOCKVERIFY_SRC=testcode/lock_verify.c LOCKVERIFY_OBJ=lock_verify.lo @@ -199,7 +219,7 @@ $(SLDNS_OBJ) ASYNCLOOK_SRC=testcode/asynclook.c ASYNCLOOK_OBJ=asynclook.lo -ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) +ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@ STREAMTCP_SRC=testcode/streamtcp.c STREAMTCP_OBJ=streamtcp.lo STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ @@ -211,6 +231,8 @@ DELAYER_OBJ=delayer.lo DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) +IPSET_SRC=@IPSET_SRC@ +IPSET_OBJ=@IPSET_OBJ@ LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \ libunbound/libworker.c LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo @@ -238,8 +260,9 @@ $(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \ $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \ $(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) \ - $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\ + $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \ $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) + ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \ $(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \ $(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \ @@ -250,7 +273,7 @@ COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined +LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined .PHONY: clean realclean doc lint all install uninstall tests test strip lib longtest longcheck check alltargets @@ -292,10 +315,11 @@ test: unittest$(EXEEXT) testbound$(EXEEXT) ./unittest$(EXEEXT) ./testbound$(EXEEXT) -s - for x in testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done + for x in $(srcdir)/testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done @echo test OK longtest: tests + if test ! $(srcdir)/testdata -ef ./testdata; then rm -rf testcode testdata; mkdir testcode testdata; cp -R $(srcdir)/testdata/*.sh $(srcdir)/testdata/*.tdir $(srcdir)/testdata/*.rpl $(srcdir)/testdata/*.crpl testdata; cp $(srcdir)/testcode/*.sh testcode; if test ! -d util; then mkdir util; fi; cp $(srcdir)/util/iana_ports.inc util; fi if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi lib: libunbound.la unbound.h @@ -313,7 +337,7 @@ $(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la - $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(LIBS) + $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS) unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ_LINK) libunbound.la $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat $(SSLLIB) $(LIBS) @@ -346,7 +370,7 @@ $(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS) asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la - $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) $(LIBS) -L. -L.libs -lunbound + $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS) streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK) $(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS) @@ -375,10 +399,17 @@ dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto @-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi - $(PROTOC_C) --c_out=. $(srcdir)/dnstap/dnstap.proto + $(PROTOC_C) --c_out=. --proto_path=$(srcdir) $(srcdir)/dnstap/dnstap.proto dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h +# dnscrypt +dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \ + dnscrypt/dnscrypt_config.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \ + $(srcdir)/util/config_file.h $(srcdir)/util/log.h \ + $(srcdir)/util/netevent.h + # Python Module pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \ pythonmod/interface.h \ @@ -404,7 +435,7 @@ # Pyunbound python unbound wrapper _unbound.la: libunbound_wrap.lo libunbound.la - $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound + $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) -L. -L.libs -lunbound util/config_file.c: util/configparser.h util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h @@ -426,14 +457,19 @@ rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py rm -rf autom4te.cache .libs build doc/html doc/xml -realclean: clean - rm -f config.status config.log config.h.in config.h - rm -f configure config.sub config.guess ltmain.sh aclocal.m4 libtool - rm -f util/configlexer.c util/configparser.c util/configparser.h - rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 +distclean: clean + rm -f config.status config.log config.h + rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 doc/unbound-host.1 + rm -f smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service rm -f $(TEST_BIN) rm -f Makefile +maintainer-clean: distclean + rm -f util/configlexer.c util/configparser.c util/configparser.h + +realclean: maintainer-clean + rm -f configure config.h.in config.sub config.guess ltmain.sh aclocal.m4 libtool + .SUFFIXES: .lint .c.lint: $(LINT) $(LINTFLAGS) -I. -I$(srcdir) $< @@ -456,9 +492,9 @@ if test -n "$(doxygen)"; then \ $(doxygen) $(srcdir)/doc/unbound.doxygen; fi if test "$(WITH_PYUNBOUND)" = "yes" -o "$(WITH_PYTHONMODULE)" = "yes"; \ - then if test -x "`which sphinx-build 2>&1`"; then \ - sphinx-build -b html pythonmod/doc doc/html/pythonmod; \ - sphinx-build -b html libunbound/python/doc doc/html/pyunbound;\ + then if test -x "`which sphinx-build-$(PY_MAJOR_VERSION) 2>&1`"; then \ + sphinx-build-$(PY_MAJOR_VERSION) -b html pythonmod/doc doc/html/pythonmod; \ + sphinx-build-$(PY_MAJOR_VERSION) -b html libunbound/python/doc doc/html/pyunbound;\ fi ;\ fi @@ -511,6 +547,8 @@ $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man5 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1 + $(INSTALL) -m 755 -d $(DESTDIR)$(libdir)/pkgconfig + $(INSTALL) -m 644 contrib/libunbound.pc $(DESTDIR)$(libdir)/pkgconfig $(LIBTOOL) --mode=install cp -f unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(LIBTOOL) --mode=install cp -f unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(LIBTOOL) --mode=install cp -f unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) @@ -564,7 +602,7 @@ DEPEND_TMP=depend1073.tmp DEPEND_TMP2=depend1074.tmp DEPEND_TARGET=Makefile -DEPEND_TARGET2=Makefile.in +DEPEND_TARGET2=$(srcdir)/Makefile.in # actions: generate deplines from gcc, # then, filter out home/xx, /usr/xx and /opt/xx lines (some cc already do this) # then, remove empty " \" lines @@ -572,7 +610,8 @@ # then, remove srcdir from the (generated) parser and lexer. # and mention the .lo depend: - (cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ $(ALL_SRC) $(COMPAT_SRC)) | \ + (BUILDDIR=$$PWD; cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) -I$$BUILDDIR @PTHREAD_CFLAGS_ONLY@ $(ALL_SRC) $(COMPAT_SRC)) | \ + sed -e 's?'$$PWD'/config.h?config.h?g' | \ sed -e 's!'$$HOME'[^ ]* !!g' -e 's!'$$HOME'[^ ]*$$!!g' \ -e 's!/usr[^ ]* !!g' -e 's!/usr[^ ]*$$!!g' \ -e 's!/opt[^ ]* !!g' -e 's!/opt[^ ]*$$!!g' | \ @@ -584,7 +623,12 @@ -e 's?$$(srcdir)/util/configparser.c?util/configparser.c?g' \ -e 's?$$(srcdir)/util/configparser.h?util/configparser.h?g' \ -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)/dnscrypt/dnscrypt_config.h??g' \ -e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \ + -e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \ + -e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \ -e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \ > $(DEPEND_TMP) cp $(DEPEND_TARGET) $(DEPEND_TMP2) @@ -599,24 +643,30 @@ fi rm -f $(DEPEND_TMP) $(DEPEND_TMP2) +# build rules +ipset.lo ipset.o: $(srcdir)/ipset/ipset.c + # Dependencies dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \ - $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/locks.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h \ - $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/validator/val_nsec.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ + $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ + $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \ - $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/storage/slabhash.h \ - $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h + $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h \ + $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h + $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \ @@ -625,7 +675,8 @@ $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \ - $(srcdir)/sldns/sbuffer.h + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/services/view.h msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ @@ -633,9 +684,15 @@ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h + $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/module.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ + $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ + $(srcdir)/respip/respip.h packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \ @@ -648,10 +705,13 @@ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_donotq.h \ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h $(srcdir)/iterator/iter_priv.h \ $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ + $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/config_file.h $(srcdir)/util/random.h \ - $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h + $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \ $(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \ @@ -692,152 +752,267 @@ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_priv.h \ - $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h \ - $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h \ - $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ - $(srcdir)/services/modstack.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h \ - $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h \ - $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h + $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \ + $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \ + $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \ + $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \ + $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/sldns/str2wire.h listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h \ - $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/services/outside_network.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \ - $(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h + $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h \ + $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \ - $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/regional.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/util/as112.h + $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \ + $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/as112.h mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ - $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \ $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h + $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ + $(srcdir)/util/alloc.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h \ + $(srcdir)/services/listen_dnsport.h modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \ - $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \ - $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \ - $(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/tube.h \ + $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \ + $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h +view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h +rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \ + $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h \ + $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h \ + $(srcdir)/sldns/str2wire.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \ $(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/netevent.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \ $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \ - $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \ - $(srcdir)/util/rtt.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \ - $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \ - $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h + $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/iterator/iterator.h \ + $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ + $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h \ + $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \ + $(srcdir)/dnstap/dnstap.h alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h + $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/util/log.h \ $(srcdir)/util/configyyrename.h $(srcdir)/util/config_file.h util/configparser.h \ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ - $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \ - $(srcdir)/util/iana_ports.inc + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ + $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \ + $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/iana_ports.inc configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \ $(srcdir)/util/config_file.h util/configparser.h configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h +shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ + $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ + $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h \ + $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \ + $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \ + $(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/fptr_wlist.h \ + $(srcdir)/util/tube.h +authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \ + $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \ + $(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \ + $(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \ + $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \ + $(srcdir)/validator/val_secalgo.h fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \ - $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \ - $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/infra.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \ $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \ $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \ - $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \ - $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \ - $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h + $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \ + $(srcdir)/libunbound/worker.h locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h + $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h -netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/util/ub_event.h \ - $(srcdir)/util/log.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/dnstap/dnstap.h + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h +netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/ub_event.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ + $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \ + $(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h \ - $(srcdir)/sldns/wire2str.h + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \ + $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h random.lo random.o: $(srcdir)/util/random.c config.h $(srcdir)/util/random.h $(srcdir)/util/log.h rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h regional.lo regional.o: $(srcdir)/util/regional.c config.h $(srcdir)/util/log.h $(srcdir)/util/regional.h -rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h +rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/iterator/iterator.h \ + $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h +edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ + $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/net_help.h lookup3.lo lookup3.o: $(srcdir)/util/storage/lookup3.c config.h $(srcdir)/util/storage/lookup3.h lruhash.lo lruhash.o: $(srcdir)/util/storage/lruhash.c config.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h \ + $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/module.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ - $(srcdir)/services/modstack.h + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h +tcp_conn_limit.lo tcp_conn_limit.o: $(srcdir)/util/tcp_conn_limit.c config.h $(srcdir)/util/regional.h \ + $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/tcp_conn_limit.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.h $(srcdir)/util/log.h tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h \ - $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/ub_event.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \ - $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \ + $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ - $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h \ - $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ - $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/services/modstack.h \ - $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kcache.h \ - $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h + $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \ + $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/services/mesh.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ + $(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ + $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \ - $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \ - $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/as112.h \ - $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/validator/autotrust.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \ + $(srcdir)/util/config_file.h $(srcdir)/util/as112.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/sldns/str2wire.h validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/validator/validator.h \ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ @@ -845,10 +1020,14 @@ $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \ - $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \ - $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \ - $(srcdir)/sldns/wire2str.h + $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ + $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \ @@ -861,7 +1040,7 @@ val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \ - $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \ $(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \ @@ -873,8 +1052,8 @@ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/validator/val_nsec.h $(srcdir)/sldns/sbuffer.h val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/validator/val_nsec.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/validator/val_utils.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/dname.h \ - $(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \ @@ -882,36 +1061,55 @@ $(srcdir)/sldns/sbuffer.h val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h + $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \ + $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \ + $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ + $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h \ + $(srcdir)/sldns/wire2str.h val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_kentry.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_kentry.h \ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h \ $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \ - $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h + $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/wire2str.h \ + $(srcdir)/sldns/parseutil.h dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(srcdir)/util/module.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ - $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h -cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \ - $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \ - $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \ - $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h \ - $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h \ - $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \ - $(srcdir)/sldns/sbuffer.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ + $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \ + $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h +edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h +subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h +addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h +subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h +cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h +redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h +respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/modstack.h \ + $(srcdir)/services/rpz.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/services/cache/dns.h \ + $(srcdir)/sldns/str2wire.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ + $(srcdir)/util/regional.h checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/testcode/checklocks.h +ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h +ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \ $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h @@ -922,9 +1120,13 @@ $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \ $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/random.h + $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \ + $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/random.h $(srcdir)/respip/respip.h \ + $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \ $(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ @@ -941,10 +1143,10 @@ $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h unitverify.lo unitverify.o: $(srcdir)/testcode/unitverify.c config.h $(srcdir)/util/log.h \ $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/validator/val_secalgo.h \ - $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h \ - $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h \ + $(srcdir)/util/rbtree.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \ $(srcdir)/testcode/testpkts.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \ $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/keyraw.h \ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h @@ -955,15 +1157,29 @@ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h +unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h +unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \ + $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/testcode/unitmain.h \ + $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \ + $(srcdir)/sldns/wire2str.h acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \ - $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \ + $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ + $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \ $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \ $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \ @@ -973,25 +1189,30 @@ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ - $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ - $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ + $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \ + $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \ + $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \ - $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h + $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ + $(srcdir)/sldns/keyraw.h remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \ - $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/alloc.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \ $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ - $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \ $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \ @@ -999,51 +1220,62 @@ $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \ $(srcdir)/sldns/wire2str.h stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ - $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ - $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \ - $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ - $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h \ - $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ - $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ + $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \ + $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/tube.h \ + $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ + $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ + $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ - $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h \ - $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h \ - $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h \ + $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \ + $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \ $(srcdir)/util/ub_event.h worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \ - $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ - $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \ - $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ + $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \ + $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \ - $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \ - $(srcdir)/libunbound/libworker.h + $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \ + $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \ - $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \ + $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \ $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ - $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h + $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \ $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h @@ -1050,63 +1282,80 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \ - $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ - $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \ - $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ + $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \ + $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \ + $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \ - $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \ - $(srcdir)/libunbound/libworker.h + $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \ + $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \ - $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \ + $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ + $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ - $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ - $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ + $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \ + $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \ + $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \ - $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h + $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ + $(srcdir)/sldns/keyraw.h stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ - $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ - $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \ - $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ - $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h \ - $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ - $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ + $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \ + $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/tube.h \ + $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ + $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ + $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ - $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/testcode/testpkts.h \ - $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h + $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \ + $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ - $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \ - $(srcdir)/util/data/dname.h $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h \ - $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \ - $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \ - $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \ - $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \ + $(srcdir)/util/rbtree.h $(srcdir)/services/cache/infra.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h + $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h pktview.lo pktview.o: $(srcdir)/testcode/pktview.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h \ @@ -1114,10 +1363,14 @@ readhex.lo readhex.o: $(srcdir)/testcode/readhex.c config.h $(srcdir)/testcode/readhex.h $(srcdir)/util/log.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \ - $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ - $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h + $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c config.h $(srcdir)/util/log.h \ $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ @@ -1125,20 +1378,31 @@ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \ - $(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER) + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ - $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h + $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \ + $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ + $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ - $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \ - $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ - $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/sldns/sbuffer.h + $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \ + $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ + $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \ + $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \ $(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ @@ -1146,19 +1410,23 @@ $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \ $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \ - $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/infra.h \ - $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ - $(srcdir)/sldns/sbuffer.h + $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \ + $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ + $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ - $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \ - $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ - $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/rrset.h \ - $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h \ - $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/config_file.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h \ + $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \ + $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ + $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h \ + $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \ + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \ $(srcdir)/sldns/str2wire.h @@ -1166,8 +1434,8 @@ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \ - $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/sldns/rrdef.h + $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ @@ -1180,7 +1448,14 @@ delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \ $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h $(srcdir)/util/log.h \ - $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h + $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \ + $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \ + $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \ + $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h petal.lo petal.o: $(srcdir)/testcode/petal.c config.h @@ -1187,17 +1462,19 @@ pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \ + $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \ - $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \ - + $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \ $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ - $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \ - $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ - $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \ - $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h + $(srcdir)/daemon/worker.h \ + $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \ + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ + $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ + $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \ + $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \ + $(srcdir)/util/net_help.h w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \ $(srcdir)/winrc/w_inst.h @@ -1209,7 +1486,8 @@ sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/sldns/keyraw.h + $(srcdir)/sldns/keyraw.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ + $(srcdir)/util/log.h parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \ $(srcdir)/sldns/sbuffer.h parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h @@ -1229,8 +1507,9 @@ strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h +getentropy_freebsd.lo getentropy_freebsd.o: $(srcdir)/compat/getentropy_freebsd.c getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h -getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h +getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h --- contrib/unbound/README.md.orig +++ contrib/unbound/README.md @@ -0,0 +1,38 @@ +# Unbound + +[![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound) +[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound) + +Unbound is a validating, recursive, caching DNS resolver. It is designed to be +fast and lean and incorporates modern features based on open standards. If you +have any feedback, we would love to hear from you. Don’t hesitate to +[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new) +or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users). +You can lean more about Unbound by reading our +[documentation](https://nlnetlabs.nl/documentation/unbound/). + +## Compiling + +Make sure you have the C toolchain, OpenSSL and its include files, and libexpat +installed. Unbound can be compiled and installed using: + +``` +./configure && make && make install +``` + +You can use libevent if you want. libevent is useful when using many (10000) +outgoing ports. By default max 256 ports are opened at the same time and the +builtin alternative is equally capable and a little faster. + +Use the `--with-libevent=dir` configure option to compile Unbound with libevent +support. + +## Unbound configuration + +All of Unbound's configuration options are described in the man pages, which +will be installed and are available on the Unbound +[documentation page](https://nlnetlabs.nl/documentation/unbound/). + +An example configuration file is located in +[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in). --- contrib/unbound/ac_pkg_swig.m4.orig +++ contrib/unbound/ac_pkg_swig.m4 @@ -103,9 +103,20 @@ if test -z "$available_patch" ; then [available_patch=0] fi - if test $available_major -ne $required_major \ - -o $available_minor -ne $required_minor \ - -o $available_patch -lt $required_patch ; then + [badversion=0] + if test $available_major -lt $required_major ; then + [badversion=1] + fi + if test $available_major -eq $required_major \ + -a $available_minor -lt $required_minor ; then + [badversion=1] + fi + if test $available_major -eq $required_major \ + -a $available_minor -eq $required_minor \ + -a $available_patch -lt $required_patch ; then + [badversion=1] + fi + if test $badversion -eq 1 ; then AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org]) SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' else --- contrib/unbound/aclocal.m4.orig +++ contrib/unbound/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.16.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -9044,3 +9044,397 @@ m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 11 (pkg-config-0.29.1) + +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +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 +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 +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [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 Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +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. +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)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------ +dnl +dnl Prepare a "--with-" configure option using the lowercase +dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and +dnl PKG_CHECK_MODULES in a single macro. +AC_DEFUN([PKG_WITH_MODULES], +[ +m4_pushdef([with_arg], m4_tolower([$1])) + +m4_pushdef([description], + [m4_default([$5], [build with ]with_arg[ support])]) + +m4_pushdef([def_arg], [m4_default([$6], [auto])]) +m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) +m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) + +m4_case(def_arg, + [yes],[m4_pushdef([with_without], [--without-]with_arg)], + [m4_pushdef([with_without],[--with-]with_arg)]) + +AC_ARG_WITH(with_arg, + AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, + [AS_TR_SH([with_]with_arg)=def_arg]) + +AS_CASE([$AS_TR_SH([with_]with_arg)], + [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], + [auto],[PKG_CHECK_MODULES([$1],[$2], + [m4_n([def_action_if_found]) $3], + [m4_n([def_action_if_not_found]) $4])]) + +m4_popdef([with_arg]) +m4_popdef([description]) +m4_popdef([def_arg]) + +])dnl PKG_WITH_MODULES + +dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ----------------------------------------------- +dnl +dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES +dnl check._[VARIABLE-PREFIX] is exported as make variable. +AC_DEFUN([PKG_HAVE_WITH_MODULES], +[ +PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) + +AM_CONDITIONAL([HAVE_][$1], + [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) +])dnl PKG_HAVE_WITH_MODULES + +dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------------------ +dnl +dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after +dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make +dnl and preprocessor variable. +AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], +[ +PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) + +AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], + [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) +])dnl PKG_HAVE_DEFINE_WITH_MODULES + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + --- contrib/unbound/acx_nlnetlabs.m4.orig +++ contrib/unbound/acx_nlnetlabs.m4 @@ -688,8 +688,8 @@ # check if -lwsock32 or -lgdi32 are needed. BAKLIBS="$LIBS" BAKSSLLIBS="$LIBSSL_LIBS" - LIBS="$LIBS -lgdi32" - LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32" + LIBS="$LIBS -lgdi32 -lws2_32" + LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32" AC_MSG_CHECKING([if -lcrypto needs -lgdi32]) AC_TRY_LINK([], [ int HMAC_Update(void); @@ -839,7 +839,11 @@ if test "$ac_cv_header_windows_h" = "yes"; then AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) USE_WINSOCK="1" - LIBS="$LIBS -lws2_32" + 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. --- contrib/unbound/acx_python.m4.orig +++ contrib/unbound/acx_python.m4 @@ -22,8 +22,7 @@ # Check if you have distutils, else fail # AC_MSG_CHECKING([for the distutils Python package]) - ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` - if test -z "$ac_distutils_result"; then + if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) --- contrib/unbound/cachedb/cachedb.c.orig +++ contrib/unbound/cachedb/cachedb.c @@ -43,6 +43,7 @@ #include "config.h" #ifdef USE_CACHEDB #include "cachedb/cachedb.h" +#include "cachedb/redis.h" #include "util/regional.h" #include "util/net_help.h" #include "util/config_file.h" @@ -56,11 +57,39 @@ #include "sldns/wire2str.h" #include "sldns/sbuffer.h" -#define CACHEDB_HASHSIZE 256 /* bit hash */ +/* header file for htobe64 */ +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +# include +#endif +#ifndef HAVE_HTOBE64 +# ifdef HAVE_LIBKERN_OSBYTEORDER_H + /* In practice this is specific to MacOS X. We assume it doesn't have + * htobe64/be64toh but has alternatives with a different name. */ +# include +# define htobe64(x) OSSwapHostToBigInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +# else + /* not OSX */ + /* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */ +# if __BIG_ENDIAN__ +# define be64toh(n) (n) +# define htobe64(n) (n) +# else +# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32)) +# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32)) +# endif /* _ENDIAN */ +# endif /* HAVE_LIBKERN_OSBYTEORDER_H */ +#endif /* HAVE_BE64TOH */ + /** the unit test testframe for cachedb, its module state contains * a cache for a couple queries (in memory). */ struct testframe_moddata { + /** lock for mutex */ + lock_basic_type lock; /** key for single stored data element, NULL if none */ char* stored_key; /** data for single stored data element, NULL if none */ @@ -72,14 +101,18 @@ static int testframe_init(struct module_env* env, struct cachedb_env* cachedb_env) { + struct testframe_moddata* d; (void)env; verbose(VERB_ALGO, "testframe_init"); - cachedb_env->backend_data = (void*)calloc(1, + d = (struct testframe_moddata*)calloc(1, sizeof(struct testframe_moddata)); + cachedb_env->backend_data = (void*)d; if(!cachedb_env->backend_data) { log_err("out of memory"); return 0; } + lock_basic_init(&d->lock); + lock_protect(&d->lock, d, sizeof(*d)); return 1; } @@ -92,6 +125,7 @@ verbose(VERB_ALGO, "testframe_deinit"); if(!d) return; + lock_basic_destroy(&d->lock); free(d->stored_key); free(d->stored_data); free(d); @@ -105,9 +139,12 @@ cachedb_env->backend_data; (void)env; verbose(VERB_ALGO, "testframe_lookup of %s", key); + lock_basic_lock(&d->lock); if(d->stored_key && strcmp(d->stored_key, key) == 0) { - if(d->stored_datalen > sldns_buffer_capacity(result_buffer)) + if(d->stored_datalen > sldns_buffer_capacity(result_buffer)) { + lock_basic_unlock(&d->lock); return 0; /* too large */ + } verbose(VERB_ALGO, "testframe_lookup found %d bytes", (int)d->stored_datalen); sldns_buffer_clear(result_buffer); @@ -114,8 +151,10 @@ sldns_buffer_write(result_buffer, d->stored_data, d->stored_datalen); sldns_buffer_flip(result_buffer); + lock_basic_unlock(&d->lock); return 1; } + lock_basic_unlock(&d->lock); return 0; } @@ -126,6 +165,7 @@ struct testframe_moddata* d = (struct testframe_moddata*) cachedb_env->backend_data; (void)env; + lock_basic_lock(&d->lock); verbose(VERB_ALGO, "testframe_store %s (%d bytes)", key, (int)data_len); /* free old data element (if any) */ @@ -137,6 +177,7 @@ d->stored_data = memdup(data, data_len); if(!d->stored_data) { + lock_basic_unlock(&d->lock); log_err("out of memory"); return; } @@ -146,8 +187,10 @@ free(d->stored_data); d->stored_data = NULL; d->stored_datalen = 0; + lock_basic_unlock(&d->lock); return; } + lock_basic_unlock(&d->lock); /* (key,data) successfully stored */ } @@ -160,6 +203,10 @@ static struct cachedb_backend* cachedb_find_backend(const char* str) { +#ifdef USE_REDIS + if(strcmp(str, redis_backend.name) == 0) + return &redis_backend; +#endif if(strcmp(str, testframe_backend.name) == 0) return &testframe_backend; /* TODO add more backends here */ @@ -170,15 +217,13 @@ static int cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg) { - const char* backend_str = "testframe"; /* TODO get from cfg */ - if(backend_str && backend_str[0]) { - cachedb_env->backend = cachedb_find_backend(backend_str); - if(!cachedb_env->backend) { - log_err("cachedb: cannot find backend name '%s", - backend_str); - return NULL; - } + const char* backend_str = cfg->cachedb_backend; + cachedb_env->backend = cachedb_find_backend(backend_str); + if(!cachedb_env->backend) { + log_err("cachedb: cannot find backend name '%s'", backend_str); + return 0; } + /* TODO see if more configuration needs to be applied or not */ return 1; } @@ -195,6 +240,8 @@ env->modinfo[id] = (void*)cachedb_env; if(!cachedb_apply_cfg(cachedb_env, env->cfg)) { log_err("cachedb: could not apply configuration settings."); + free(cachedb_env); + env->modinfo[id] = NULL; return 0; } /* see if a backend is selected */ @@ -203,9 +250,20 @@ if(!(*cachedb_env->backend->init)(env, cachedb_env)) { log_err("cachedb: could not init %s backend", cachedb_env->backend->name); + free(cachedb_env); + env->modinfo[id] = NULL; return 0; } cachedb_env->enabled = 1; + if(env->cfg->serve_expired_reply_ttl) + log_warn( + "cachedb: serve-expired-reply-ttl is set but not working for data " + "originating from the external cache; 0 TLL is used for those."); + if(env->cfg->serve_expired_client_timeout) + log_warn( + "cachedb: serve-expired-client-timeout is set but not working for " + "data originating from the external cache; expired data are used " + "in the reply without first trying to refresh the data."); return 1; } @@ -276,9 +334,9 @@ size_t clen = 0; uint8_t hash[CACHEDB_HASHSIZE/8]; const char* hex = "0123456789ABCDEF"; - const char* secret = "default"; /* TODO: from qstate->env->cfg */ + const char* secret = qstate->env->cfg->cachedb_secret; size_t i; - + /* copy the hash info into the clear buffer */ if(clen + qstate->qinfo.qname_len < sizeof(clear)) { memmove(clear+clen, qstate->qinfo.qname, @@ -299,7 +357,11 @@ /* hash the buffer */ secalgo_hash_sha256(clear, clen, hash); +#ifdef HAVE_EXPLICIT_BZERO + explicit_bzero(clear, clen); +#else memset(clear, 0, clen); +#endif /* hex encode output for portability (some online dbs need * no nulls, no control characters, and so on) */ @@ -328,6 +390,13 @@ if(!qstate->return_msg || !qstate->return_msg->rep) return 0; + /* We don't store the reply if its TTL is 0 unless serve-expired is + * enabled. Such a reply won't be reusable and simply be a waste for + * the backend. It's also compatible with the default behavior of + * dns_cache_store_msg(). */ + if(qstate->return_msg->rep->ttl == 0 && + !qstate->env->cfg->serve_expired) + return 0; if(verbosity >= VERB_ALGO) log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo, qstate->return_msg->rep); @@ -368,12 +437,55 @@ &expiry, sizeof(expiry)); expiry = be64toh(expiry); - if((time_t)expiry < *qstate->env->now) + /* Check if we are allowed to return expired entries: + * - serve_expired needs to be set + * - if SERVE_EXPIRED_TTL is set make sure that the record is not older + * than that. */ + if((time_t)expiry < *qstate->env->now && + (!qstate->env->cfg->serve_expired || + (SERVE_EXPIRED_TTL && + *qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL))) return 0; return 1; } +/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is + * negative, set the TTL to 0. */ +static void +packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract) +{ + size_t i; + size_t total = data->count + data->rrsig_count; + if(subtract >= 0 && data->ttl > subtract) + data->ttl -= subtract; + else data->ttl = 0; + for(i=0; i= 0 && data->rr_ttl[i] > subtract) + data->rr_ttl[i] -= subtract; + else data->rr_ttl[i] = 0; + } +} + +/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is + * negative, set the TTLs to 0. */ +static void +adjust_msg_ttl(struct dns_msg* msg, time_t adjust) +{ + size_t i; + if(adjust >= 0 && msg->rep->ttl > adjust) + msg->rep->ttl -= adjust; + else + msg->rep->ttl = 0; + msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); + msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; + + for(i=0; irep->rrset_count; i++) { + packed_rrset_ttl_subtract((struct packed_rrset_data*)msg-> + rep->rrsets[i]->entry.data, adjust); + } +} + /** convert dns message in buffer to return_msg */ static int parse_data(struct module_qstate* qstate, struct sldns_buffer* buf) @@ -420,24 +532,34 @@ qstate->return_rcode = LDNS_RCODE_NOERROR; /* see how much of the TTL expired, and remove it */ + if(*qstate->env->now <= (time_t)timestamp) { + verbose(VERB_ALGO, "cachedb msg adjust by zero"); + return 1; /* message from the future (clock skew?) */ + } adjust = *qstate->env->now - (time_t)timestamp; + if(qstate->return_msg->rep->ttl < adjust) { + verbose(VERB_ALGO, "cachedb msg expired"); + /* If serve-expired is enabled, we still use an expired message + * setting the TTL to 0. */ + if(qstate->env->cfg->serve_expired) + adjust = -1; + else + return 0; /* message expired */ + } verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust); - /*adjust_msg(qstate->return_msg, adjust);*/ - /* TODO: - msg->rep->ttl = r->ttl - adjust; - msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); - for(i=0; icount + d->rrsig_count; i++) { - if(d->rr_ttl[i] < adjust) - d->rr_ttl[i] = 0; - else d->rr_ttl[i] -= adjust; - } - if(d->ttl < adjust) - d->ttl = 0; - else d->ttl -= adjust; - */ - /* TODO */ + adjust_msg_ttl(qstate->return_msg, adjust); - return 0; + /* Similar to the unbound worker, if serve-expired is enabled and + * the msg would be considered to be expired, mark the state so a + * refetch will be scheduled. The comparison between 'expiry' and + * 'now' should be redundant given how these values were calculated, + * but we check it just in case as does good_expiry_and_qinfo(). */ + if(qstate->env->cfg->serve_expired && + (adjust == -1 || (time_t)expiry < *qstate->env->now)) { + qstate->need_refetch = 1; + } + + return 1; } /** @@ -497,14 +619,18 @@ msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname, qstate->qinfo.qname_len, qstate->qinfo.qtype, qstate->qinfo.qclass, qstate->query_flags, - qstate->region, qstate->env->scratch); - if(!msg && qstate->env->neg_cache) { + qstate->region, qstate->env->scratch, + 1 /* no partial messages with only a CNAME */ + ); + if(!msg && qstate->env->neg_cache && + iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) { /* lookup in negative cache; may result in * NOERROR/NODATA or NXDOMAIN answers that need validation */ msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo, qstate->region, qstate->env->rrset_cache, qstate->env->scratch_buffer, - *qstate->env->now, 1/*add SOA*/, NULL); + *qstate->env->now, 1/*add SOA*/, NULL, + qstate->env->cfg); } if(!msg) return 0; @@ -520,11 +646,15 @@ static void cachedb_intcache_store(struct module_qstate* qstate) { + uint32_t store_flags = qstate->query_flags; + + if(qstate->env->cfg->serve_expired) + store_flags |= DNSCACHE_STORE_ZEROTTL; if(!qstate->return_msg) return; (void)dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0, - qstate->region, qstate->query_flags); + qstate->region, store_flags); } /** @@ -547,19 +677,26 @@ return; } - if(qstate->blacklist) { - /* cache is blacklisted */ + if(qstate->blacklist || qstate->no_cache_lookup) { + /* cache is blacklisted or we are instructed from edns to not look */ /* pass request to next module */ qstate->ext_state[id] = module_wait_module; return; } - /* lookup inside unbound's internal cache */ + /* lookup inside unbound's internal cache. + * This does not look for expired entries. */ if(cachedb_intcache_lookup(qstate)) { - if(verbosity >= VERB_ALGO) - log_dns_msg("cachedb internal cache lookup", - &qstate->return_msg->qinfo, - qstate->return_msg->rep); + if(verbosity >= VERB_ALGO) { + if(qstate->return_msg->rep) + log_dns_msg("cachedb internal cache lookup", + &qstate->return_msg->qinfo, + qstate->return_msg->rep); + else log_info("cachedb internal cache lookup: rcode %s", + sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode) + ?sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name + :"??"); + } /* we are done with the query */ qstate->ext_state[id] = module_finished; return; @@ -573,6 +710,19 @@ qstate->return_msg->rep); /* store this result in internal cache */ cachedb_intcache_store(qstate); + /* In case we have expired data but there is a client timer for expired + * answers, pass execution to next module in order to try updating the + * data first. + * TODO: this needs revisit. The expired data stored from cachedb has + * 0 TTL which is picked up by iterator later when looking in the cache. + * Document that ext cachedb does not work properly with + * serve_stale_reply_ttl yet. */ + if(qstate->need_refetch && qstate->serve_expired_data && + qstate->serve_expired_data->timer) { + qstate->return_msg = NULL; + qstate->ext_state[id] = module_wait_module; + return; + } /* we are done with the query */ qstate->ext_state[id] = module_finished; return; @@ -595,8 +745,8 @@ cachedb_handle_response(struct module_qstate* qstate, struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id) { - /* check if we are enabled, and skip if not */ - if(!ie->enabled) { + /* check if we are not enabled or instructed to not cache, and skip */ + if(!ie->enabled || qstate->no_cache_store) { /* we are done with the query */ qstate->ext_state[id] = module_finished; return; @@ -649,6 +799,11 @@ (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); return; } + if(!iq && (event == module_event_moddone)) { + /* during priming, module done but we never started */ + qstate->ext_state[id] = module_finished; + return; + } log_err("bad event for cachedb"); (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); --- contrib/unbound/cachedb/cachedb.h.orig +++ contrib/unbound/cachedb/cachedb.h @@ -87,6 +87,8 @@ uint8_t*, size_t); }; +#define CACHEDB_HASHSIZE 256 /* bit hash */ + /** Init the cachedb module */ int cachedb_init(struct module_env* env, int id); /** Deinit the cachedb module */ --- contrib/unbound/cachedb/redis.c.orig +++ contrib/unbound/cachedb/redis.c @@ -0,0 +1,283 @@ +/* + * cachedb/redis.c - cachedb redis module + * + * Copyright (c) 2018, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains a module that uses the redis database to cache + * dns responses. + */ + +#include "config.h" +#ifdef USE_CACHEDB +#include "cachedb/redis.h" +#include "cachedb/cachedb.h" +#include "util/alloc.h" +#include "util/config_file.h" +#include "sldns/sbuffer.h" + +#ifdef USE_REDIS +#include "hiredis/hiredis.h" + +struct redis_moddata { + redisContext** ctxs; /* thread-specific redis contexts */ + int numctxs; /* number of ctx entries */ + const char* server_host; /* server's IP address or host name */ + int server_port; /* server's TCP port */ + struct timeval timeout; /* timeout for connection setup and commands */ +}; + +static redisContext* +redis_connect(const struct redis_moddata* moddata) +{ + redisContext* ctx; + + ctx = redisConnectWithTimeout(moddata->server_host, + moddata->server_port, moddata->timeout); + if(!ctx || ctx->err) { + const char *errstr = "out of memory"; + if(ctx) + errstr = ctx->errstr; + log_err("failed to connect to redis server: %s", errstr); + goto fail; + } + if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) { + log_err("failed to set redis timeout"); + goto fail; + } + return ctx; + + fail: + if(ctx) + redisFree(ctx); + return NULL; +} + +static int +redis_init(struct module_env* env, struct cachedb_env* cachedb_env) +{ + int i; + struct redis_moddata* moddata = NULL; + + verbose(VERB_ALGO, "redis_init"); + + moddata = calloc(1, sizeof(struct redis_moddata)); + if(!moddata) { + log_err("out of memory"); + return 0; + } + moddata->numctxs = env->cfg->num_threads; + moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*)); + if(!moddata->ctxs) { + log_err("out of memory"); + free(moddata); + return 0; + } + /* note: server_host is a shallow reference to configured string. + * we don't have to free it in this module. */ + moddata->server_host = env->cfg->redis_server_host; + moddata->server_port = env->cfg->redis_server_port; + moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000; + moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000; + for(i = 0; i < moddata->numctxs; i++) + moddata->ctxs[i] = redis_connect(moddata); + cachedb_env->backend_data = moddata; + return 1; +} + +static void +redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env) +{ + struct redis_moddata* moddata = (struct redis_moddata*) + cachedb_env->backend_data; + (void)env; + + verbose(VERB_ALGO, "redis_deinit"); + + if(!moddata) + return; + if(moddata->ctxs) { + int i; + for(i = 0; i < moddata->numctxs; i++) { + if(moddata->ctxs[i]) + redisFree(moddata->ctxs[i]); + } + free(moddata->ctxs); + } + free(moddata); +} + +/* + * Send a redis command and get a reply. Unified so that it can be used for + * both SET and GET. If 'data' is non-NULL the command is supposed to be + * SET and GET otherwise, but the implementation of this function is agnostic + * about the semantics (except for logging): 'command', 'data', and 'data_len' + * are opaquely passed to redisCommand(). + * This function first checks whether a connection with a redis server has + * been established; if not it tries to set up a new one. + * It returns redisReply returned from redisCommand() or NULL if some low + * level error happens. The caller is responsible to check the return value, + * if it's non-NULL, it has to free it with freeReplyObject(). + */ +static redisReply* +redis_command(struct module_env* env, struct cachedb_env* cachedb_env, + const char* command, const uint8_t* data, size_t data_len) +{ + redisContext* ctx; + redisReply* rep; + struct redis_moddata* d = (struct redis_moddata*) + cachedb_env->backend_data; + + /* We assume env->alloc->thread_num is a unique ID for each thread + * in [0, num-of-threads). We could treat it as an error condition + * if the assumption didn't hold, but it seems to be a fundamental + * assumption throughout the unbound architecture, so we simply assert + * it. */ + log_assert(env->alloc->thread_num < d->numctxs); + ctx = d->ctxs[env->alloc->thread_num]; + + /* If we've not established a connection to the server or we've closed + * it on a failure, try to re-establish a new one. Failures will be + * logged in redis_connect(). */ + if(!ctx) { + ctx = redis_connect(d); + d->ctxs[env->alloc->thread_num] = ctx; + } + if(!ctx) + return NULL; + + /* Send the command and get a reply, synchronously. */ + rep = (redisReply*)redisCommand(ctx, command, data, data_len); + if(!rep) { + /* Once an error as a NULL-reply is returned the context cannot + * be reused and we'll need to set up a new connection. */ + log_err("redis_command: failed to receive a reply, " + "closing connection: %s", ctx->errstr); + redisFree(ctx); + d->ctxs[env->alloc->thread_num] = NULL; + return NULL; + } + + /* Check error in reply to unify logging in that case. + * The caller may perform context-dependent checks and logging. */ + if(rep->type == REDIS_REPLY_ERROR) + log_err("redis: %s resulted in an error: %s", + data ? "set" : "get", rep->str); + + return rep; +} + +static int +redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env, + char* key, struct sldns_buffer* result_buffer) +{ + redisReply* rep; + char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */ + int n; + int ret = 0; + + verbose(VERB_ALGO, "redis_lookup of %s", key); + + n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key); + if(n < 0 || n >= (int)sizeof(cmdbuf)) { + log_err("redis_lookup: unexpected failure to build command"); + return 0; + } + + rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0); + if(!rep) + return 0; + switch (rep->type) { + case REDIS_REPLY_NIL: + verbose(VERB_ALGO, "redis_lookup: no data cached"); + break; + case REDIS_REPLY_STRING: + verbose(VERB_ALGO, "redis_lookup found %d bytes", + (int)rep->len); + if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) { + log_err("redis_lookup: replied data too long: %lu", + (size_t)rep->len); + break; + } + sldns_buffer_clear(result_buffer); + sldns_buffer_write(result_buffer, rep->str, rep->len); + sldns_buffer_flip(result_buffer); + ret = 1; + break; + case REDIS_REPLY_ERROR: + break; /* already logged */ + default: + log_err("redis_lookup: unexpected type of reply for (%d)", + rep->type); + break; + } + freeReplyObject(rep); + return ret; +} + +static void +redis_store(struct module_env* env, struct cachedb_env* cachedb_env, + char* key, uint8_t* data, size_t data_len) +{ + redisReply* rep; + char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */ + int n; + + verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len); + + /* build command to set to a binary safe string */ + n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key); + if(n < 0 || n >= (int)sizeof(cmdbuf)) { + log_err("redis_store: unexpected failure to build command"); + return; + } + + rep = redis_command(env, cachedb_env, cmdbuf, data, data_len); + if(rep) { + verbose(VERB_ALGO, "redis_store set completed"); + if(rep->type != REDIS_REPLY_STATUS && + rep->type != REDIS_REPLY_ERROR) { + log_err("redis_store: unexpected type of reply (%d)", + rep->type); + } + freeReplyObject(rep); + } +} + +struct cachedb_backend redis_backend = { "redis", + redis_init, redis_deinit, redis_lookup, redis_store +}; +#endif /* USE_REDIS */ +#endif /* USE_CACHEDB */ --- contrib/unbound/cachedb/redis.h.orig +++ contrib/unbound/cachedb/redis.h @@ -0,0 +1,45 @@ +/* + * cachedb/redis.h - cachedb redis module + * + * Copyright (c) 2018, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains a module that uses the redis database to cache + * dns responses. + */ + +/** the redis backend definition, contains callable functions + * and name string */ +extern struct cachedb_backend redis_backend; --- contrib/unbound/compat/arc4_lock.c.orig +++ contrib/unbound/compat/arc4_lock.c @@ -33,6 +33,9 @@ */ #include "config.h" #define LOCKRET(func) func +#ifdef ENABLE_LOCK_CHECKS +#undef ENABLE_LOCK_CHECKS +#endif #include "util/locks.h" void _ARC4_LOCK(void); @@ -46,9 +49,13 @@ void _ARC4_UNLOCK(void) { } + +void _ARC4_LOCK_DESTROY(void) +{ +} #else /* !THREADS_DISABLED */ -static lock_quick_t arc4lock; +static lock_quick_type arc4lock; static int arc4lockinit = 0; void _ARC4_LOCK(void) @@ -64,4 +71,12 @@ { lock_quick_unlock(&arc4lock); } + +void _ARC4_LOCK_DESTROY(void) +{ + if(arc4lockinit) { + arc4lockinit = 0; + lock_quick_destroy(&arc4lock); + } +} #endif /* THREADS_DISABLED */ --- contrib/unbound/compat/arc4random.c.orig +++ contrib/unbound/compat/arc4random.c @@ -71,9 +71,76 @@ static inline void _rs_rekey(u_char *dat, size_t datlen); +/* + * Basic sanity checking; wish we could do better. + */ +static int +fallback_gotdata(char *buf, size_t len) +{ + char any_set = 0; + size_t i; + + for (i = 0; i < len; ++i) + any_set |= buf[i]; + if (any_set == 0) + return -1; + return 0; +} + +/* fallback for getentropy in case libc returns failure */ +static int +fallback_getentropy_urandom(void *buf, size_t len) +{ + size_t i; + int fd, flags; + int save_errno = errno; + +start: + + flags = O_RDONLY; +#ifdef O_NOFOLLOW + flags |= O_NOFOLLOW; +#endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + fd = open("/dev/urandom", flags, 0); + if (fd == -1) { + if (errno == EINTR) + goto start; + goto nodevrandom; + } +#ifndef O_CLOEXEC +# ifdef HAVE_FCNTL + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +# endif +#endif + for (i = 0; i < len; ) { + size_t wanted = len - i; + ssize_t ret = read(fd, (char*)buf + i, wanted); + + if (ret == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + goto nodevrandom; + } + i += ret; + } + close(fd); + if (fallback_gotdata(buf, len) == 0) { + errno = save_errno; + return 0; /* satisfied */ + } +nodevrandom: + errno = EIO; + return -1; +} + static inline void _rs_init(u_char *buf, size_t n) { + assert(buf); if (n < KEYSZ + IVSZ) return; @@ -114,11 +181,14 @@ u_char rnd[KEYSZ + IVSZ]; if (getentropy(rnd, sizeof rnd) == -1) { + if(errno != ENOSYS || + fallback_getentropy_urandom(rnd, sizeof rnd) == -1) { #ifdef SIGKILL - raise(SIGKILL); + raise(SIGKILL); #else - exit(9); /* windows */ + exit(9); /* windows */ #endif + } } if (!rs) --- contrib/unbound/compat/ctime_r.c.orig +++ contrib/unbound/compat/ctime_r.c @@ -6,7 +6,7 @@ #include "util/locks.h" /** the lock for ctime buffer */ -static lock_basic_t ctime_lock; +static lock_basic_type ctime_lock; /** has it been inited */ static int ctime_r_init = 0; --- contrib/unbound/compat/getentropy_freebsd.c.orig +++ contrib/unbound/compat/getentropy_freebsd.c @@ -0,0 +1,62 @@ +/* $OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $ */ + +/* + * Copyright (c) 2014 Pawel Jakub Dawidek + * Copyright (c) 2014 Brent Cook + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 + */ + +#include +#include + +#include +#include + +/* + * Derived from lib/libc/gen/arc4random.c from FreeBSD. + */ +static size_t +getentropy_sysctl(u_char *buf, size_t size) +{ + int mib[2]; + size_t len, done; + + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + done = 0; + + do { + len = size; + if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) + return (done); + done += len; + buf += len; + size -= len; + } while (size > 0); + + return (done); +} + +int +getentropy(void *buf, size_t len) +{ + if (len <= 256 && getentropy_sysctl(buf, len) == len) + return (0); + + errno = EIO; + return (-1); +} --- contrib/unbound/compat/getentropy_linux.c.orig +++ contrib/unbound/compat/getentropy_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.46 2018/11/20 08:04:28 deraadt Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -15,12 +15,15 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 */ + #include "config.h" - /* -#define _POSIX_C_SOURCE 199309L -#define _GNU_SOURCE 1 +#define _POSIX_C_SOURCE 199309L +#define _GNU_SOURCE 1 */ #include #include @@ -27,8 +30,8 @@ #include #include #include -#ifdef HAVE_SYS_SYSCTL_H -#include +#ifdef SYS__sysctl +#include #endif #include #include @@ -39,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -46,16 +50,18 @@ #include #include #include - -#if defined(HAVE_SSL) +#ifndef HAVE_NETTLE #include -#elif defined(HAVE_NETTLE) +#else #include +#define SHA512_CTX struct sha512_ctx +#define SHA512_Init(x) sha512_init(x) +#define SHA512_Update(x, b, s) sha512_update(x, s, b) +#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r) #endif #include #include -#include #ifdef HAVE_GETAUXVAL #include #endif @@ -75,29 +81,13 @@ HD(b); \ } while (0) -#if defined(HAVE_SSL) -#define CRYPTO_SHA512_CTX SHA512_CTX -#define CRYPTO_SHA512_INIT(x) SHA512_Init(x) -#define CRYPTO_SHA512_FINAL(r, c) SHA512_Final(r, c) #define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) #define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) -#elif defined(HAVE_NETTLE) -#define CRYPTO_SHA512_CTX struct sha512_ctx -#define CRYPTO_SHA512_INIT(x) sha512_init(x) -#define CRYPTO_SHA512_FINAL(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r) -#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x))) -#define HD(x) (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x))) -#define HF(x) (sha512_update(&ctx, sizeof (void*), (uint8_t *)&(x))) -#endif int getentropy(void *buf, size_t len); -#ifdef CAN_REFERENCE_MAIN -extern int main(int, char *argv[]); -#endif -static int gotdata(char *buf, size_t len); -#if defined(SYS_getrandom) && defined(__NR_getrandom) +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) static int getentropy_getrandom(void *buf, size_t len); #endif static int getentropy_urandom(void *buf, size_t len); @@ -105,6 +95,7 @@ static int getentropy_sysctl(void *buf, size_t len); #endif static int getentropy_fallback(void *buf, size_t len); +static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data); int getentropy(void *buf, size_t len) @@ -113,18 +104,21 @@ if (len > 256) { errno = EIO; - return -1; + return (-1); } -#if defined(SYS_getrandom) && defined(__NR_getrandom) +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) /* - * Try descriptor-less getrandom() + * Try descriptor-less getrandom(), in non-blocking mode. + * + * The design of Linux getrandom is broken. It has an + * uninitialized phase coupled with blocking behaviour, which + * is unacceptable from within a library at boot time without + * possible recovery. See http://bugs.python.org/issue26839#msg267745 */ ret = getentropy_getrandom(buf, len); if (ret != -1) return (ret); - if (errno != ENOSYS) - return (-1); #endif /* @@ -178,7 +172,7 @@ * - Do the best under the circumstances.... * * This code path exists to bring light to the issue that Linux - * does not provide a failsafe API for entropy collection. + * still does not provide a failsafe API for entropy collection. * * We hope this demonstrates that Linux should either retain their * sysctl ABI, or consider providing a new failsafe API which @@ -196,24 +190,8 @@ return (ret); } -/* - * Basic sanity checking; wish we could do better. - */ +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) static int -gotdata(char *buf, size_t len) -{ - char any_set = 0; - size_t i; - - for (i = 0; i < len; ++i) - any_set |= buf[i]; - if (any_set == 0) - return -1; - return 0; -} - -#if defined(SYS_getrandom) && defined(__NR_getrandom) -static int getentropy_getrandom(void *buf, size_t len) { int pre_errno = errno; @@ -221,7 +199,7 @@ if (len > 256) return (-1); do { - ret = syscall(SYS_getrandom, buf, len, 0); + ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK); } while (ret == -1 && errno == EINTR); if (ret != (int)len) @@ -269,7 +247,7 @@ } for (i = 0; i < len; ) { size_t wanted = len - i; - ssize_t ret = read(fd, (char*)buf + i, wanted); + ssize_t ret = read(fd, (char *)buf + i, wanted); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) @@ -280,13 +258,11 @@ i += ret; } close(fd); - if (gotdata(buf, len) == 0) { - errno = save_errno; - return 0; /* satisfied */ - } + errno = save_errno; + return (0); /* satisfied */ nodevrandom: errno = EIO; - return -1; + return (-1); } #ifdef SYS__sysctl @@ -311,17 +287,15 @@ goto sysctlfailed; i += chunk; } - if (gotdata(buf, len) == 0) { - errno = save_errno; - return (0); /* satisfied */ - } + errno = save_errno; + return (0); /* satisfied */ sysctlfailed: errno = EIO; - return -1; + return (-1); } #endif /* SYS__sysctl */ -static int cl[] = { +static const int cl[] = { CLOCK_REALTIME, #ifdef CLOCK_MONOTONIC CLOCK_MONOTONIC, @@ -347,6 +321,15 @@ }; static int +getentropy_phdr(struct dl_phdr_info *info, size_t ATTR_UNUSED(size), void *data) +{ + SHA512_CTX *ctx = data; + + SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); + return (0); +} + +static int getentropy_fallback(void *buf, size_t len) { uint8_t results[SHA512_DIGEST_LENGTH]; @@ -357,7 +340,7 @@ struct rusage ru; sigset_t sigset; struct stat st; - CRYPTO_SHA512_CTX ctx; + SHA512_CTX ctx; static pid_t lastpid; pid_t pid; size_t i, ii, m; @@ -374,7 +357,7 @@ } for (i = 0; i < len; ) { int j; - CRYPTO_SHA512_INIT(&ctx); + SHA512_Init(&ctx); for (j = 0; j < repeat; j++) { HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { @@ -382,6 +365,8 @@ cnt += (int)tv.tv_usec; } + dl_iterate_phdr(getentropy_phdr, &ctx); + for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) HX(clock_gettime(cl[ii], &ts) == -1, ts); @@ -401,9 +386,6 @@ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, sigset); -#ifdef CAN_REFERENCE_MAIN - HF(main); /* an addr in program */ -#endif HF(getentropy); /* an addr in this library */ HF(printf); /* an addr in libc */ p = (char *)&p; @@ -528,33 +510,30 @@ HD(cnt); } #ifdef HAVE_GETAUXVAL -# ifdef AT_RANDOM +#ifdef AT_RANDOM /* Not as random as you think but we take what we are given */ p = (char *) getauxval(AT_RANDOM); if (p) HR(p, 16); -# endif -# ifdef AT_SYSINFO_EHDR +#endif +#ifdef AT_SYSINFO_EHDR p = (char *) getauxval(AT_SYSINFO_EHDR); if (p) HR(p, pgs); -# endif -# ifdef AT_BASE +#endif +#ifdef AT_BASE p = (char *) getauxval(AT_BASE); if (p) HD(p); -# endif -#endif /* HAVE_GETAUXVAL */ +#endif +#endif - CRYPTO_SHA512_FINAL(results, &ctx); - memcpy((char*)buf + i, results, min(sizeof(results), len - i)); + SHA512_Final(results, &ctx); + memcpy((char *)buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); } - memset(results, 0, sizeof results); - if (gotdata(buf, len) == 0) { - errno = save_errno; - return 0; /* satisfied */ - } - errno = EIO; - return -1; + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ } --- contrib/unbound/compat/getentropy_osx.c.orig +++ contrib/unbound/compat/getentropy_osx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $ */ +/* $OpenBSD: getentropy_osx.c,v 1.12 2018/11/20 08:04:28 deraadt Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -15,9 +15,12 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 */ -#include "config.h" +#include #include #include #include @@ -43,14 +46,18 @@ #include #include #include +#if TARGET_OS_OSX #include #include +#endif #include #include +#if TARGET_OS_OSX #include #include #include #include +#endif #include #define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c))) #define SHA512_Init(xxx) (CC_SHA512_Init((xxx))) @@ -75,10 +82,6 @@ int getentropy(void *buf, size_t len); -#ifdef CAN_REFERENCE_MAIN -extern int main(int, char *argv[]); -#endif -static int gotdata(char *buf, size_t len); static int getentropy_urandom(void *buf, size_t len); static int getentropy_fallback(void *buf, size_t len); @@ -89,7 +92,7 @@ if (len > 256) { errno = EIO; - return -1; + return (-1); } /* @@ -138,23 +141,7 @@ return (ret); } -/* - * Basic sanity checking; wish we could do better. - */ static int -gotdata(char *buf, size_t len) -{ - char any_set = 0; - size_t i; - - for (i = 0; i < len; ++i) - any_set |= buf[i]; - if (any_set == 0) - return -1; - return 0; -} - -static int getentropy_urandom(void *buf, size_t len) { struct stat st; @@ -188,7 +175,7 @@ } for (i = 0; i < len; ) { size_t wanted = len - i; - ssize_t ret = read(fd, (char*)buf + i, wanted); + ssize_t ret = read(fd, (char *)buf + i, wanted); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) @@ -199,18 +186,18 @@ i += ret; } close(fd); - if (gotdata(buf, len) == 0) { - errno = save_errno; - return 0; /* satisfied */ - } + errno = save_errno; + return (0); /* satisfied */ nodevrandom: errno = EIO; - return -1; + return (-1); } +#if TARGET_OS_OSX static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS }; static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS }; static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS }; +#endif static int kmib[] = { CTL_KERN, KERN_USRSTACK }; static int hwmib[] = { CTL_HW, HW_USERMEM }; @@ -230,9 +217,11 @@ pid_t pid; size_t i, ii, m; char *p; +#if TARGET_OS_OSX struct tcpstat tcpstat; struct udpstat udpstat; struct ipstat ipstat; +#endif u_int64_t mach_time; unsigned int idata; void *addr; @@ -267,6 +256,7 @@ HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]), &idata, &ii, NULL, 0) == -1, idata); +#if TARGET_OS_OSX ii = sizeof(tcpstat); HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]), &tcpstat, &ii, NULL, 0) == -1, tcpstat); @@ -278,6 +268,7 @@ ii = sizeof(ipstat); HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]), &ipstat, &ii, NULL, 0) == -1, ipstat); +#endif HX((pid = getpid()) == -1, pid); HX((pid = getsid(pid)) == -1, pid); @@ -295,9 +286,6 @@ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, sigset); -#ifdef CAN_REFERENCE_MAIN - HF(main); /* an addr in program */ -#endif HF(getentropy); /* an addr in this library */ HF(printf); /* an addr in libc */ p = (char *)&p; @@ -419,14 +407,11 @@ } SHA512_Final(results, &ctx); - memcpy((char*)buf + i, results, min(sizeof(results), len - i)); + memcpy((char *)buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); } - memset(results, 0, sizeof results); - if (gotdata(buf, len) == 0) { - errno = save_errno; - return 0; /* satisfied */ - } - errno = EIO; - return -1; + explicit_bzero(&ctx, sizeof ctx); + explicit_bzero(results, sizeof results); + errno = save_errno; + return (0); /* satisfied */ } --- contrib/unbound/compat/getentropy_solaris.c.orig +++ contrib/unbound/compat/getentropy_solaris.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $ */ +/* $OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -204,7 +204,7 @@ } for (i = 0; i < len; ) { size_t wanted = len - i; - ssize_t ret = read(fd, (char*)buf + i, wanted); + ssize_t ret = read(fd, (char *)buf + i, wanted); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) @@ -428,7 +428,7 @@ HD(cnt); } SHA512_Final(results, &ctx); - memcpy((char*)buf + i, results, min(sizeof(results), len - i)); + memcpy((char *)buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); } memset(results, 0, sizeof results); --- contrib/unbound/compat/getentropy_win.c.orig +++ contrib/unbound/compat/getentropy_win.c @@ -1,4 +1,4 @@ -/* $OpenBSD$ */ +/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */ /* * Copyright (c) 2014, Theo de Raadt @@ -15,6 +15,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Emulation of getentropy(2) as documented at: + * http://man.openbsd.org/getentropy.2 */ #include @@ -37,7 +40,7 @@ if (len > 256) { errno = EIO; - return -1; + return (-1); } if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, --- contrib/unbound/compat/malloc.c.orig +++ contrib/unbound/compat/malloc.c @@ -5,7 +5,12 @@ #undef malloc #include +#ifndef USE_WINSOCK void *malloc (); +#else +/* provide a prototype */ +void *malloc (size_t n); +#endif /* Allocate an N-byte block of memory from the heap. If N is zero, allocate a 1-byte block. */ --- contrib/unbound/compat/snprintf.c.orig +++ contrib/unbound/compat/snprintf.c @@ -658,7 +658,7 @@ * are not their own functions. */ /* printout designation: - * conversion specifier: x, d, u, s, c, n, m, p + * conversion specifier: x, d, u, s, c, m, p * flags: # not supported * 0 zeropad (on the left) * - left adjust (right by default) @@ -798,7 +798,10 @@ minw, minus); break; case 'n': - *va_arg(arg, int*) = ret; + /* unsupported to harden against format string + * exploitation, + * handled like an unknown format specifier. */ + /* *va_arg(arg, int*) = ret; */ break; case 'm': print_str(&at, &left, &ret, strerror(errno), --- contrib/unbound/config.guess.orig +++ contrib/unbound/config.guess @@ -1,8 +1,8 @@ -#! /bin/sh +#!/usr/bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2013-06-10' +timestamp='2016-10-02' # 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 @@ -24,12 +24,12 @@ # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` @@ -50,7 +50,7 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2013 Free Software Foundation, Inc. +Copyright 1992-2016 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." @@ -149,7 +149,7 @@ LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac @@ -168,8 +168,10 @@ # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; @@ -176,11 +178,19 @@ sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ @@ -197,6 +207,13 @@ os=netbsd ;; esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need @@ -207,13 +224,13 @@ release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` @@ -223,6 +240,10 @@ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; @@ -235,6 +256,9 @@ *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -251,35 +275,35 @@ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. @@ -286,7 +310,7 @@ # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -359,16 +383,16 @@ exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build - SUN_ARCH="i386" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` @@ -393,7 +417,7 @@ exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} @@ -579,8 +603,9 @@ else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi @@ -617,13 +642,13 @@ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi @@ -662,11 +687,11 @@ exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build @@ -679,12 +704,12 @@ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} @@ -789,14 +814,14 @@ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -826,7 +851,7 @@ *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; - i*:MSYS*:*) + *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) @@ -878,7 +903,7 @@ exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix @@ -901,7 +926,7 @@ EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) @@ -932,6 +957,9 @@ crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -944,6 +972,9 @@ ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -969,10 +1000,13 @@ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; - or1k:Linux:*:*) + mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; - or32:Linux:*:*) + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) @@ -1001,6 +1035,9 @@ ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; @@ -1020,7 +1057,7 @@ echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -1099,7 +1136,7 @@ # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1248,6 +1285,9 @@ SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1260,22 +1300,32 @@ if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi @@ -1306,7 +1356,7 @@ # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" @@ -1348,7 +1398,7 @@ echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos @@ -1359,171 +1409,25 @@ x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - cat >&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp --- contrib/unbound/config.h.orig +++ contrib/unbound/config.h @@ -1,1160 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Directory to chroot to */ -#define CHROOT_DIR "/var/unbound" - -/* Do sha512 definitions in config.h */ -/* #undef COMPAT_SHA512 */ - -/* Pathname to the Unbound configuration file */ -#define CONFIGFILE "/var/unbound/unbound.conf" - -/* Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work - */ -/* #undef DARWIN_BROKEN_SETREUID */ - -/* Whether daemon is deprecated */ -/* #undef DEPRECATED_DAEMON */ - -/* default dnstap socket path */ -/* #undef DNSTAP_SOCKET_PATH */ - -/* Define if you want to use debug lock checking (slow). */ -/* #undef ENABLE_LOCK_CHECKS */ - -/* Define this if you enabled-allsymbols from libunbound to link binaries to - it for smaller install size, but the libunbound export table is polluted by - internal symbols */ -/* #undef EXPORT_ALL_SYMBOLS */ - -/* Define to 1 if you have the `arc4random' function. */ -#define HAVE_ARC4RANDOM 1 - -/* Define to 1 if you have the `arc4random_uniform' function. */ -#define HAVE_ARC4RANDOM_UNIFORM 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Whether the C compiler accepts the "format" attribute */ -#define HAVE_ATTR_FORMAT 1 - -/* Whether the C compiler accepts the "unused" attribute */ -#define HAVE_ATTR_UNUSED 1 - -/* Whether the C compiler accepts the "weak" attribute */ -#define HAVE_ATTR_WEAK 1 - -/* Define to 1 if you have the `chown' function. */ -#define HAVE_CHOWN 1 - -/* Define to 1 if you have the `chroot' function. */ -#define HAVE_CHROOT 1 - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - -/* Define to 1 if you have the `ctime_r' function. */ -#define HAVE_CTIME_R 1 - -/* Define to 1 if you have the `daemon' function. */ -#define HAVE_DAEMON 1 - -/* Define to 1 if you have the declaration of `arc4random', and to 0 if you - don't. */ -/* #undef HAVE_DECL_ARC4RANDOM */ - -/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0 - if you don't. */ -/* #undef HAVE_DECL_ARC4RANDOM_UNIFORM */ - -/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you - don't. */ -#define HAVE_DECL_NID_SECP384R1 1 - -/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0 - if you don't. */ -#define HAVE_DECL_NID_X9_62_PRIME256V1 1 - -/* 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 `sk_SSL_COMP_pop_free', and to 0 - if you don't. */ -#define HAVE_DECL_SK_SSL_COMP_POP_FREE 1 - -/* Define to 1 if you have the declaration of - `SSL_COMP_get_compression_methods', and to 0 if you don't. */ -#define HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS 1 - -/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to - 0 if you don't. */ -#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 1 - -/* Define to 1 if you have the declaration of `strlcat', and to 0 if you - don't. */ -/* #undef HAVE_DECL_STRLCAT */ - -/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you - don't. */ -/* #undef HAVE_DECL_STRLCPY */ - -/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if - you don't. */ -#define HAVE_DECL_XML_STOPPARSER 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ENDIAN_H */ - -/* Define to 1 if you have the `endprotoent' function. */ -#define HAVE_ENDPROTOENT 1 - -/* Define to 1 if you have the `endpwent' function. */ -#define HAVE_ENDPWENT 1 - -/* Define to 1 if you have the `endservent' function. */ -#define HAVE_ENDSERVENT 1 - -/* Define to 1 if you have the `ERR_free_strings' function. */ -#define HAVE_ERR_FREE_STRINGS 1 - -/* Define to 1 if you have the `ERR_load_crypto_strings' function. */ -#define HAVE_ERR_LOAD_CRYPTO_STRINGS 1 - -/* 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. */ -/* #undef HAVE_EVENT_BASE_GET_METHOD */ - -/* 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. */ -/* #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 HAVE_EVP_CLEANUP 1 - -/* Define to 1 if you have the `EVP_MD_CTX_new' function. */ -/* #undef HAVE_EVP_MD_CTX_NEW */ - -/* Define to 1 if you have the `EVP_sha1' function. */ -#define HAVE_EVP_SHA1 1 - -/* Define to 1 if you have the `EVP_sha256' function. */ -#define HAVE_EVP_SHA256 1 - -/* Define to 1 if you have the `EVP_sha512' function. */ -#define HAVE_EVP_SHA512 1 - -/* 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. */ -/* #undef HAVE_EV_LOOP */ - -/* Define to 1 if you have the header file. */ -#define HAVE_EXPAT_H 1 - -/* Define to 1 if you have the `fcntl' function. */ -#define HAVE_FCNTL 1 - -/* Define to 1 if you have the `FIPS_mode' function. */ -#define HAVE_FIPS_MODE 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ -#define HAVE_FSEEKO 1 - -/* Define to 1 if you have the `fsync' function. */ -#define HAVE_FSYNC 1 - -/* Whether getaddrinfo is available */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `getauxval' function. */ -/* #undef HAVE_GETAUXVAL */ - -/* Define to 1 if you have the `getentropy' function. */ -/* #undef HAVE_GETENTROPY */ - -/* Define to 1 if you have the header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getpwnam' function. */ -#define HAVE_GETPWNAM 1 - -/* Define to 1 if you have the `getrlimit' function. */ -#define HAVE_GETRLIMIT 1 - -/* Define to 1 if you have the `glob' function. */ -#define HAVE_GLOB 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_GLOB_H 1 - -/* Define to 1 if you have the `gmtime_r' function. */ -#define HAVE_GMTIME_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_GRP_H 1 - -/* If you have HMAC_Update */ -#define HAVE_HMAC_UPDATE 1 - -/* Define to 1 if you have the `inet_aton' function. */ -#define HAVE_INET_ATON 1 - -/* Define to 1 if you have the `inet_ntop' function. */ -#define HAVE_INET_NTOP 1 - -/* Define to 1 if you have the `inet_pton' function. */ -#define HAVE_INET_PTON 1 - -/* Define to 1 if you have the `initgroups' function. */ -#define HAVE_INITGROUPS 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* if the function 'ioctlsocket' is available */ -/* #undef HAVE_IOCTLSOCKET */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IPHLPAPI_H */ - -/* Define to 1 if you have the `isblank' function. */ -#define HAVE_ISBLANK 1 - -/* Define to 1 if you have the `kill' function. */ -#define HAVE_KILL 1 - -/* Define if we have LibreSSL */ -/* #undef HAVE_LIBRESSL */ - -/* Define to 1 if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOGIN_CAP_H 1 - -/* If have GNU libc compatible malloc */ -#define HAVE_MALLOC 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Use libnettle for crypto */ -/* #undef HAVE_NETTLE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETTLE_DSA_COMPAT_H */ - -/* Use libnss for crypto */ -/* #undef HAVE_NSS */ - -/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */ -#define HAVE_OPENSSL_ADD_ALL_DIGESTS 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_BN_H 1 - -/* Define to 1 if you have the `OPENSSL_config' function. */ -#define HAVE_OPENSSL_CONFIG 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_CONF_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_DH_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_DSA_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_ENGINE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_ERR_H 1 - -/* 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. */ -/* #undef HAVE_OPENSSL_INIT_SSL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_RAND_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_SSL_H 1 - -/* Define if you have POSIX threads libraries and header files. */ -#define HAVE_PTHREAD 1 - -/* Have PTHREAD_PRIO_INHERIT. */ -#define HAVE_PTHREAD_PRIO_INHERIT 1 - -/* Define to 1 if the system has the type `pthread_rwlock_t'. */ -#define HAVE_PTHREAD_RWLOCK_T 1 - -/* Define to 1 if the system has the type `pthread_spinlock_t'. */ -#define HAVE_PTHREAD_SPINLOCK_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_PWD_H 1 - -/* Define if you have Python libraries and header files. */ -/* #undef HAVE_PYTHON */ - -/* Define to 1 if you have the `random' function. */ -#define HAVE_RANDOM 1 - -/* Define to 1 if you have the `RAND_cleanup' function. */ -#define HAVE_RAND_CLEANUP 1 - -/* Define to 1 if you have the `reallocarray' function. */ -#define HAVE_REALLOCARRAY 1 - -/* Define to 1 if you have the `recvmsg' function. */ -#define HAVE_RECVMSG 1 - -/* define if you have the sbrk() call */ -/* #undef HAVE_SBRK */ - -/* Define to 1 if you have the `sendmsg' function. */ -#define HAVE_SENDMSG 1 - -/* Define to 1 if you have the `setregid' function. */ -/* #undef HAVE_SETREGID */ - -/* Define to 1 if you have the `setresgid' function. */ -#define HAVE_SETRESGID 1 - -/* Define to 1 if you have the `setresuid' function. */ -#define HAVE_SETRESUID 1 - -/* Define to 1 if you have the `setreuid' function. */ -/* #undef HAVE_SETREUID */ - -/* Define to 1 if you have the `setrlimit' function. */ -#define HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the `setsid' function. */ -#define HAVE_SETSID 1 - -/* Define to 1 if you have the `setusercontext' function. */ -#define HAVE_SETUSERCONTEXT 1 - -/* Define to 1 if you have the `SHA512_Update' function. */ -/* #undef HAVE_SHA512_UPDATE */ - -/* Define to 1 if you have the `sigprocmask' function. */ -#define HAVE_SIGPROCMASK 1 - -/* Define to 1 if you have the `sleep' function. */ -#define HAVE_SLEEP 1 - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the `socketpair' function. */ -#define HAVE_SOCKETPAIR 1 - -/* Using Solaris threads */ -/* #undef HAVE_SOLARIS_THREADS */ - -/* Define to 1 if you have the `srandom' function. */ -#define HAVE_SRANDOM 1 - -/* Define if you have the SSL libraries installed. */ -#define HAVE_SSL /**/ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strftime' function. */ -#define HAVE_STRFTIME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcat' function. */ -#define HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if you have the `strptime' function. */ -#define HAVE_STRPTIME 1 - -/* Define to 1 if you have the `strsep' function. */ -#define HAVE_STRSEP 1 - -/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */ -/* #undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST */ - -/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */ -#define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1 - -/* Define if you have Swig libraries and header files. */ -/* #undef HAVE_SWIG */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYSLOG_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SHA2_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SYSCTL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the `tzset' function. */ -#define HAVE_TZSET 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `usleep' function. */ -#define HAVE_USLEEP 1 - -/* Define to 1 if you have the `vfork' function. */ -#define HAVE_VFORK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_VFORK_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Using Windows threads */ -/* #undef HAVE_WINDOWS_THREADS */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINSOCK2_H */ - -/* Define to 1 if `fork' works. */ -#define HAVE_WORKING_FORK 1 - -/* Define to 1 if `vfork' works. */ -#define HAVE_WORKING_VFORK 1 - -/* Define to 1 if you have the `writev' function. */ -#define HAVE_WRITEV 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WS2TCPIP_H */ - -/* Define to 1 if you have the `_beginthreadex' function. */ -/* #undef HAVE__BEGINTHREADEX */ - -/* if lex has yylex_destroy */ -#define LEX_HAS_YYLEX_DESTROY 1 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Define to the maximum message length to pass to syslog. */ -#define MAXSYSLOGMSGLEN 10240 - -/* Define if memcmp() does not compare unsigned bytes */ -/* #undef MEMCMP_IS_BROKEN */ - -/* Define if mkdir has one argument. */ -/* #undef MKDIR_HAS_ONE_ARG */ - -/* Define if the network stack does not fully support nonblocking io (causes - lower performance). */ -/* #undef NONBLOCKING_IS_BROKEN */ - -/* Put -D_ALL_SOURCE define in config.h */ -/* #undef OMITTED__D_ALL_SOURCE */ - -/* Put -D_BSD_SOURCE define in config.h */ -/* #undef OMITTED__D_BSD_SOURCE */ - -/* Put -D_DEFAULT_SOURCE define in config.h */ -/* #undef OMITTED__D_DEFAULT_SOURCE */ - -/* Put -D_GNU_SOURCE define in config.h */ -/* #undef OMITTED__D_GNU_SOURCE */ - -/* Put -D_LARGEFILE_SOURCE=1 define in config.h */ -/* #undef OMITTED__D_LARGEFILE_SOURCE_1 */ - -/* Put -D_POSIX_C_SOURCE=200112 define in config.h */ -/* #undef OMITTED__D_POSIX_C_SOURCE_200112 */ - -/* Put -D_XOPEN_SOURCE=600 define in config.h */ -/* #undef OMITTED__D_XOPEN_SOURCE_600 */ - -/* Put -D_XOPEN_SOURCE_EXTENDED=1 define in config.h */ -/* #undef OMITTED__D_XOPEN_SOURCE_EXTENDED_1 */ - -/* Put -D__EXTENSIONS__ define in config.h */ -/* #undef OMITTED__D__EXTENSIONS__ */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "unbound-bugs@nlnetlabs.nl" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "unbound" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "unbound 1.5.10" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "unbound" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.5.10" - -/* default pidfile location */ -#define PIDFILE "/var/unbound/unbound.pid" - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* default rootkey location */ -#define ROOT_ANCHOR_FILE "/var/unbound/root.key" - -/* default rootcert location */ -#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem" - -/* version number for resource files */ -#define RSRC_PACKAGE_VERSION 1,5,10,0 - -/* Directory to chdir to */ -#define RUN_DIR "/var/unbound" - -/* Shared data */ -#define SHARE_DIR "/var/unbound" - -/* The size of `time_t', as computed by sizeof. */ -#define SIZEOF_TIME_T 8 - -/* define if (v)snprintf does not return length needed, (but length used) */ -/* #undef SNPRINTF_RET_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* use default strptime. */ -#define STRPTIME_WORKS 1 - -/* Use win32 resources and API */ -/* #undef UB_ON_WINDOWS */ - -/* default username */ -#define UB_USERNAME "unbound" - -/* use to enable lightweight alloc assertions, for debug use */ -/* #undef UNBOUND_ALLOC_LITE */ - -/* use malloc not regions, for debug use */ -/* #undef UNBOUND_ALLOC_NONREGIONAL */ - -/* use statistics for allocs and frees, for debug use */ -/* #undef UNBOUND_ALLOC_STATS */ - -/* define this to enable debug checks. */ -/* #undef UNBOUND_DEBUG */ - -/* Define to 1 to use cachedb support */ -/* #undef USE_CACHEDB */ - -/* Define to 1 to enable dnstap support */ -/* #undef USE_DNSTAP */ - -/* Define this to enable DSA support. */ -#define USE_DSA 1 - -/* Define this to enable ECDSA support. */ -#define USE_ECDSA 1 - -/* Define this to enable an EVP workaround for older openssl */ -/* #undef USE_ECDSA_EVP_WORKAROUND */ - -/* Define this to enable GOST support. */ -#define USE_GOST 1 - -/* Define if you want to use internal select based events */ -#define USE_MINI_EVENT 1 - -/* Define this to enable client TCP Fast Open. */ -/* #undef USE_MSG_FASTOPEN */ - -/* Define this to enable client TCP Fast Open. */ -/* #undef USE_OSX_MSG_FASTOPEN */ - -/* Define this to enable SHA256 and SHA512 support. */ -#define USE_SHA2 1 - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Define this to enable server TCP Fast Open. */ -/* #undef USE_TCP_FASTOPEN */ - -/* Whether the windows socket API is used */ -/* #undef USE_WINSOCK */ - -/* the version of the windows API enabled */ -#define WINVER 0x0502 - -/* Define if you want Python module. */ -/* #undef WITH_PYTHONMODULE */ - -/* Define if you want PyUnbound. */ -/* #undef WITH_PYUNBOUND */ - -/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a - `char[]'. */ -#define YYTEXT_POINTER 1 - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* 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). */ -/* #undef _LARGEFILE_SOURCE */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Enable for compile on Minix */ -/* #undef _NETBSD_SOURCE */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `int' if doesn't define. */ -/* #undef gid_t */ - -/* in_addr_t */ -/* #undef in_addr_t */ - -/* in_port_t */ -/* #undef in_port_t */ - -/* 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 */ -#endif - -/* Define to `short' if does not define. */ -/* #undef int16_t */ - -/* Define to `int' if does not define. */ -/* #undef int32_t */ - -/* Define to `long long' if does not define. */ -/* #undef int64_t */ - -/* Define to `signed char' if does not define. */ -/* #undef int8_t */ - -/* Define if replacement function should be used. */ -/* #undef malloc */ - -/* Define to `long int' if does not define. */ -/* #undef off_t */ - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to 'int' if not defined */ -/* #undef rlim_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to 'int' if not defined */ -/* #undef socklen_t */ - -/* Define to `int' if does not define. */ -/* #undef ssize_t */ - -/* Define to 'unsigned char if not defined */ -/* #undef u_char */ - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define to `unsigned short' if does not define. */ -/* #undef uint16_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef uint32_t */ - -/* Define to `unsigned long long' if does not define. */ -/* #undef uint64_t */ - -/* Define to `unsigned char' if does not define. */ -/* #undef uint8_t */ - -/* Define as `fork' if `vfork' does not work. */ -/* #undef vfork */ - -#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE) -#define _GNU_SOURCE 1 -#endif - -#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE) -#define _BSD_SOURCE 1 -#endif - -#if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE) -#define _DEFAULT_SOURCE 1 -#endif - -#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__) -#define __EXTENSIONS__ 1 -#endif - -#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112 -#endif - -#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE) -#define _XOPEN_SOURCE 600 -#endif - -#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED) -#define _XOPEN_SOURCE_EXTENDED 1 -#endif - -#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE) -#define _ALL_SOURCE 1 -#endif - -#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE) -#define _LARGEFILE_SOURCE 1 -#endif - - - - -#ifndef UNBOUND_DEBUG -# define NDEBUG -#endif - -/** Use small-ldns codebase */ -#define USE_SLDNS 1 -#ifdef HAVE_SSL -# define LDNS_BUILD_CONFIG_HAVE_SSL 1 -#endif - -#include -#include -#include -#include - -#if STDC_HEADERS -#include -#include -#endif - -#ifdef HAVE_STDARG_H -#include -#endif - -#ifdef HAVE_STDINT_H -#include -#endif - -#include - -#if HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifdef HAVE_SYS_UIO_H -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_NETINET_TCP_H -#include -#endif - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef HAVE_WINSOCK2_H -#include -#endif - -#ifdef HAVE_WS2TCPIP_H -#include -#endif - -#ifndef USE_WINSOCK -#define ARG_LL "%ll" -#else -#define ARG_LL "%I64" -#endif - -#ifndef AF_LOCAL -#define AF_LOCAL AF_UNIX -#endif - - - -#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 */ - - -#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 */ - - -#ifndef HAVE_FSEEKO -#define fseeko fseek -#define ftello ftell -#endif /* HAVE_FSEEKO */ - - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN) -#define snprintf snprintf_unbound -#define vsnprintf vsnprintf_unbound -#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 or SNPRINTF_RET_BROKEN */ - -#ifndef HAVE_INET_PTON -#define inet_pton inet_pton_unbound -int inet_pton(int af, const char* src, void* dst); -#endif /* HAVE_INET_PTON */ - - -#ifndef HAVE_INET_NTOP -#define inet_ntop inet_ntop_unbound -const char *inet_ntop(int af, const void *src, char *dst, size_t size); -#endif - - -#ifndef HAVE_INET_ATON -#define inet_aton inet_aton_unbound -int inet_aton(const char *cp, struct in_addr *addr); -#endif - - -#ifndef HAVE_MEMMOVE -#define memmove memmove_unbound -void *memmove(void *dest, const void *src, size_t n); -#endif - - -#ifndef HAVE_STRLCAT -#define strlcat strlcat_unbound -size_t strlcat(char *dst, const char *src, size_t siz); -#endif - - -#ifndef HAVE_STRLCPY -#define strlcpy strlcpy_unbound -size_t strlcpy(char *dst, const char *src, size_t siz); -#endif - - -#ifndef HAVE_GMTIME_R -#define gmtime_r gmtime_r_unbound -struct tm *gmtime_r(const time_t *timep, struct tm *result); -#endif - - -#ifndef HAVE_REALLOCARRAY -#define reallocarray reallocarrayunbound -void* reallocarray(void *ptr, size_t nmemb, size_t size); -#endif - - -#if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H) -#define sleep(x) Sleep((x)*1000) /* on win32 */ -#endif /* HAVE_SLEEP */ - - -#ifndef HAVE_USLEEP -#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */ -#endif /* HAVE_USLEEP */ - - -#ifndef HAVE_RANDOM -#define random rand /* on win32, for tests only (bad random) */ -#endif /* HAVE_RANDOM */ - - -#ifndef HAVE_SRANDOM -#define srandom(x) srand(x) /* on win32, for tests only (bad random) */ -#endif /* HAVE_SRANDOM */ - - -/* 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 - - -#ifndef IPV6_MIN_MTU -#define IPV6_MIN_MTU 1280 -#endif /* IPV6_MIN_MTU */ - - -#ifdef MEMCMP_IS_BROKEN -#include "compat/memcmp.h" -#define memcmp memcmp_unbound -int memcmp(const void *x, const void *y, size_t n); -#endif - - - -#ifndef HAVE_CTIME_R -#define ctime_r unbound_ctime_r -char *ctime_r(const time_t *timep, char *buf); -#endif - -#ifndef HAVE_STRSEP -#define strsep unbound_strsep -char *strsep(char **stringp, const char *delim); -#endif - -#ifndef HAVE_ISBLANK -#define isblank unbound_isblank -int isblank(int c); -#endif - -#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS) -#define strptime unbound_strptime -struct tm; -char *strptime(const char *s, const char *format, struct tm *tm); -#endif - -#ifdef HAVE_LIBRESSL -# if !HAVE_DECL_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t siz); -# endif -# if !HAVE_DECL_STRLCAT -size_t strlcat(char *dst, const char *src, size_t siz); -# endif -# if !HAVE_DECL_ARC4RANDOM && defined(HAVE_ARC4RANDOM) -uint32_t arc4random(void); -# endif -# if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM) -uint32_t arc4random_uniform(uint32_t upper_bound); -# endif -# if !HAVE_DECL_REALLOCARRAY -void *reallocarray(void *ptr, size_t nmemb, size_t size); -# endif -#endif /* HAVE_LIBRESSL */ -#ifndef HAVE_ARC4RANDOM -void explicit_bzero(void* buf, size_t len); -int getentropy(void* buf, size_t len); -uint32_t arc4random(void); -void arc4random_buf(void* buf, size_t n); -void _ARC4_LOCK(void); -void _ARC4_UNLOCK(void); -#endif -#ifndef HAVE_ARC4RANDOM_UNIFORM -uint32_t arc4random_uniform(uint32_t upper_bound); -#endif -#ifdef COMPAT_SHA512 -#ifndef SHA512_DIGEST_LENGTH -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) -typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; -#endif /* SHA512_DIGEST_LENGTH */ -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, void*, size_t); -void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest); -#endif /* COMPAT_SHA512 */ - - - -#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)) - /* using version of libevent that is not threadsafe. */ -# define LIBEVENT_SIGNAL_PROBLEM 1 -#endif - -#ifndef CHECKED_INET6 -# define CHECKED_INET6 -# ifdef AF_INET6 -# define INET6 -# else -# define AF_INET6 28 -# endif -#endif /* CHECKED_INET6 */ - -#ifndef HAVE_GETADDRINFO -struct sockaddr_storage; -#include "compat/fake-rfc2553.h" -#endif - -#ifdef UNBOUND_ALLOC_STATS -# define malloc(s) unbound_stat_malloc_log(s, __FILE__, __LINE__, __func__) -# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__) -# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__) -# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__) -void *unbound_stat_malloc(size_t size); -void *unbound_stat_calloc(size_t nmemb, size_t size); -void unbound_stat_free(void *ptr); -void *unbound_stat_realloc(void *ptr, size_t size); -void *unbound_stat_malloc_log(size_t size, const char* file, int line, - const char* func); -void *unbound_stat_calloc_log(size_t nmemb, size_t size, const char* file, - int line, const char* func); -void unbound_stat_free_log(void *ptr, const char* file, int line, - const char* func); -void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, - int line, const char* func); -#elif defined(UNBOUND_ALLOC_LITE) -# include "util/alloc.h" -#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */ - -/** default port for DNS traffic. */ -#define UNBOUND_DNS_PORT 53 -/** default port for unbound control traffic, registered port with IANA, - ub-dns-control 8953/tcp unbound dns nameserver control */ -#define UNBOUND_CONTROL_PORT 8953 -/** the version of unbound-control that this software implements */ -#define UNBOUND_CONTROL_VERSION 1 - - --- contrib/unbound/config.h.in.orig +++ contrib/unbound/config.h.in @@ -1,11 +1,23 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* apply the noreturn attribute to a function that exits the program */ +#undef ATTR_NORETURN + +/* apply the weak attribute to a symbol */ +#undef ATTR_WEAK + /* Directory to chroot to */ #undef CHROOT_DIR +/* Define this to enable client subnet option. */ +#undef CLIENT_SUBNET + /* Do sha512 definitions in config.h */ #undef COMPAT_SHA512 +/* Command line arguments used with configure */ +#undef CONFCMDLINE + /* Pathname to the Unbound configuration file */ #undef CONFIGFILE @@ -27,6 +39,9 @@ internal symbols */ #undef EXPORT_ALL_SYMBOLS +/* Define to 1 if you have the `accept4' function. */ +#undef HAVE_ACCEPT4 + /* Define to 1 if you have the `arc4random' function. */ #undef HAVE_ARC4RANDOM @@ -39,6 +54,9 @@ /* Whether the C compiler accepts the "format" attribute */ #undef HAVE_ATTR_FORMAT +/* Whether the C compiler accepts the "noreturn" attribute */ +#undef HAVE_ATTR_NORETURN + /* Whether the C compiler accepts the "unused" attribute */ #undef HAVE_ATTR_UNUSED @@ -45,6 +63,15 @@ /* Whether the C compiler accepts the "weak" attribute */ #undef HAVE_ATTR_WEAK +/* If we have be64toh */ +#undef HAVE_BE64TOH + +/* Define to 1 if you have the header file. */ +#undef HAVE_BSD_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BSD_STRING_H + /* Define to 1 if you have the `chown' function. */ #undef HAVE_CHOWN @@ -54,6 +81,9 @@ /* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA +/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */ +#undef HAVE_CRYPTO_THREADID_SET_CALLBACK + /* Define to 1 if you have the `ctime_r' function. */ #undef HAVE_CTIME_R @@ -68,6 +98,26 @@ if you don't. */ #undef HAVE_DECL_ARC4RANDOM_UNIFORM +/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if + you don't. */ +#undef HAVE_DECL_EVSIGNAL_ASSIGN + +/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you + don't. */ +#undef HAVE_DECL_INET_NTOP + +/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you + don't. */ +#undef HAVE_DECL_INET_PTON + +/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you + don't. */ +#undef HAVE_DECL_NID_ED25519 + +/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you + don't. */ +#undef HAVE_DECL_NID_ED448 + /* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you don't. */ #undef HAVE_DECL_NID_SECP384R1 @@ -80,6 +130,10 @@ don't. */ #undef HAVE_DECL_REALLOCARRAY +/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you + don't. */ +#undef HAVE_DECL_REDISCONNECT + /* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0 if you don't. */ #undef HAVE_DECL_SK_SSL_COMP_POP_FREE @@ -107,6 +161,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `DSA_SIG_set0' function. */ +#undef HAVE_DSA_SIG_SET0 + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H @@ -125,6 +182,9 @@ /* 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 `event_assign' function. */ +#undef HAVE_EVENT_ASSIGN + /* Define to 1 if you have the `event_base_free' function. */ #undef HAVE_EVENT_BASE_FREE @@ -140,9 +200,21 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EVENT_H +/* Define to 1 if you have the `EVP_aes_256_cbc' function. */ +#undef HAVE_EVP_AES_256_CBC + /* Define to 1 if you have the `EVP_cleanup' function. */ #undef HAVE_EVP_CLEANUP +/* Define to 1 if you have the `EVP_DigestVerify' function. */ +#undef HAVE_EVP_DIGESTVERIFY + +/* Define to 1 if you have the `EVP_dss1' function. */ +#undef HAVE_EVP_DSS1 + +/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ +#undef HAVE_EVP_ENCRYPTINIT_EX + /* Define to 1 if you have the `EVP_MD_CTX_new' function. */ #undef HAVE_EVP_MD_CTX_NEW @@ -164,6 +236,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EXPAT_H +/* Define to 1 if you have the `explicit_bzero' function. */ +#undef HAVE_EXPLICIT_BZERO + /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL @@ -209,9 +284,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_GRP_H +/* Define to 1 if you have the header file. */ +#undef HAVE_HIREDIS_HIREDIS_H + +/* Define to 1 if you have the `HMAC_Init_ex' function. */ +#undef HAVE_HMAC_INIT_EX + /* If you have HMAC_Update */ #undef HAVE_HMAC_UPDATE +/* If we have htobe64 */ +#undef HAVE_HTOBE64 + /* Define to 1 if you have the `inet_aton' function. */ #undef HAVE_INET_ATON @@ -239,6 +323,12 @@ /* Define to 1 if you have the `kill' function. */ #undef HAVE_KILL +/* Use portable libbsd functions */ +#undef HAVE_LIBBSD + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBKERN_OSBYTEORDER_H + /* Define if we have LibreSSL */ #undef HAVE_LIBRESSL @@ -272,6 +362,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETTLE_DSA_COMPAT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NETTLE_EDDSA_H + /* Use libnss for crypto */ #undef HAVE_NSS @@ -338,15 +431,12 @@ /* Define to 1 if you have the `RAND_cleanup' function. */ #undef HAVE_RAND_CLEANUP -/* Define to 1 if you have the `reallocarray' function. */ +/* If we have reallocarray(3) */ #undef HAVE_REALLOCARRAY /* Define to 1 if you have the `recvmsg' function. */ #undef HAVE_RECVMSG -/* define if you have the sbrk() call */ -#undef HAVE_SBRK - /* Define to 1 if you have the `sendmsg' function. */ #undef HAVE_SENDMSG @@ -374,6 +464,9 @@ /* Define to 1 if you have the `SHA512_Update' function. */ #undef HAVE_SHA512_UPDATE +/* Define to 1 if you have the `shmget' function. */ +#undef HAVE_SHMGET + /* Define to 1 if you have the `sigprocmask' function. */ #undef HAVE_SIGPROCMASK @@ -395,6 +488,21 @@ /* Define if you have the SSL libraries installed. */ #undef HAVE_SSL +/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */ +#undef HAVE_SSL_CTX_SET_CIPHERSUITES + +/* 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_CTX_set_tlsext_ticket_key_cb' function. */ +#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB + +/* Define to 1 if you have the `SSL_get0_peername' function. */ +#undef HAVE_SSL_GET0_PEERNAME + +/* Define to 1 if you have the `SSL_set1_host' function. */ +#undef HAVE_SSL_SET1_HOST + /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H @@ -440,6 +548,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H +/* Define to 1 if systemd should be used */ +#undef HAVE_SYSTEMD + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_ENDIAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IPC_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H @@ -449,6 +566,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SHA2_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SHM_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H @@ -509,9 +629,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WS2TCPIP_H +/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */ +#undef HAVE_X509_VERIFY_PARAM_SET1_HOST + /* Define to 1 if you have the `_beginthreadex' function. */ #undef HAVE__BEGINTHREADEX +/* If HMAC_Init_ex() returns void */ +#undef HMAC_INIT_EX_RETURNS_VOID + /* if lex has yylex_destroy */ #undef LEX_HAS_YYLEX_DESTROY @@ -586,6 +712,9 @@ /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE +/* if REUSEPORT is enabled by default */ +#undef REUSEPORT_DEFAULT + /* default rootkey location */ #undef ROOT_ANCHOR_FILE @@ -601,6 +730,9 @@ /* Shared data */ #undef SHARE_DIR +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + /* The size of `time_t', as computed by sizeof. */ #undef SIZEOF_TIME_T @@ -607,6 +739,9 @@ /* define if (v)snprintf does not return length needed, (but length used) */ #undef SNPRINTF_RET_BROKEN +/* Define to 1 if libsodium supports sodium_set_misuse_handler */ +#undef SODIUM_MISUSE_HANDLER + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS @@ -616,6 +751,9 @@ /* Use win32 resources and API */ #undef UB_ON_WINDOWS +/* the SYSLOG_FACILITY to use, default LOG_DAEMON */ +#undef UB_SYSLOG_FACILITY + /* default username */ #undef UB_USERNAME @@ -634,6 +772,12 @@ /* Define to 1 to use cachedb support */ #undef USE_CACHEDB +/* Define to 1 to enable dnscrypt support */ +#undef USE_DNSCRYPT + +/* Define to 1 to enable dnscrypt with xchacha20 support */ +#undef USE_DNSCRYPT_XCHACHA20 + /* Define to 1 to enable dnstap support */ #undef USE_DNSTAP @@ -646,9 +790,21 @@ /* Define this to enable an EVP workaround for older openssl */ #undef USE_ECDSA_EVP_WORKAROUND +/* Define this to enable ED25519 support. */ +#undef USE_ED25519 + +/* Define this to enable ED448 support. */ +#undef USE_ED448 + /* Define this to enable GOST support. */ #undef USE_GOST +/* Define to 1 to use ipsecmod support. */ +#undef USE_IPSECMOD + +/* Define to 1 to use ipset support */ +#undef USE_IPSET + /* Define if you want to use internal select based events */ #undef USE_MINI_EVENT @@ -658,6 +814,12 @@ /* Define this to enable client TCP Fast Open. */ #undef USE_OSX_MSG_FASTOPEN +/* Define this to use hiredis client. */ +#undef USE_REDIS + +/* Define this to enable SHA1 support. */ +#undef USE_SHA1 + /* Define this to enable SHA256 and SHA512 support. */ #undef USE_SHA2 @@ -840,8 +1002,14 @@ +#ifndef _OPENBSD_SOURCE +#define _OPENBSD_SOURCE 1 +#endif + #ifndef UNBOUND_DEBUG +# ifndef NDEBUG # define NDEBUG +# endif #endif /** Use small-ldns codebase */ @@ -1055,6 +1223,19 @@ int isblank(int c); #endif +#ifndef HAVE_EXPLICIT_BZERO +#define explicit_bzero unbound_explicit_bzero +void explicit_bzero(void* buf, size_t len); +#endif + +#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + +#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON +int inet_pton(int af, const char* src, void* dst); +#endif + #if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS) #define strptime unbound_strptime struct tm; @@ -1061,6 +1242,15 @@ char *strptime(const char *s, const char *format, struct tm *tm); #endif +#if !HAVE_DECL_REALLOCARRAY +void *reallocarray(void *ptr, size_t nmemb, size_t size); +#endif + +#ifdef HAVE_LIBBSD +#include +#include +#endif + #ifdef HAVE_LIBRESSL # if !HAVE_DECL_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz); @@ -1074,17 +1264,14 @@ # if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM) uint32_t arc4random_uniform(uint32_t upper_bound); # endif -# if !HAVE_DECL_REALLOCARRAY -void *reallocarray(void *ptr, size_t nmemb, size_t size); -# endif #endif /* HAVE_LIBRESSL */ #ifndef HAVE_ARC4RANDOM -void explicit_bzero(void* buf, size_t len); int getentropy(void* buf, size_t len); uint32_t arc4random(void); void arc4random_buf(void* buf, size_t n); void _ARC4_LOCK(void); void _ARC4_UNLOCK(void); +void _ARC4_LOCK_DESTROY(void); #endif #ifndef HAVE_ARC4RANDOM_UNIFORM uint32_t arc4random_uniform(uint32_t upper_bound); @@ -1150,6 +1337,8 @@ /** default port for DNS traffic. */ #define UNBOUND_DNS_PORT 53 +/** default port for DNS over TLS traffic. */ +#define UNBOUND_DNS_OVER_TLS_PORT 853 /** default port for unbound control traffic, registered port with IANA, ub-dns-control 8953/tcp unbound dns nameserver control */ #define UNBOUND_CONTROL_PORT 8953 --- contrib/unbound/config.sub.orig +++ contrib/unbound/config.sub @@ -1,8 +1,8 @@ -#! /bin/sh +#!/usr/bin/sh # Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2013-08-10' +timestamp='2016-09-05' # 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 @@ -25,7 +25,7 @@ # of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -33,7 +33,7 @@ # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,8 +53,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. @@ -68,7 +67,7 @@ version="\ GNU config.sub ($timestamp) -Copyright 1992-2013 Free Software Foundation, Inc. +Copyright 1992-2016 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." @@ -117,8 +116,8 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` @@ -255,16 +254,18 @@ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ @@ -282,8 +283,10 @@ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ @@ -295,14 +298,14 @@ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ + | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ + | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -310,6 +313,7 @@ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -324,7 +328,10 @@ c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -369,12 +376,13 @@ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ + | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ @@ -381,6 +389,7 @@ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ @@ -400,8 +409,10 @@ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ @@ -413,16 +424,18 @@ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ + | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -430,6 +443,7 @@ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ + | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -506,6 +520,9 @@ basic_machine=i386-pc os=-aros ;; + asmjs) + basic_machine=asmjs-unknown + ;; aux) basic_machine=m68k-apple os=-aux @@ -626,6 +643,14 @@ basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -767,6 +792,9 @@ basic_machine=m68k-isi os=-sysv ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; m68knommu) basic_machine=m68k-unknown os=-linux @@ -822,6 +850,10 @@ basic_machine=powerpc-unknown os=-morphos ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; msdos) basic_machine=i386-pc os=-msdos @@ -998,7 +1030,7 @@ ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) @@ -1006,9 +1038,9 @@ ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) @@ -1354,11 +1386,11 @@ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ @@ -1365,9 +1397,9 @@ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ @@ -1374,7 +1406,8 @@ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1506,6 +1539,8 @@ ;; -nacl*) ;; + -ios) + ;; -none) ;; *) @@ -1592,9 +1627,6 @@ mips*-*) os=-elf ;; - or1k-*) - os=-elf - ;; or32-*) os=-coff ;; --- contrib/unbound/configure.orig +++ contrib/unbound/configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for unbound 1.5.10. +# Generated by GNU Autoconf 2.69 for unbound 1.10.1. # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -275,10 +275,11 @@ $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: unbound-bugs@nlnetlabs.nl about your system, including -$0: any error possibly output before this message. Then -$0: install a modern shell, or manually run the script -$0: under such a shell if you do have one." +$0: unbound-bugs@nlnetlabs.nl or +$0: https://github.com/NLnetLabs/unbound/issues about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -590,9 +591,9 @@ # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.5.10' -PACKAGE_STRING='unbound 1.5.10' -PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl' +PACKAGE_VERSION='1.10.1' +PACKAGE_STRING='unbound 1.10.1' +PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_URL='' # Factoring default headers for most tests. @@ -638,6 +639,14 @@ ALLTARGET SOURCEFILE SOURCEDETERMINE +IPSET_OBJ +IPSET_SRC +IPSECMOD_HEADER +IPSECMOD_OBJ +DNSCRYPT_OBJ +DNSCRYPT_SRC +ENABLE_DNSCRYPT +ENABLE_DNSCRYPT_XCHACHA20 DNSTAP_OBJ DNSTAP_SRC opt_dnstap_socket_path @@ -659,10 +668,15 @@ WINDRES CHECKLOCK_OBJ staticexe +PC_LIBEVENT_DEPENDENCY UNBOUND_EVENT_UNINSTALL UNBOUND_EVENT_INSTALL +SUBNET_HEADER +SUBNET_OBJ +PC_LIBBSD_DEPENDENCY SSLLIB HAVE_SSL +PC_CRYPTO_DEPENDENCY CONFIG_DATE NETBSD_LINTFLAGS PYUNBOUND_UNINSTALL @@ -678,6 +692,7 @@ swig SWIG_LIB SWIG +PC_PY_DEPENDENCY PY_MAJOR_VERSION PYTHON_SITE_PKG PYTHON_LDFLAGS @@ -689,8 +704,19 @@ PTHREAD_LIBS PTHREAD_CC ax_pthread_config +ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ +SLDNS_ALLOCCHECK_EXTRA_OBJ +USE_SYSTEMD_FALSE +USE_SYSTEMD_TRUE +SYSTEMD_DAEMON_LIBS +SYSTEMD_DAEMON_CFLAGS +SYSTEMD_LIBS +SYSTEMD_CFLAGS RUNTIME_PATH LIBOBJS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG LT_SYS_LIBRARY_PATH OTOOL64 OTOOL @@ -739,6 +765,9 @@ UNBOUND_RUN_DIR ub_conf_dir ub_conf_file +UNBOUND_LOCALSTATE_DIR +UNBOUND_SYSCONF_DIR +UNBOUND_SBIN_DIR EGREP GREP CPP @@ -819,26 +848,36 @@ enable_libtool_lock enable_rpath enable_largefile +enable_systemd enable_alloc_checks enable_alloc_lite enable_alloc_nonregional with_pthreads with_solaris_threads +with_syslog_facility with_pyunbound with_pythonmodule +enable_swig_version_check with_nss with_nettle with_ssl +with_libbsd +enable_sha1 enable_sha2 +enable_subnet enable_gost enable_ecdsa enable_dsa +enable_ed25519 +enable_ed448 enable_event_api enable_tfo_client enable_tfo_server with_libevent with_libexpat +with_libhiredis enable_static_exe +enable_fully_static enable_lock_checks enable_allsymbols enable_dnstap @@ -845,7 +884,12 @@ with_dnstap_socket_path with_protobuf_c with_libfstrm +enable_dnscrypt +with_libsodium enable_cachedb +enable_ipsecmod +enable_ipset +with_libmnl with_libunbound_only ' ac_precious_vars='build_alias @@ -860,6 +904,13 @@ YACC YFLAGS LT_SYS_LIBRARY_PATH +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +SYSTEMD_CFLAGS +SYSTEMD_LIBS +SYSTEMD_DAEMON_CFLAGS +SYSTEMD_DAEMON_LIBS PYTHON_VERSION' @@ -1401,7 +1452,7 @@ # 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 unbound 1.5.10 to adapt to many kinds of systems. +\`configure' configures unbound 1.10.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1466,7 +1517,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.5.10:";; + short | recursive ) echo "Configuration of unbound 1.10.1:";; esac cat <<\_ACEOF @@ -1488,6 +1539,7 @@ --disable-libtool-lock avoid locking (might break parallel builds) --disable-rpath disable hardcoded rpath (default=enabled) --disable-largefile omit support for large files + --enable-systemd compile with systemd support --enable-alloc-checks enable to memory allocation statistics, for debug purposes --enable-alloc-lite enable for lightweight alloc assertions, for debug @@ -1496,16 +1548,25 @@ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes + --disable-swig-version-check + Disable swig version check to build python modules + with older swig even though that is unreliable + --disable-sha1 Disable SHA1 RRSIG support, does not disable nsec3 + support --disable-sha2 Disable SHA256 and SHA512 RRSIG support + --enable-subnet Enable client subnet --disable-gost Disable GOST support --disable-ecdsa Disable ECDSA support --disable-dsa Disable DSA support + --disable-ed25519 Disable ED25519 support + --disable-ed448 Disable ED448 support --enable-event-api Enable (experimental) pluggable event base libunbound API installed to unbound-event.h --enable-tfo-client Enable TCP Fast Open for client mode --enable-tfo-server Enable TCP Fast Open for server mode --enable-static-exe enable to compile executables statically against - (event) libs, for debug purposes + (event) uninstalled libs, for debug purposes + --enable-fully-static enable to compile fully static --enable-lock-checks enable to check lock and unlock calls, for debug purposes --enable-allsymbols export all symbols from libunbound and link binaries @@ -1512,8 +1573,12 @@ to it, smaller install size but libunbound export table is polluted by internal symbols --enable-dnstap Enable dnstap support (requires fstrm, protobuf-c) + --enable-dnscrypt Enable dnscrypt support (requires libsodium) --enable-cachedb enable cachedb module that can use external cache storage + --enable-ipsecmod Enable ipsecmod module that facilitates + opportunistic IPsec + --enable-ipset enable ipset module Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1547,6 +1612,8 @@ --with-pthreads use pthreads library, or --without-pthreads to disable threading support. --with-solaris-threads use solaris native thread library. + --with-syslog-facility=LOCAL0 - LOCAL7 + set SYSLOG_FACILITY, default DAEMON --with-pyunbound build PyUnbound, or --without-pyunbound to skip it. (default=no) --with-pythonmodule build Python module, or --without-pythonmodule to @@ -1556,6 +1623,7 @@ --with-ssl=pathname enable SSL (will check /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr) + --with-libbsd Use portable libbsd functions --with-libevent=pathname use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify @@ -1562,10 +1630,13 @@ an explicit path). Slower, but allows use of large outgoing port ranges. --with-libexpat=path specify explicit path for libexpat. + --with-libhiredis=path specify explicit path for libhiredis. --with-dnstap-socket-path=pathname set default dnstap socket path --with-protobuf-c=path Path where protobuf-c is installed, for dnstap --with-libfstrm=path Path where libfstrm is installed, for dnstap + --with-libsodium=path Path where libsodium is installed, for dnscrypt + --with-libmnl=path specify explicit path for libmnl. --with-libunbound-only do not build daemon and tool programs Some influential environment variables: @@ -1585,6 +1656,19 @@ default value of `-d' given by some make applications. LT_SYS_LIBRARY_PATH User-defined run-time library search path. + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + SYSTEMD_CFLAGS + C compiler flags for SYSTEMD, overriding pkg-config + SYSTEMD_LIBS + linker flags for SYSTEMD, overriding pkg-config + SYSTEMD_DAEMON_CFLAGS + C compiler flags for SYSTEMD_DAEMON, overriding pkg-config + SYSTEMD_DAEMON_LIBS + linker flags for SYSTEMD_DAEMON, overriding pkg-config PYTHON_VERSION The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical @@ -1593,7 +1677,7 @@ 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 . +Report bugs to . _ACEOF ac_status=$? fi @@ -1656,7 +1740,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.5.10 +unbound configure 1.10.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1815,9 +1899,9 @@ $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ---------------------------------------- ## -## Report this to unbound-bugs@nlnetlabs.nl ## -## ---------------------------------------- ##" +( $as_echo "## --------------------------------------------------------------------------------------- ## +## Report this to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues ## +## --------------------------------------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac @@ -2365,7 +2449,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by unbound $as_me 1.5.10, which was +It was created by unbound $as_me 1.10.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2715,14 +2799,14 @@ UNBOUND_VERSION_MAJOR=1 -UNBOUND_VERSION_MINOR=5 +UNBOUND_VERSION_MINOR=10 -UNBOUND_VERSION_MICRO=10 +UNBOUND_VERSION_MICRO=1 -LIBUNBOUND_CURRENT=6 -LIBUNBOUND_REVISION=2 -LIBUNBOUND_AGE=4 +LIBUNBOUND_CURRENT=9 +LIBUNBOUND_REVISION=8 +LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 # 1.0.2 had 0:14:0 @@ -2771,6 +2855,32 @@ # 1.5.8 had 6:0:4 # adds ub_ctx_set_stub # 1.5.9 had 6:1:4 # 1.5.10 had 6:2:4 +# 1.6.0 had 6:3:4 +# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type +# 1.6.2 had 7:1:5 +# 1.6.3 had 7:2:5 +# 1.6.4 had 7:3:5 +# 1.6.5 had 7:4:5 +# 1.6.6 had 7:5:5 +# 1.6.7 had 7:6:5 +# 1.6.8 had 7:7:5 +# 1.7.0 had 7:8:5 +# 1.7.1 had 7:9:5 +# 1.7.2 had 7:10:5 +# 1.7.3 had 7:11:5 +# 1.8.0 had 8:0:0 # changes the event callback function signature +# 1.8.1 had 8:1:0 +# 1.8.2 had 8:2:0 +# 1.8.3 had 8:3:0 +# 1.9.0 had 9:0:1 # add ub_ctx_set_tls +# 1.9.1 had 9:1:1 +# 1.9.2 had 9:2:1 +# 1.9.3 had 9:3:1 +# 1.9.4 had 9:4:1 +# 1.9.5 had 9:5:1 +# 1.9.6 had 9:6:1 +# 1.10.0 had 9:7:1 +# 1.10.1 had 9:8:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -2786,7 +2896,7 @@ # Current and Age. Set Revision to 0, since this is the first # implementation of the new API. # -# Otherwise, we're changing the binary API and breaking bakward +# Otherwise, we're changing the binary API and breaking backward # compatibility with old binaries. Increment Current. Set Age to 0, # since we're backward compatible with no previous APIs. Set Revision # to 0 too. @@ -2794,6 +2904,14 @@ + +cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`" + +cat >>confdefs.h <<_ACEOF +#define CONFCMDLINE "$cmdln" +_ACEOF + + CFLAGS="$CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -4055,6 +4173,11 @@ prefix="/usr/local" ;; esac +case "$exec_prefix" in + NONE) + exec_prefix="$prefix" + ;; +esac # are we on MinGW? if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes" @@ -4066,10 +4189,16 @@ # # Determine configuration file # the eval is to evaluate shell expansion twice +UNBOUND_SBIN_DIR=`eval echo "${sbindir}"` + +UNBOUND_SYSCONF_DIR=`eval echo "${sysconfdir}"` + +UNBOUND_LOCALSTATE_DIR=`eval echo "${localstatedir}"` + if test $on_mingw = "no"; then ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"` else - ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf" + ub_conf_file="C:\\Program Files\\Unbound\\service.conf" fi # Check whether --with-conf_file was given. @@ -4200,7 +4329,7 @@ if test $on_mingw = no; then UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key" else - UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key" + UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key" fi fi @@ -4222,7 +4351,7 @@ if test $on_mingw = no; then UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem" else - UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem" + UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem" fi fi @@ -4351,6 +4480,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # allow user to override the -g -O2 flags. +default_cflags=no if test "x$CFLAGS" = "x" ; then @@ -4414,6 +4544,7 @@ fi +default_cflags=yes fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -5867,6 +5998,10 @@ # nothing to do. ;; esac +if test "$default_cflags" = "yes"; then + # only when CFLAGS was "" at the start, if the users wants to + # override we shouldn't add default cflags, because they wouldn't + # be able to turn off these options and set the CFLAGS wanted. # Check whether --enable-flto was given. if test "${enable_flto+set}" = set; then : @@ -6001,6 +6136,7 @@ fi +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } @@ -6167,9 +6303,57 @@ $as_echo "#define HAVE_ATTR_WEAK 1" >>confdefs.h + +$as_echo "#define ATTR_WEAK __attribute__((weak))" >>confdefs.h + fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"noreturn\" attribute" >&5 +$as_echo_n "checking whether the C compiler (${CC-cc}) accepts the \"noreturn\" attribute... " >&6; } +if ${ac_cv_c_noreturn_attribute+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_noreturn_attribute=no +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +__attribute__((noreturn)) void f(int x) { printf("%d", x); } + +int +main () +{ + + f(1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_noreturn_attribute="yes" +else + ac_cv_c_noreturn_attribute="no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_noreturn_attribute" >&5 +$as_echo "$ac_cv_c_noreturn_attribute" >&6; } +if test $ac_cv_c_noreturn_attribute = yes; then + +$as_echo "#define HAVE_ATTR_NORETURN 1" >>confdefs.h + + +$as_echo "#define ATTR_NORETURN __attribute__((__noreturn__))" >>confdefs.h + +fi + + if test "$srcdir" != "."; then CPPFLAGS="$CPPFLAGS -I$srcdir" fi @@ -6176,6 +6360,8 @@ + + for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -6335,6 +6521,7 @@ rm -f conftest.l $LEX_OUTPUT_ROOT.c fi +if test "$LEX" != "" -a "$LEX" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yylex_destroy" >&5 $as_echo_n "checking for yylex_destroy... " >&6; } @@ -6345,8 +6532,27 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; }; fi +$as_echo "no" >&6; }; + LEX=":" + fi +fi +if test "$LEX" != "" -a "$LEX" != ":"; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lex %option" >&5 +$as_echo_n "checking for lex %option... " >&6; } + if cat <&1 | grep yy_delete_buffer >/dev/null 2>&1; then +%option nounput +%% +EOF + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; + LEX=":" + fi + +fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -14386,8 +14592,129 @@ + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # 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 + test -z "$as_dir" && as_dir=. + 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_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$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 +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # 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 + test -z "$as_dir" && as_dir=. + 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_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$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 +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + # Checks for header files. -for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h +for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default @@ -14750,7 +15077,40 @@ _ACEOF +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 +$as_echo_n "checking size of size_t... " >&6; } +if ${ac_cv_sizeof_size_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : +else + if test "$ac_cv_type_size_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (size_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_size_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 +$as_echo "$ac_cv_sizeof_size_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t +_ACEOF + + + # add option to disable the evil rpath # Check whether --enable-rpath was given. @@ -15797,6 +16157,208 @@ done +# check if we can use SO_REUSEPORT +if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then + +$as_echo "#define REUSEPORT_DEFAULT 1" >>confdefs.h + +else + +$as_echo "#define REUSEPORT_DEFAULT 0" >>confdefs.h + +fi + +# Include systemd.m4 - begin +# macros for configuring systemd +# Copyright 2015, Sami Kerola, CloudFlare. +# BSD licensed. +# Check whether --enable-systemd was given. +if test "${enable_systemd+set}" = set; then : + enableval=$enable_systemd; +else + enable_systemd=no +fi + +have_systemd=no +if test "x$enable_systemd" != xno; then : + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5 +$as_echo_n "checking for SYSTEMD... " >&6; } + +if test -n "$SYSTEMD_CFLAGS"; then + pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$SYSTEMD_LIBS"; then + pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1` + else + SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$SYSTEMD_PKG_ERRORS" >&5 + + have_systemd=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_systemd=no +else + SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS + SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_systemd=yes +fi + if test "x$have_systemd" != "xyes"; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5 +$as_echo_n "checking for SYSTEMD_DAEMON... " >&6; } + +if test -n "$SYSTEMD_DAEMON_CFLAGS"; then + pkg_cv_SYSTEMD_DAEMON_CFLAGS="$SYSTEMD_DAEMON_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SYSTEMD_DAEMON_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$SYSTEMD_DAEMON_LIBS"; then + pkg_cv_SYSTEMD_DAEMON_LIBS="$SYSTEMD_DAEMON_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SYSTEMD_DAEMON_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + else + SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5 + + have_systemd_daemon=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_systemd_daemon=no +else + SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS + SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_systemd_daemon=yes +fi + if test "x$have_systemd_daemon" = "xyes"; then : + have_systemd=yes +fi + +fi + case $enable_systemd:$have_systemd in #( + yes:no) : + as_fn_error $? "systemd enabled but libsystemd not found" "$LINENO" 5 ;; #( + *:yes) : + +$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h + + LIBS="$LIBS $SYSTEMD_LIBS" + + ;; #( + *) : + ;; +esac + + +fi + if test "x$have_systemd" = xyes; then + USE_SYSTEMD_TRUE= + USE_SYSTEMD_FALSE='#' +else + USE_SYSTEMD_TRUE='#' + USE_SYSTEMD_FALSE= +fi + + +# Include systemd.m4 - end + # set memory allocation checking if requested # Check whether --enable-alloc-checks was given. if test "${enable_alloc_checks+set}" = set; then : @@ -15822,6 +16384,10 @@ $as_echo "#define UNBOUND_ALLOC_STATS 1" >>confdefs.h + SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo" + + ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo" + else if test x_$enable_alloc_lite = x_yes; then @@ -16389,7 +16955,9 @@ $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h - LIBS="$PTHREAD_LIBS $LIBS" + if test -n "$PTHREAD_LIBS"; then + LIBS="$PTHREAD_LIBS $LIBS" + fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC" ub_have_pthreads=yes @@ -16583,6 +17151,26 @@ fi # end of non-mingw check of thread libraries +# Check for SYSLOG_FACILITY + +# Check whether --with-syslog-facility was given. +if test "${with_syslog_facility+set}" = set; then : + withval=$with_syslog_facility; UNBOUND_SYSLOG_FACILITY="$withval" +fi + +case "${UNBOUND_SYSLOG_FACILITY}" in + + LOCAL[0-7]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;; + + *) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;; + +esac + +cat >>confdefs.h <<_ACEOF +#define UB_SYSLOG_FACILITY ${UNBOUND_SYSLOG_FACILITY} +_ACEOF + + # Check for PyUnbound # Check whether --with-pyunbound was given. @@ -16682,8 +17270,7 @@ # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5 $as_echo_n "checking for the distutils Python package... " >&6; } - ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` - if test -z "$ac_distutils_result"; then + if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -16820,13 +17407,38 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h - LIBS="$PYTHON_LDFLAGS $LIBS" - CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + if test -n "$LIBS"; then + LIBS="$PYTHON_LDFLAGS $LIBS" + else + LIBS="$PYTHON_LDFLAGS" + fi + if test -n "$CPPFLAGS"; then + CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + else + CPPFLAGS="$PYTHON_CPPFLAGS" + fi ub_have_python=yes + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5 + ($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}" +else + PC_PY_DEPENDENCY="python" +fi + # Check for SWIG ub_have_swig=no + # Check whether --enable-swig-version-check was given. +if test "${enable_swig_version_check+set}" = set; then : + enableval=$enable_swig_version_check; +fi + if test "$enable_swig_version_check" = "yes"; then + # Extract the first word of "swig", so it can be a program name with args. set dummy swig; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -16871,6 +17483,123 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5 $as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;} SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false' + elif test -n "2.0.1" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5 +$as_echo_n "checking for SWIG version... " >&6; } + swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5 +$as_echo "$swig_version" >&6; } + if test -n "$swig_version" ; then + # Calculate the required version number components + required=2.0.1 + required_major=`echo $required | sed 's/[^0-9].*//'` + if test -z "$required_major" ; then + required_major=0 + fi + required=`echo $required | sed 's/[0-9]*[^0-9]//'` + required_minor=`echo $required | sed 's/[^0-9].*//'` + if test -z "$required_minor" ; then + required_minor=0 + fi + required=`echo $required | sed 's/[0-9]*[^0-9]//'` + required_patch=`echo $required | sed 's/[^0-9].*//'` + if test -z "$required_patch" ; then + required_patch=0 + fi + # Calculate the available version number components + available=$swig_version + available_major=`echo $available | sed 's/[^0-9].*//'` + if test -z "$available_major" ; then + available_major=0 + fi + available=`echo $available | sed 's/[0-9]*[^0-9]//'` + available_minor=`echo $available | sed 's/[^0-9].*//'` + if test -z "$available_minor" ; then + available_minor=0 + fi + available=`echo $available | sed 's/[0-9]*[^0-9]//'` + available_patch=`echo $available | sed 's/[^0-9].*//'` + if test -z "$available_patch" ; then + available_patch=0 + fi + badversion=0 + if test $available_major -lt $required_major ; then + badversion=1 + fi + if test $available_major -eq $required_major \ + -a $available_minor -lt $required_minor ; then + badversion=1 + fi + if test $available_major -eq $required_major \ + -a $available_minor -eq $required_minor \ + -a $available_patch -lt $required_patch ; then + badversion=1 + fi + if test $badversion -eq 1 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 2.0.1 is required. You have $swig_version. You should look at http://www.swig.org" >&5 +$as_echo "$as_me: WARNING: SWIG version >= 2.0.1 is required. You have $swig_version. You should look at http://www.swig.org" >&2;} + SWIG='echo "Error: SWIG version >= 2.0.1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: SWIG executable is '$SWIG'" >&5 +$as_echo "$as_me: SWIG executable is '$SWIG'" >&6;} + SWIG_LIB=`$SWIG -swiglib` + { $as_echo "$as_me:${as_lineno-$LINENO}: SWIG library directory is '$SWIG_LIB'" >&5 +$as_echo "$as_me: SWIG library directory is '$SWIG_LIB'" >&6;} + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5 +$as_echo "$as_me: WARNING: cannot determine SWIG version" >&2;} + SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false' + fi + fi + + + else + + # Extract the first word of "swig", so it can be a program name with args. +set dummy swig; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SWIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SWIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_SWIG="$SWIG" # 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 + test -z "$as_dir" && as_dir=. + 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_SWIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$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 +SWIG=$ac_cv_path_SWIG +if test -n "$SWIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5 +$as_echo "$SWIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test -z "$SWIG" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5 +$as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;} + SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false' elif test -n "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5 $as_echo_n "checking for SWIG version... " >&6; } @@ -16910,9 +17639,20 @@ if test -z "$available_patch" ; then available_patch=0 fi - if test $available_major -ne $required_major \ - -o $available_minor -ne $required_minor \ - -o $available_patch -lt $required_patch ; then + badversion=0 + if test $available_major -lt $required_major ; then + badversion=1 + fi + if test $available_major -eq $required_major \ + -a $available_minor -lt $required_minor ; then + badversion=1 + fi + if test $available_major -eq $required_major \ + -a $available_minor -eq $required_minor \ + -a $available_patch -lt $required_patch ; then + badversion=1 + fi + if test $badversion -eq 1 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&5 $as_echo "$as_me: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&2;} SWIG='echo "Error: SWIG version >= is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' @@ -16931,6 +17671,7 @@ fi + fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking SWIG" >&5 $as_echo_n "checking SWIG... " >&6; } if test ! -x "$SWIG"; then @@ -17023,8 +17764,10 @@ fi LIBS="$LIBS -lnss3 -lnspr4" SSLLIB="" + PC_CRYPTO_DEPENDENCY="nss nspr" + fi @@ -17066,8 +17809,10 @@ fi LIBS="$LIBS -lhogweed -lnettle -lgmp" SSLLIB="" + PC_CRYPTO_DEPENDENCY="hogweed nettle" + fi @@ -17163,8 +17908,8 @@ # check if -lwsock32 or -lgdi32 are needed. BAKLIBS="$LIBS" BAKSSLLIBS="$LIBSSL_LIBS" - LIBS="$LIBS -lgdi32" - LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32" + LIBS="$LIBS -lgdi32 -lws2_32" + LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -lgdi32" >&5 $as_echo_n "checking if -lcrypto needs -lgdi32... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -17416,6 +18161,9 @@ conftest$ac_exeext conftest.$ac_ext SSLLIB="-lssl" +PC_CRYPTO_DEPENDENCY="libcrypto libssl" + + # check if -lcrypt32 is needed because CAPIENG needs that. (on windows) BAKLIBS="$LIBS" LIBS="-lssl $LIBS" @@ -17506,17 +18254,7 @@ cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ARC4RANDOM_UNIFORM $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "reallocarray" "ac_cv_have_decl_reallocarray" "$ac_includes_default" -if test "x$ac_cv_have_decl_reallocarray" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_REALLOCARRAY $ac_have_decl -_ACEOF - else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -17535,7 +18273,7 @@ done -for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup +for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -17551,12 +18289,13 @@ # these check_funcs need -lssl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" -for ac_func in OPENSSL_init_ssl +for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites do : - ac_fn_c_check_func "$LINENO" "OPENSSL_init_ssl" "ac_cv_func_OPENSSL_init_ssl" -if test "x$ac_cv_func_OPENSSL_init_ssl" = xyes; then : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_INIT_SSL 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi @@ -17655,10 +18394,173 @@ #define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO $ac_have_decl _ACEOF + +if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then +# check function return type. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the return type of HMAC_Init_ex" >&5 +$as_echo_n "checking the return type of HMAC_Init_ex... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif + +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif +#include +#include + +int +main () +{ + + HMAC_CTX* hmac_ctx = NULL; + void* hmac_key = NULL; + const EVP_MD* digest = NULL; + int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL); + (void)x; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5 +$as_echo "int" >&6; } + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5 +$as_echo "void" >&6; } + +$as_echo "#define HMAC_INIT_EX_RETURNS_VOID 1" >>confdefs.h + + fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +fi +# libbsd + +# Check whether --with-libbsd was given. +if test "${with_libbsd+set}" = set; then : + withval=$with_libbsd; + for ac_header in bsd/string.h bsd/stdlib.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then + for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do + as_ac_Search=`$as_echo "ac_cv_search_$func" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing $func" >&5 +$as_echo_n "checking for library containing $func... " >&6; } +if eval \${$as_ac_Search+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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. */ +#ifdef __cplusplus +extern "C" +#endif +char $func (); +int +main () +{ +return $func (); + ; + return 0; +} +_ACEOF +for ac_lib in '' bsd; 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 : + eval "$as_ac_Search=\$ac_res" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if eval \${$as_ac_Search+:} false; then : + break +fi +done +if eval \${$as_ac_Search+:} false; then : + +else + eval "$as_ac_Search=no" +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +eval ac_res=\$$as_ac_Search + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +eval ac_res=\$$as_ac_Search +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + +$as_echo "#define HAVE_LIBBSD 1" >>confdefs.h + + PC_LIBBSD_DEPENDENCY=libbsd + + +fi + + done + fi + +fi + + +# Check whether --enable-sha1 was given. +if test "${enable_sha1+set}" = set; then : + enableval=$enable_sha1; +fi + +case "$enable_sha1" in + no) + ;; + yes|*) + +$as_echo "#define USE_SHA1 1" >>confdefs.h + + ;; +esac + + # Check whether --enable-sha2 was given. if test "${enable_sha2+set}" = set; then : enableval=$enable_sha2; @@ -17674,6 +18576,25 @@ ;; esac +# Check whether --enable-subnet was given. +if test "${enable_subnet+set}" = set; then : + enableval=$enable_subnet; +fi + +case "$enable_subnet" in + yes) + +$as_echo "#define CLIENT_SUBNET 1" >>confdefs.h + + SUBNET_OBJ="edns-subnet.lo subnetmod.lo addrtree.lo subnet-whitelist.lo" + + SUBNET_HEADER='$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/addrtree.h' + + ;; + no|*) + ;; +esac + # check wether gost also works # Check whether --enable-gost was given. @@ -17925,15 +18846,36 @@ fi use_dsa="no" -case "$enable_ecdsa" in - no) - ;; - *) +case "$enable_dsa" in + yes) # detect if DSA is supported, and turn it off if not. - ac_fn_c_check_func "$LINENO" "EVP_dss1" "ac_cv_func_EVP_dss1" -if test "x$ac_cv_func_EVP_dss1" = xyes; then : + if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then + ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new" +if test "x$ac_cv_func_DSA_SIG_new" = xyes; then : + as_ac_Type=`$as_echo "ac_cv_type_DSA_SIG*" | $as_tr_sh` +ac_fn_c_check_type "$LINENO" "DSA_SIG*" "$as_ac_Type" " +$ac_includes_default +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif + +" +if eval test \"x\$"$as_ac_Type"\" = x"yes"; then : + + cat >>confdefs.h <<_ACEOF #define USE_DSA 1 _ACEOF @@ -17944,10 +18886,129 @@ fi fi + +else + if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5 + fi +fi + + else + +cat >>confdefs.h <<_ACEOF +#define USE_DSA 1 +_ACEOF + + fi ;; + *) + # disable dsa by default, RFC 8624 section 3.1, validators MUST NOT + # support DSA for DNSSEC Validation. + ;; esac +# Check whether --enable-ed25519 was given. +if test "${enable_ed25519+set}" = set; then : + enableval=$enable_ed25519; +fi +use_ed25519="no" +case "$enable_ed25519" in + no) + ;; + *) + if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then + ac_fn_c_check_decl "$LINENO" "NID_ED25519" "ac_cv_have_decl_NID_ED25519" "$ac_includes_default +#include + +" +if test "x$ac_cv_have_decl_NID_ED25519" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_NID_ED25519 $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : + + use_ed25519="yes" + +else + if test "x$enable_ed25519" = "xyes"; then as_fn_error $? "OpenSSL does not support ED25519 and you used --enable-ed25519." "$LINENO" 5 + fi +fi + + fi + if test $USE_NETTLE = "yes"; then + for ac_header in nettle/eddsa.h +do : + ac_fn_c_check_header_compile "$LINENO" "nettle/eddsa.h" "ac_cv_header_nettle_eddsa_h" "$ac_includes_default +" +if test "x$ac_cv_header_nettle_eddsa_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETTLE_EDDSA_H 1 +_ACEOF + use_ed25519="yes" +fi + +done + + fi + if test $use_ed25519 = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define USE_ED25519 1 +_ACEOF + + fi + ;; +esac + +# Check whether --enable-ed448 was given. +if test "${enable_ed448+set}" = set; then : + enableval=$enable_ed448; +fi + +use_ed448="no" +case "$enable_ed448" in + no) + ;; + *) + if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then + ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default +#include + +" +if test "x$ac_cv_have_decl_NID_ED448" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_NID_ED448 $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : + + use_ed448="yes" + +else + if test "x$enable_ed448" = "xyes"; then as_fn_error $? "OpenSSL does not support ED448 and you used --enable-ed448." "$LINENO" 5 + fi +fi + + fi + if test $use_ed448 = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define USE_ED448 1 +_ACEOF + + fi + ;; +esac + # Check whether --enable-event-api was given. if test "${enable_event_api+set}" = set; then : enableval=$enable_event_api; @@ -18378,6 +19439,37 @@ fi done # only in libev. (tested on 4.00) + for ac_func in event_assign +do : + ac_fn_c_check_func "$LINENO" "event_assign" "ac_cv_func_event_assign" +if test "x$ac_cv_func_event_assign" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EVENT_ASSIGN 1 +_ACEOF + +fi +done + # in libevent, for thread-safety + ac_fn_c_check_decl "$LINENO" "evsignal_assign" "ac_cv_have_decl_evsignal_assign" "$ac_includes_default +#ifdef HAVE_EVENT_H +# include +#else +# include \"event2/event.h\" +#endif + +" +if test "x$ac_cv_have_decl_evsignal_assign" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_EVSIGNAL_ASSIGN $ac_have_decl +_ACEOF + + PC_LIBEVENT_DEPENDENCY="libevent" + if test -n "$BAK_LDFLAGS_SET"; then LDFLAGS="$BAK_LDFLAGS" fi @@ -18442,8 +19534,72 @@ _ACEOF -# set static linking if requested +# hiredis (redis C client for cachedb) +# Check whether --with-libhiredis was given. +if test "${with_libhiredis+set}" = set; then : + withval=$with_libhiredis; +else + withval="no" +fi + +found_libhiredis="no" +if test x_$withval = x_yes -o x_$withval != x_no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libhiredis" >&5 +$as_echo_n "checking for libhiredis... " >&6; } + if test x_$withval = x_ -o x_$withval = x_yes; then + withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" + fi + for dir in $withval ; do + if test -f "$dir/include/hiredis/hiredis.h"; then + found_libhiredis="yes" + if test "$dir" != "/usr"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5 +$as_echo "found in $dir" >&6; } + +$as_echo "#define USE_REDIS 1" >>confdefs.h + + LIBS="$LIBS -lhiredis" + break; + fi + done + if test x_$found_libhiredis != x_yes; then + as_fn_error $? "Could not find libhiredis, hiredis.h" "$LINENO" 5 + fi + for ac_header in hiredis/hiredis.h +do : + ac_fn_c_check_header_compile "$LINENO" "hiredis/hiredis.h" "ac_cv_header_hiredis_hiredis_h" "$ac_includes_default +" +if test "x$ac_cv_header_hiredis_hiredis_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_HIREDIS_HIREDIS_H 1 +_ACEOF + +fi + +done + + ac_fn_c_check_decl "$LINENO" "redisConnect" "ac_cv_have_decl_redisConnect" "$ac_includes_default + #include + +" +if test "x$ac_cv_have_decl_redisConnect" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_REDISCONNECT $ac_have_decl +_ACEOF + +fi + +# set static linking for uninstalled libraries if requested + staticexe="" # Check whether --enable-static-exe was given. if test "${enable_static_exe+set}" = set; then : @@ -18455,10 +19611,34 @@ if test "$on_mingw" = yes; then staticexe="-all-static" # for static compile, include gdi32 and zlib here. - LIBS="$LIBS -lgdi32 -lz" + if echo $LIBS | grep 'lgdi32' >/dev/null; then + : + else + LIBS="$LIBS -lgdi32" + fi + LIBS="$LIBS -lz" fi fi +# set full static linking if requested +# Check whether --enable-fully-static was given. +if test "${enable_fully_static+set}" = set; then : + enableval=$enable_fully_static; +fi + +if test x_$enable_fully_static = x_yes; then + staticexe="-all-static" + if test "$on_mingw" = yes; then + # for static compile, include gdi32 and zlib here. + if echo $LIBS | grep 'lgdi32' >/dev/null; then + : + else + LIBS="$LIBS -lgdi32" + fi + LIBS="$LIBS -lz" + fi +fi + # set lock checking if requested # Check whether --enable-lock_checks was given. if test "${enable_lock_checks+set}" = set; then : @@ -18502,7 +19682,11 @@ $as_echo "#define USE_WINSOCK 1" >>confdefs.h USE_WINSOCK="1" - LIBS="$LIBS -lws2_32" + if echo $LIBS | grep 'lws2_32' >/dev/null; then + : + else + LIBS="$LIBS -lws2_32" + fi fi else @@ -18666,7 +19850,7 @@ WINDRES="$ac_cv_prog_WINDRES" fi - LIBS="$LIBS -liphlpapi" + LIBS="$LIBS -liphlpapi -lcrypt32" WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe" WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c" @@ -18844,6 +20028,75 @@ fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htobe64" >&5 +$as_echo_n "checking for htobe64... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +# include +#endif + +int +main () +{ +unsigned long long x = htobe64(0); printf("%u", (unsigned)x); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_HTOBE64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for be64toh" >&5 +$as_echo_n "checking for be64toh... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +# include +#endif + +int +main () +{ +unsigned long long x = be64toh(0); printf("%u", (unsigned)x); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_BE64TOH 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setusercontext" >&5 $as_echo_n "checking for library containing setusercontext... " >&6; } if ${ac_cv_search_setusercontext+:} false; then : @@ -18900,7 +20153,7 @@ fi -for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync +for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -18959,39 +20212,77 @@ done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sbrk" >&5 -$as_echo_n "checking for sbrk... " >&6; } -# catch the warning of deprecated sbrk -old_cflags="$CFLAGS" -CFLAGS="$CFLAGS -Werror" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +# check if setreuid en setregid fail, on MacOSX10.4(darwin8). +if echo $target_os | grep darwin8 > /dev/null; then + +$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h + +fi +ac_fn_c_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" " $ac_includes_default +#ifdef HAVE_NETINET_IN_H +#include +#endif -int main(void) { void* cur = sbrk(0); printf("%u\n", (unsigned)(size_t)((char*)cur - (char*)sbrk(0))); return 0; } +#ifdef HAVE_NETINET_TCP_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +" +if test "x$ac_cv_have_decl_inet_pton" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_INET_PTON $ac_have_decl _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +ac_fn_c_check_decl "$LINENO" "inet_ntop" "ac_cv_have_decl_inet_ntop" " +$ac_includes_default +#ifdef HAVE_NETINET_IN_H +#include +#endif - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +#ifdef HAVE_NETINET_TCP_H +#include +#endif -$as_echo "#define HAVE_SBRK 1" >>confdefs.h +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_WINSOCK2_H +#include +#endif +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +" +if test "x$ac_cv_have_decl_inet_ntop" = xyes; then : + ac_have_decl=1 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + ac_have_decl=0 fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -CFLAGS="$old_cflags" -# check if setreuid en setregid fail, on MacOSX10.4(darwin8). -if echo $build_os | grep darwin8 > /dev/null; then +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_INET_NTOP $ac_have_decl +_ACEOF -$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h - -fi ac_fn_c_check_func "$LINENO" "inet_aton" "ac_cv_func_inet_aton" if test "x$ac_cv_func_inet_aton" = xyes; then : $as_echo "#define HAVE_INET_ATON 1" >>confdefs.h @@ -19160,21 +20451,70 @@ fi +ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero" +if test "x$ac_cv_func_explicit_bzero" = xyes; then : + $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" explicit_bzero.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext" + ;; +esac + +fi + + LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS" -ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray" -if test "x$ac_cv_func_reallocarray" = xyes; then : - $as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for reallocarray" >&5 +$as_echo_n "checking for reallocarray... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#ifndef _OPENBSD_SOURCE +#define _OPENBSD_SOURCE 1 +#endif +#include +int main(void) { + void* p = reallocarray(NULL, 10, 100); + free(p); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h + + else - case " $LIBOBJS " in + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + case " $LIBOBJS " in *" reallocarray.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS reallocarray.$ac_objext" ;; esac + fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +ac_fn_c_check_decl "$LINENO" "reallocarray" "ac_cv_have_decl_reallocarray" "$ac_includes_default" +if test "x$ac_cv_have_decl_reallocarray" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_REALLOCARRAY $ac_have_decl +_ACEOF if test "$USE_NSS" = "no"; then ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random" @@ -19207,12 +20547,6 @@ if test "$ac_cv_func_arc4random" = "no"; then case " $LIBOBJS " in - *" explicit_bzero.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext" - ;; -esac - - case " $LIBOBJS " in *" arc4_lock.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS arc4_lock.$ac_objext" ;; @@ -19236,8 +20570,8 @@ esac else - case `uname` in - Darwin) + case "$host" in + Darwin|*darwin*) case " $LIBOBJS " in *" getentropy_osx.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getentropy_osx.$ac_objext" @@ -19245,7 +20579,7 @@ esac ;; - SunOS) + *solaris*|*sunos*|SunOS) case " $LIBOBJS " in *" getentropy_solaris.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getentropy_solaris.$ac_objext" @@ -19349,8 +20683,16 @@ fi ;; - Linux|*) + *freebsd*|*FreeBSD) case " $LIBOBJS " in + *" getentropy_freebsd.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS getentropy_freebsd.$ac_objext" + ;; +esac + + ;; + *linux*|Linux|*) + case " $LIBOBJS " in *" getentropy_linux.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getentropy_linux.$ac_objext" ;; @@ -19781,6 +21123,234 @@ fi +# check for dnscrypt if requested + + # Check whether --enable-dnscrypt was given. +if test "${enable_dnscrypt+set}" = set; then : + enableval=$enable_dnscrypt; opt_dnscrypt=$enableval +else + opt_dnscrypt=no +fi + + + if test "x$opt_dnscrypt" != "xno"; then + +# Check whether --with-libsodium was given. +if test "${with_libsodium+set}" = set; then : + withval=$with_libsodium; + CFLAGS="$CFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sodium_init" >&5 +$as_echo_n "checking for library containing sodium_init... " >&6; } +if ${ac_cv_search_sodium_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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. */ +#ifdef __cplusplus +extern "C" +#endif +char sodium_init (); +int +main () +{ +return sodium_init (); + ; + return 0; +} +_ACEOF +for ac_lib in '' sodium; 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_sodium_init=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_sodium_init+:} false; then : + break +fi +done +if ${ac_cv_search_sodium_init+:} false; then : + +else + ac_cv_search_sodium_init=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sodium_init" >&5 +$as_echo "$ac_cv_search_sodium_init" >&6; } +ac_res=$ac_cv_search_sodium_init +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "The sodium library was not found. Please install sodium!" "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypto_box_curve25519xchacha20poly1305_beforenm" >&5 +$as_echo_n "checking for library containing crypto_box_curve25519xchacha20poly1305_beforenm... " >&6; } +if ${ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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. */ +#ifdef __cplusplus +extern "C" +#endif +char crypto_box_curve25519xchacha20poly1305_beforenm (); +int +main () +{ +return crypto_box_curve25519xchacha20poly1305_beforenm (); + ; + return 0; +} +_ACEOF +for ac_lib in '' sodium; 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_crypto_box_curve25519xchacha20poly1305_beforenm=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm+:} false; then : + break +fi +done +if ${ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm+:} false; then : + +else + ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm" >&5 +$as_echo "$ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm" >&6; } +ac_res=$ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + ENABLE_DNSCRYPT_XCHACHA20=1 + + +$as_echo "#define USE_DNSCRYPT_XCHACHA20 1" >>confdefs.h + + +else + + ENABLE_DNSCRYPT_XCHACHA20=0 + + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sodium_set_misuse_handler" >&5 +$as_echo_n "checking for library containing sodium_set_misuse_handler... " >&6; } +if ${ac_cv_search_sodium_set_misuse_handler+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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. */ +#ifdef __cplusplus +extern "C" +#endif +char sodium_set_misuse_handler (); +int +main () +{ +return sodium_set_misuse_handler (); + ; + return 0; +} +_ACEOF +for ac_lib in '' sodium; 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_sodium_set_misuse_handler=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_sodium_set_misuse_handler+:} false; then : + break +fi +done +if ${ac_cv_search_sodium_set_misuse_handler+:} false; then : + +else + ac_cv_search_sodium_set_misuse_handler=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sodium_set_misuse_handler" >&5 +$as_echo "$ac_cv_search_sodium_set_misuse_handler" >&6; } +ac_res=$ac_cv_search_sodium_set_misuse_handler +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + +$as_echo "#define SODIUM_MISUSE_HANDLER 1" >>confdefs.h + + +fi + + + +$as_echo "#define USE_DNSCRYPT 1" >>confdefs.h + + ENABLE_DNSCRYPT=1 + + + DNSCRYPT_SRC="dnscrypt/dnscrypt.c" + + DNSCRYPT_OBJ="dnscrypt.lo" + + + else + ENABLE_DNSCRYPT_XCHACHA20=0 + + + ENABLE_DNSCRYPT=0 + + + + fi + + # check for cachedb if requested # Check whether --enable-cachedb was given. if test "${enable_cachedb+set}" = set; then : @@ -19787,6 +21357,8 @@ enableval=$enable_cachedb; fi +# turn on cachedb when hiredis support is enabled. +if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi case "$enable_cachedb" in yes) @@ -19798,6 +21370,80 @@ ;; esac +# check for ipsecmod if requested +# Check whether --enable-ipsecmod was given. +if test "${enable_ipsecmod+set}" = set; then : + enableval=$enable_ipsecmod; +fi + +case "$enable_ipsecmod" in + yes) + +$as_echo "#define USE_IPSECMOD 1" >>confdefs.h + + IPSECMOD_OBJ="ipsecmod.lo ipsecmod-whitelist.lo" + + IPSECMOD_HEADER='$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h' + + ;; + no|*) + # nothing + ;; +esac + +# check for ipset if requested +# Check whether --enable-ipset was given. +if test "${enable_ipset+set}" = set; then : + enableval=$enable_ipset; +fi + +case "$enable_ipset" in + yes) + +$as_echo "#define USE_IPSET 1" >>confdefs.h + + IPSET_SRC="ipset/ipset.c" + + IPSET_OBJ="ipset.lo" + + + # mnl + +# Check whether --with-libmnl was given. +if test "${with_libmnl+set}" = set; then : + withval=$with_libmnl; +else + withval="yes" +fi + + found_libmnl="no" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5 +$as_echo_n "checking for libmnl... " >&6; } + if test x_$withval = x_ -o x_$withval = x_yes; then + withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" + fi + for dir in $withval ; do + if test -f "$dir/include/libmnl/libmnl.h"; then + found_libmnl="yes" + if test "$dir" != "/usr"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5 +$as_echo "found in $dir" >&6; } + LIBS="$LIBS -lmnl" + break; + fi + done + if test x_$found_libmnl != x_yes; then + as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5 + fi + ;; + no|*) + # nothing + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5 $as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; } # on openBSD, the implicit rule make $< work. @@ -19850,10 +21496,19 @@ fi +if test $ALLTARGET = "alltargets"; then + if test $USE_NSS = "yes"; then + as_fn_error $? "--with-nss can only be used in combination with --with-libunbound-only." "$LINENO" 5 + fi + if test $USE_NETTLE = "yes"; then + as_fn_error $? "--with-nettle can only be used in combination with --with-libunbound-only." "$LINENO" 5 + fi +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: Stripping extension flags..." >&5 $as_echo "$as_me: Stripping extension flags..." >&6;} @@ -19929,7 +21584,12 @@ fi -LDFLAGS="$LATE_LDFLAGS $LDFLAGS" +if test -n "$LATE_LDFLAGS"; then + LDFLAGS="$LATE_LDFLAGS $LDFLAGS" +fi +# remove start spaces +LDFLAGS=`echo "$LDFLAGS"|sed -e 's/^ *//'` +LIBS=`echo "$LIBS"|sed -e 's/^ *//'` cat >>confdefs.h <<_ACEOF @@ -19939,12 +21599,12 @@ -version=1.5.10 +version=1.10.1 date=`date +'%b %e, %Y'` -ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc" +ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service" ac_config_headers="$ac_config_headers config.h" @@ -20057,6 +21717,10 @@ LTLIBOBJS=$ac_ltlibobjs +if test -z "${USE_SYSTEMD_TRUE}" && test -z "${USE_SYSTEMD_FALSE}"; then + as_fn_error $? "conditional \"USE_SYSTEMD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -20454,7 +22118,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by unbound $as_me 1.5.10, which was +This file was extended by unbound $as_me 1.10.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20514,13 +22178,13 @@ Configuration commands: $config_commands -Report bugs to ." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -unbound config.status 1.5.10 +unbound config.status 1.10.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -20942,7 +22606,11 @@ "doc/unbound-host.1") CONFIG_FILES="$CONFIG_FILES doc/unbound-host.1" ;; "smallapp/unbound-control-setup.sh") CONFIG_FILES="$CONFIG_FILES smallapp/unbound-control-setup.sh" ;; "dnstap/dnstap_config.h") CONFIG_FILES="$CONFIG_FILES dnstap/dnstap_config.h" ;; + "dnscrypt/dnscrypt_config.h") CONFIG_FILES="$CONFIG_FILES dnscrypt/dnscrypt_config.h" ;; "contrib/libunbound.pc") CONFIG_FILES="$CONFIG_FILES contrib/libunbound.pc" ;; + "contrib/unbound.socket") CONFIG_FILES="$CONFIG_FILES contrib/unbound.socket" ;; + "contrib/unbound.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound.service" ;; + "contrib/unbound_portable.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound_portable.service" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; --- contrib/unbound/configure.ac.orig +++ contrib/unbound/configure.ac @@ -6,19 +6,20 @@ sinclude(acx_python.m4) sinclude(ac_pkg_swig.m4) sinclude(dnstap/dnstap.m4) +sinclude(dnscrypt/dnscrypt.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) -m4_define([VERSION_MINOR],[5]) -m4_define([VERSION_MICRO],[10]) -AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound) +m4_define([VERSION_MINOR],[10]) +m4_define([VERSION_MICRO],[1]) +AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) -LIBUNBOUND_CURRENT=6 -LIBUNBOUND_REVISION=2 -LIBUNBOUND_AGE=4 +LIBUNBOUND_CURRENT=9 +LIBUNBOUND_REVISION=8 +LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 # 1.0.2 had 0:14:0 @@ -67,6 +68,32 @@ # 1.5.8 had 6:0:4 # adds ub_ctx_set_stub # 1.5.9 had 6:1:4 # 1.5.10 had 6:2:4 +# 1.6.0 had 6:3:4 +# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type +# 1.6.2 had 7:1:5 +# 1.6.3 had 7:2:5 +# 1.6.4 had 7:3:5 +# 1.6.5 had 7:4:5 +# 1.6.6 had 7:5:5 +# 1.6.7 had 7:6:5 +# 1.6.8 had 7:7:5 +# 1.7.0 had 7:8:5 +# 1.7.1 had 7:9:5 +# 1.7.2 had 7:10:5 +# 1.7.3 had 7:11:5 +# 1.8.0 had 8:0:0 # changes the event callback function signature +# 1.8.1 had 8:1:0 +# 1.8.2 had 8:2:0 +# 1.8.3 had 8:3:0 +# 1.9.0 had 9:0:1 # add ub_ctx_set_tls +# 1.9.1 had 9:1:1 +# 1.9.2 had 9:2:1 +# 1.9.3 had 9:3:1 +# 1.9.4 had 9:4:1 +# 1.9.5 had 9:5:1 +# 1.9.6 had 9:6:1 +# 1.10.0 had 9:7:1 +# 1.10.1 had 9:8:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -82,7 +109,7 @@ # Current and Age. Set Revision to 0, since this is the first # implementation of the new API. # -# Otherwise, we're changing the binary API and breaking bakward +# Otherwise, we're changing the binary API and breaking backward # compatibility with old binaries. Increment Current. Set Age to 0, # since we're backward compatible with no previous APIs. Set Revision # to 0 too. @@ -90,6 +117,10 @@ AC_SUBST(LIBUNBOUND_REVISION) AC_SUBST(LIBUNBOUND_AGE) + +cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`" +AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure]) + CFLAGS="$CFLAGS" AC_AIX if test "$ac_cv_header_minix_config_h" = "yes"; then @@ -104,6 +135,11 @@ prefix="/usr/local" ;; esac +case "$exec_prefix" in + NONE) + exec_prefix="$prefix" + ;; +esac # are we on MinGW? if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes" @@ -115,10 +151,16 @@ # # Determine configuration file # the eval is to evaluate shell expansion twice +UNBOUND_SBIN_DIR=`eval echo "${sbindir}"` +AC_SUBST(UNBOUND_SBIN_DIR) +UNBOUND_SYSCONF_DIR=`eval echo "${sysconfdir}"` +AC_SUBST(UNBOUND_SYSCONF_DIR) +UNBOUND_LOCALSTATE_DIR=`eval echo "${localstatedir}"` +AC_SUBST(UNBOUND_LOCALSTATE_DIR) if test $on_mingw = "no"; then ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"` else - ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf" + ub_conf_file="C:\\Program Files\\Unbound\\service.conf" fi AC_ARG_WITH([conf_file], AC_HELP_STRING([--with-conf-file=path], @@ -188,7 +230,7 @@ if test $on_mingw = no; then UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key" else - UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key" + UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key" fi ) AC_SUBST(UNBOUND_ROOTKEY_FILE) @@ -202,7 +244,7 @@ if test $on_mingw = no; then UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem" else - UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem" + UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem" fi ) AC_SUBST(UNBOUND_ROOTCERT_FILE) @@ -225,9 +267,11 @@ AC_C_CONST AC_LANG_C # allow user to override the -g -O2 flags. +default_cflags=no if test "x$CFLAGS" = "x" ; then ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="$CFLAGS -g"]) ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"]) +default_cflags=yes fi AC_PROG_CC ACX_DEPFLAG @@ -251,9 +295,14 @@ # nothing to do. ;; esac -ACX_CHECK_FLTO -ACX_CHECK_PIE -ACX_CHECK_RELRO_NOW +if test "$default_cflags" = "yes"; then + # only when CFLAGS was "" at the start, if the users wants to + # override we shouldn't add default cflags, because they wouldn't + # be able to turn off these options and set the CFLAGS wanted. + ACX_CHECK_FLTO + ACX_CHECK_PIE + ACX_CHECK_RELRO_NOW +fi AC_C_INLINE ACX_CHECK_FORMAT_ATTRIBUTE @@ -277,11 +326,36 @@ AC_MSG_RESULT($ac_cv_c_weak_attribute) if test $ac_cv_c_weak_attribute = yes; then AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute]) + AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol]) fi ])dnl End of CHECK_WEAK_ATTRIBUTE CHECK_WEAK_ATTRIBUTE +AC_DEFUN([CHECK_NORETURN_ATTRIBUTE], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute) +AC_CACHE_VAL(ac_cv_c_noreturn_attribute, +[ac_cv_c_noreturn_attribute=no +AC_TRY_COMPILE( +[ #include +__attribute__((noreturn)) void f(int x) { printf("%d", x); } +], [ + f(1); +], +[ac_cv_c_noreturn_attribute="yes"], +[ac_cv_c_noreturn_attribute="no"]) +]) + +AC_MSG_RESULT($ac_cv_c_noreturn_attribute) +if test $ac_cv_c_noreturn_attribute = yes; then + AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute]) + AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program]) +fi +])dnl End of CHECK_NORETURN_ATTRIBUTE + +CHECK_NORETURN_ATTRIBUTE + if test "$srcdir" != "."; then CPPFLAGS="$CPPFLAGS -I$srcdir" fi @@ -291,18 +365,39 @@ if echo %% | $LEX -t 2>&1 | grep yylex_destroy >/dev/null 2>&1; then AC_DEFINE(LEX_HAS_YYLEX_DESTROY, 1, [if lex has yylex_destroy]) AC_MSG_RESULT(yes) - else AC_MSG_RESULT(no); fi + else AC_MSG_RESULT(no); + LEX=":" + fi ]) +AC_DEFUN([ACX_YYLEX_OPTION], [ + AC_MSG_CHECKING([for lex %option]) + if cat <&1 | grep yy_delete_buffer >/dev/null 2>&1; then +%option nounput +%% +EOF + AC_MSG_RESULT(yes) + else AC_MSG_RESULT(no); + LEX=":" + fi +]) + AC_PROG_LEX +if test "$LEX" != "" -a "$LEX" != ":"; then ACX_YYLEX_DESTROY +fi +if test "$LEX" != "" -a "$LEX" != ":"; then +ACX_YYLEX_OPTION +fi AC_PROG_YACC AC_CHECK_PROG(doxygen, doxygen, doxygen) AC_CHECK_TOOL(STRIP, strip) ACX_LIBTOOL_C_ONLY +PKG_PROG_PKG_CONFIG + # Checks for header files. -AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT]) # check for types. # Using own tests for int64* because autoconf builtin only give 32bit. @@ -339,6 +434,7 @@ # endif #endif ]) +AC_CHECK_SIZEOF(size_t) # add option to disable the evil rpath ACX_ARG_RPATH @@ -383,6 +479,17 @@ ACX_MKDIR_ONE_ARG AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])]) +# check if we can use SO_REUSEPORT +if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then + AC_DEFINE(REUSEPORT_DEFAULT, 1, [if REUSEPORT is enabled by default]) +else + AC_DEFINE(REUSEPORT_DEFAULT, 0, [if REUSEPORT is enabled by default]) +fi + +# Include systemd.m4 - begin +sinclude(systemd.m4) +# Include systemd.m4 - end + # set memory allocation checking if requested AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks], [ enable to memory allocation statistics, for debug purposes ]), @@ -398,6 +505,10 @@ fi if test x_$enable_alloc_checks = x_yes; then AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use]) + SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo" + AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ) + ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo" + AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ) else if test x_$enable_alloc_lite = x_yes; then AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use]) @@ -438,7 +549,9 @@ if test x_$withval != x_no; then AX_PTHREAD([ AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]) - LIBS="$PTHREAD_LIBS $LIBS" + if test -n "$PTHREAD_LIBS"; then + LIBS="$PTHREAD_LIBS $LIBS" + fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC" ub_have_pthreads=yes @@ -499,6 +612,18 @@ fi # end of non-mingw check of thread libraries +# Check for SYSLOG_FACILITY +AC_ARG_WITH(syslog-facility, AC_HELP_STRING([--with-syslog-facility=LOCAL0 - LOCAL7], [ set SYSLOG_FACILITY, default DAEMON ]), + [ UNBOUND_SYSLOG_FACILITY="$withval" ], []) +case "${UNBOUND_SYSLOG_FACILITY}" in + + LOCAL[[0-7]]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;; + + *) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;; + +esac +AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON]) + # Check for PyUnbound AC_ARG_WITH(pyunbound, AC_HELP_STRING([--with-pyunbound], @@ -540,13 +665,30 @@ AC_SUBST(PY_MAJOR_VERSION) # Have Python AC_DEFINE(HAVE_PYTHON,1,[Define if you have Python libraries and header files.]) - LIBS="$PYTHON_LDFLAGS $LIBS" - CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + if test -n "$LIBS"; then + LIBS="$PYTHON_LDFLAGS $LIBS" + else + LIBS="$PYTHON_LDFLAGS" + fi + if test -n "$CPPFLAGS"; then + CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + else + CPPFLAGS="$PYTHON_CPPFLAGS" + fi ub_have_python=yes + PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"], + [PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"], + [PC_PY_DEPENDENCY="python"]) + AC_SUBST(PC_PY_DEPENDENCY) # Check for SWIG ub_have_swig=no - AC_PROG_SWIG + AC_ARG_ENABLE(swig-version-check, AC_HELP_STRING([--disable-swig-version-check], [Disable swig version check to build python modules with older swig even though that is unreliable])) + if test "$enable_swig_version_check" = "yes"; then + AC_PROG_SWIG(2.0.1) + else + AC_PROG_SWIG + fi AC_MSG_CHECKING(SWIG) if test ! -x "$SWIG"; then AC_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound]) @@ -620,6 +762,8 @@ fi LIBS="$LIBS -lnss3 -lnspr4" SSLLIB="" + PC_CRYPTO_DEPENDENCY="nss nspr" + AC_SUBST(PC_CRYPTO_DEPENDENCY) ] ) @@ -640,6 +784,8 @@ fi LIBS="$LIBS -lhogweed -lnettle -lgmp" SSLLIB="" + PC_CRYPTO_DEPENDENCY="hogweed nettle" + AC_SUBST(PC_CRYPTO_DEPENDENCY) ] ) @@ -649,6 +795,9 @@ ACX_LIB_SSL SSLLIB="-lssl" +PC_CRYPTO_DEPENDENCY="libcrypto libssl" +AC_SUBST(PC_CRYPTO_DEPENDENCY) + # check if -lcrypt32 is needed because CAPIENG needs that. (on windows) BAKLIBS="$LIBS" LIBS="-lssl $LIBS" @@ -668,17 +817,17 @@ AC_DEFINE([HAVE_LIBRESSL], [1], [Define if we have LibreSSL]) # libressl provides these compat functions, but they may also be # declared by the OS in libc. See if they have been declared. - AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform,reallocarray]) + AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform]) else AC_MSG_RESULT([no]) fi AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT]) -AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup]) +AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback]) # these check_funcs need -lssl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" -AC_CHECK_FUNCS([OPENSSL_init_ssl]) +AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites]) LIBS="$BAKLIBS" AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [ @@ -701,10 +850,69 @@ #include #include ]) + +if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then +# check function return type. +AC_MSG_CHECKING(the return type of HMAC_Init_ex) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif + +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif +#include +#include +], [ + HMAC_CTX* hmac_ctx = NULL; + void* hmac_key = NULL; + const EVP_MD* digest = NULL; + int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL); + (void)x; +])], [ + AC_MSG_RESULT(int) +], [ + AC_MSG_RESULT(void) + AC_DEFINE([HMAC_INIT_EX_RETURNS_VOID], 1, [If HMAC_Init_ex() returns void]) +]) fi + +fi AC_SUBST(SSLLIB) +# libbsd +AC_ARG_WITH([libbsd], AC_HELP_STRING([--with-libbsd], [Use portable libbsd functions]), [ + AC_CHECK_HEADERS([bsd/string.h bsd/stdlib.h],,, [AC_INCLUDES_DEFAULT]) + if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then + for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do + AC_SEARCH_LIBS([$func], [bsd], [ + AC_DEFINE(HAVE_LIBBSD, 1, [Use portable libbsd functions]) + PC_LIBBSD_DEPENDENCY=libbsd + AC_SUBST(PC_LIBBSD_DEPENDENCY) + ]) + done + fi +]) +AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support])) +case "$enable_sha1" in + no) + ;; + yes|*) + AC_DEFINE([USE_SHA1], [1], [Define this to enable SHA1 support.]) + ;; +esac + + AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support])) case "$enable_sha2" in no) @@ -714,6 +922,19 @@ ;; esac +AC_ARG_ENABLE(subnet, AC_HELP_STRING([--enable-subnet], [Enable client subnet])) +case "$enable_subnet" in + yes) + AC_DEFINE([CLIENT_SUBNET], [1], [Define this to enable client subnet option.]) + SUBNET_OBJ="edns-subnet.lo subnetmod.lo addrtree.lo subnet-whitelist.lo" + AC_SUBST(SUBNET_OBJ) + SUBNET_HEADER='$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/addrtree.h' + AC_SUBST(SUBNET_HEADER) + ;; + no|*) + ;; +esac + # check wether gost also works AC_DEFUN([AC_CHECK_GOST_WORKS], [AC_REQUIRE([AC_PROG_CC]) @@ -864,19 +1085,87 @@ AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support])) use_dsa="no" -case "$enable_ecdsa" in - no) - ;; - *) +case "$enable_dsa" in + yes) # detect if DSA is supported, and turn it off if not. - AC_CHECK_FUNC(EVP_dss1, [ + if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then + AC_CHECK_FUNC(DSA_SIG_new, [ + AC_CHECK_TYPE(DSA_SIG*, [ AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.]) ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.]) + fi ], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif + +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif + ]) + ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.]) fi ]) + else + AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.]) + fi ;; + *) + # disable dsa by default, RFC 8624 section 3.1, validators MUST NOT + # support DSA for DNSSEC Validation. + ;; esac +AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support])) +use_ed25519="no" +case "$enable_ed25519" in + no) + ;; + *) + if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then + AC_CHECK_DECLS([NID_ED25519], [ + use_ed25519="yes" + ], [ if test "x$enable_ed25519" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED25519 and you used --enable-ed25519.]) + fi ], [AC_INCLUDES_DEFAULT +#include + ]) + fi + if test $USE_NETTLE = "yes"; then + AC_CHECK_HEADERS([nettle/eddsa.h], use_ed25519="yes",, [AC_INCLUDES_DEFAULT]) + fi + if test $use_ed25519 = "yes"; then + AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.]) + fi + ;; +esac +AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support])) +use_ed448="no" +case "$enable_ed448" in + no) + ;; + *) + if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then + AC_CHECK_DECLS([NID_ED448], [ + use_ed448="yes" + ], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.]) + fi ], [AC_INCLUDES_DEFAULT +#include + ]) + fi + if test $use_ed448 = "yes"; then + AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.]) + fi + ;; +esac + AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h])) case "$enable_event_api" in yes) @@ -1000,6 +1289,16 @@ 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) + AC_CHECK_FUNCS([event_assign]) # in libevent, for thread-safety + AC_CHECK_DECLS([evsignal_assign], [], [], [AC_INCLUDES_DEFAULT +#ifdef HAVE_EVENT_H +# include +#else +# include "event2/event.h" +#endif + ]) + PC_LIBEVENT_DEPENDENCY="libevent" + AC_SUBST(PC_LIBEVENT_DEPENDENCY) if test -n "$BAK_LDFLAGS_SET"; then LDFLAGS="$BAK_LDFLAGS" fi @@ -1033,11 +1332,44 @@ #include ]) -# set static linking if requested +# hiredis (redis C client for cachedb) +AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path], + [specify explicit path for libhiredis.]), + [ ],[ withval="no" ]) +found_libhiredis="no" +if test x_$withval = x_yes -o x_$withval != x_no; then + AC_MSG_CHECKING(for libhiredis) + if test x_$withval = x_ -o x_$withval = x_yes; then + withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" + fi + for dir in $withval ; do + if test -f "$dir/include/hiredis/hiredis.h"; then + found_libhiredis="yes" + dnl assume /usr is in default path. + if test "$dir" != "/usr"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_MSG_RESULT(found in $dir) + AC_DEFINE([USE_REDIS], [1], [Define this to use hiredis client.]) + LIBS="$LIBS -lhiredis" + break; + fi + done + if test x_$found_libhiredis != x_yes; then + AC_ERROR([Could not find libhiredis, hiredis.h]) + fi + AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT]) + AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT + #include + ]) +fi + +# set static linking for uninstalled libraries if requested AC_SUBST(staticexe) staticexe="" AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe], - [ enable to compile executables statically against (event) libs, for debug purposes ]), + [ enable to compile executables statically against (event) uninstalled libs, for debug purposes ]), , ) if test x_$enable_static_exe = x_yes; then staticexe="-static" @@ -1044,10 +1376,32 @@ if test "$on_mingw" = yes; then staticexe="-all-static" # for static compile, include gdi32 and zlib here. - LIBS="$LIBS -lgdi32 -lz" + if echo $LIBS | grep 'lgdi32' >/dev/null; then + : + else + LIBS="$LIBS -lgdi32" + fi + LIBS="$LIBS -lz" fi fi +# set full static linking if requested +AC_ARG_ENABLE(fully-static, AC_HELP_STRING([--enable-fully-static], + [ enable to compile fully static ]), + , ) +if test x_$enable_fully_static = x_yes; then + staticexe="-all-static" + if test "$on_mingw" = yes; then + # for static compile, include gdi32 and zlib here. + if echo $LIBS | grep 'lgdi32' >/dev/null; then + : + else + LIBS="$LIBS -lgdi32" + fi + LIBS="$LIBS -lz" + fi +fi + # set lock checking if requested AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks], [ enable to check lock and unlock calls, for debug purposes ]), @@ -1065,7 +1419,7 @@ #include ]) AC_CHECK_TOOL(WINDRES, windres) - LIBS="$LIBS -liphlpapi" + LIBS="$LIBS -liphlpapi -lcrypt32" WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe" AC_SUBST(WINAPPS) WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c" @@ -1137,28 +1491,66 @@ #include #endif ]) + +AC_MSG_CHECKING([for htobe64]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([ +#include +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +# include +#endif +], [unsigned long long x = htobe64(0); printf("%u", (unsigned)x);])], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HTOBE64, 1, [If we have htobe64]), + AC_MSG_RESULT(no)) + +AC_MSG_CHECKING([for be64toh]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([ +#include +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +# include +#endif +], [unsigned long long x = be64toh(0); printf("%u", (unsigned)x);])], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BE64TOH, 1, [If we have be64toh]), + AC_MSG_RESULT(no)) + AC_SEARCH_LIBS([setusercontext], [util]) -AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync]) +AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4]) AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])]) AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])]) -AC_MSG_CHECKING([for sbrk]) -# catch the warning of deprecated sbrk -old_cflags="$CFLAGS" -CFLAGS="$CFLAGS -Werror" -AC_COMPILE_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT -[[ -int main(void) { void* cur = sbrk(0); printf("%u\n", (unsigned)(size_t)((char*)cur - (char*)sbrk(0))); return 0; } -]])], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_SBRK, 1, [define if you have the sbrk() call]) - ], [AC_MSG_RESULT(no)]) -CFLAGS="$old_cflags" - # check if setreuid en setregid fail, on MacOSX10.4(darwin8). -if echo $build_os | grep darwin8 > /dev/null; then +if echo $target_os | grep darwin8 > /dev/null; then AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work]) fi +AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [ +AC_INCLUDES_DEFAULT +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif +]) AC_REPLACE_FUNCS(inet_aton) AC_REPLACE_FUNCS(inet_pton) AC_REPLACE_FUNCS(inet_ntop) @@ -1182,25 +1574,43 @@ AC_REPLACE_FUNCS(memmove) AC_REPLACE_FUNCS(gmtime_r) AC_REPLACE_FUNCS(isblank) +AC_REPLACE_FUNCS(explicit_bzero) dnl without CTIME, ARC4-functions and without reallocarray. LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS" AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4) -AC_REPLACE_FUNCS(reallocarray) +AC_MSG_CHECKING([for reallocarray]) +AC_LINK_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT +[[ +#ifndef _OPENBSD_SOURCE +#define _OPENBSD_SOURCE 1 +#endif +#include +int main(void) { + void* p = reallocarray(NULL, 10, 100); + free(p); + return 0; +} +]])], [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REALLOCARRAY, 1, [If we have reallocarray(3)]) +], [ + AC_MSG_RESULT(no) + AC_LIBOBJ(reallocarray) +]) +AC_CHECK_DECLS([reallocarray]) if test "$USE_NSS" = "no"; then AC_REPLACE_FUNCS(arc4random) AC_REPLACE_FUNCS(arc4random_uniform) if test "$ac_cv_func_arc4random" = "no"; then - AC_LIBOBJ(explicit_bzero) AC_LIBOBJ(arc4_lock) AC_CHECK_FUNCS([getentropy],,[ if test "$USE_WINSOCK" = 1; then AC_LIBOBJ(getentropy_win) else - case `uname` in - Darwin) + case "$host" in + Darwin|*darwin*) AC_LIBOBJ(getentropy_osx) ;; - SunOS) + *solaris*|*sunos*|SunOS) AC_LIBOBJ(getentropy_solaris) AC_CHECK_HEADERS([sys/sha2.h],, [ AC_CHECK_FUNCS([SHA512_Update],,[ @@ -1213,7 +1623,10 @@ fi AC_SEARCH_LIBS([clock_gettime], [rt]) ;; - Linux|*) + *freebsd*|*FreeBSD) + AC_LIBOBJ(getentropy_freebsd) + ;; + *linux*|Linux|*) AC_LIBOBJ(getentropy_linux) AC_CHECK_FUNCS([SHA512_Update],,[ AC_DEFINE([COMPAT_SHA512], [1], [Do sha512 definitions in config.h]) @@ -1284,8 +1697,23 @@ ] ) +# check for dnscrypt if requested +dnsc_DNSCRYPT([ + AC_DEFINE([USE_DNSCRYPT], [1], [Define to 1 to enable dnscrypt support]) + AC_SUBST([ENABLE_DNSCRYPT], [1]) + + AC_SUBST([DNSCRYPT_SRC], ["dnscrypt/dnscrypt.c"]) + AC_SUBST([DNSCRYPT_OBJ], ["dnscrypt.lo"]) + ], + [ + AC_SUBST([ENABLE_DNSCRYPT], [0]) + ] +) + # check for cachedb if requested AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage])) +# turn on cachedb when hiredis support is enabled. +if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi case "$enable_cachedb" in yes) AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support]) @@ -1295,6 +1723,62 @@ ;; esac +# check for ipsecmod if requested +AC_ARG_ENABLE(ipsecmod, AC_HELP_STRING([--enable-ipsecmod], [Enable ipsecmod module that facilitates opportunistic IPsec])) +case "$enable_ipsecmod" in + yes) + AC_DEFINE([USE_IPSECMOD], [1], [Define to 1 to use ipsecmod support.]) + IPSECMOD_OBJ="ipsecmod.lo ipsecmod-whitelist.lo" + AC_SUBST(IPSECMOD_OBJ) + IPSECMOD_HEADER='$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h' + AC_SUBST(IPSECMOD_HEADER) + ;; + no|*) + # nothing + ;; +esac + +# check for ipset if requested +AC_ARG_ENABLE(ipset, AC_HELP_STRING([--enable-ipset], [enable ipset module])) +case "$enable_ipset" in + yes) + AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support]) + IPSET_SRC="ipset/ipset.c" + AC_SUBST(IPSET_SRC) + IPSET_OBJ="ipset.lo" + AC_SUBST(IPSET_OBJ) + + # mnl + AC_ARG_WITH(libmnl, AC_HELP_STRING([--with-libmnl=path], + [specify explicit path for libmnl.]), + [ ],[ withval="yes" ]) + found_libmnl="no" + AC_MSG_CHECKING(for libmnl) + if test x_$withval = x_ -o x_$withval = x_yes; then + withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" + fi + for dir in $withval ; do + if test -f "$dir/include/libmnl/libmnl.h"; then + found_libmnl="yes" + dnl assume /usr is in default path. + if test "$dir" != "/usr"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_MSG_RESULT(found in $dir) + LIBS="$LIBS -lmnl" + break; + fi + done + if test x_$found_libmnl != x_yes; then + AC_ERROR([Could not find libmnl, libmnl.h]) + fi + ;; + no|*) + # nothing + ;; +esac + AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope]) # on openBSD, the implicit rule make $< work. # on Solaris, it does not work ($? is changed sources, $^ lists dependencies). @@ -1341,11 +1825,25 @@ INSTALLTARGET="install-lib" fi ]) +if test $ALLTARGET = "alltargets"; then + if test $USE_NSS = "yes"; then + AC_ERROR([--with-nss can only be used in combination with --with-libunbound-only.]) + fi + if test $USE_NETTLE = "yes"; then + AC_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.]) + fi +fi + AC_SUBST(ALLTARGET) AC_SUBST(INSTALLTARGET) ACX_STRIP_EXT_FLAGS -LDFLAGS="$LATE_LDFLAGS $LDFLAGS" +if test -n "$LATE_LDFLAGS"; then + LDFLAGS="$LATE_LDFLAGS $LDFLAGS" +fi +# remove start spaces +LDFLAGS=`echo "$LDFLAGS"|sed -e 's/^ *//'` +LIBS=`echo "$LIBS"|sed -e 's/^ *//'` AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [10240], [Define to the maximum message length to pass to syslog.]) @@ -1355,8 +1853,14 @@ dnl includes [ +#ifndef _OPENBSD_SOURCE +#define _OPENBSD_SOURCE 1 +#endif + #ifndef UNBOUND_DEBUG +# ifndef NDEBUG # define NDEBUG +# endif #endif /** Use small-ldns codebase */ @@ -1471,6 +1975,19 @@ int isblank(int c); #endif +#ifndef HAVE_EXPLICIT_BZERO +#define explicit_bzero unbound_explicit_bzero +void explicit_bzero(void* buf, size_t len); +#endif + +#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + +#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON +int inet_pton(int af, const char* src, void* dst); +#endif + #if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS) #define strptime unbound_strptime struct tm; @@ -1477,6 +1994,15 @@ char *strptime(const char *s, const char *format, struct tm *tm); #endif +#if !HAVE_DECL_REALLOCARRAY +void *reallocarray(void *ptr, size_t nmemb, size_t size); +#endif + +#ifdef HAVE_LIBBSD +#include +#include +#endif + #ifdef HAVE_LIBRESSL # if !HAVE_DECL_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz); @@ -1490,17 +2016,14 @@ # if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM) uint32_t arc4random_uniform(uint32_t upper_bound); # endif -# if !HAVE_DECL_REALLOCARRAY -void *reallocarray(void *ptr, size_t nmemb, size_t size); -# endif #endif /* HAVE_LIBRESSL */ #ifndef HAVE_ARC4RANDOM -void explicit_bzero(void* buf, size_t len); int getentropy(void* buf, size_t len); uint32_t arc4random(void); void arc4random_buf(void* buf, size_t n); void _ARC4_LOCK(void); void _ARC4_UNLOCK(void); +void _ARC4_LOCK_DESTROY(void); #endif #ifndef HAVE_ARC4RANDOM_UNIFORM uint32_t arc4random_uniform(uint32_t upper_bound); @@ -1566,6 +2089,8 @@ /** default port for DNS traffic. */ #define UNBOUND_DNS_PORT 53 +/** default port for DNS over TLS traffic. */ +#define UNBOUND_DNS_OVER_TLS_PORT 853 /** default port for unbound control traffic, registered port with IANA, ub-dns-control 8953/tcp unbound dns nameserver control */ #define UNBOUND_CONTROL_PORT 8953 @@ -1579,6 +2104,6 @@ AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO]) AC_SUBST(date, [`date +'%b %e, %Y'`]) -AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc]) +AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service]) AC_CONFIG_HEADER([config.h]) AC_OUTPUT --- contrib/unbound/contrib/README.orig +++ contrib/unbound/contrib/README @@ -27,5 +27,29 @@ works like the BIND feature (removes AAAA records unless AAAA-only domain). Useful for certain 'broken IPv6 default route' scenarios. Patch from Stephane Lapie for ASAHI Net. -* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts. +* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts. Contributed by Yuri Voinov. +* unbound.socket and unbound.service: systemd files for unbound, install them + in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov. +* unbound_portable.service.in: systemd file for use unbound as portable service, + see comments in the file. Contributed by Frzk. +* redirect-bogus.patch: Return configured address for bogus A and AAAA answers, + instead of SERVFAIL. Contributed by SIDN. +* fastrpz.patch: fastrpz support from Farsight Security. +* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound. +* unbound-querycachedb.py: utility to show data stored in cachedb backend + for a particular query name and type. It requires dnspython and (for + redis backend) redis Python modules. +* unbound-fuzzme.patch: adds unbound-fuzzme program that parses a packet from + stdin. Used with fuzzers, patch from Jacob Hoffman-Andrews. +* unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1 + replacements for unbound-fuzzme.c that gets created after applying + the contrib/unbound-fuzzme.patch. They are contributed by + Eric Sesterhenn from X41 D-Sec. +* drop-tld.diff: adds option drop-tld: yesno that drops 2 label queries, + to stop random floods. Apply with patch -p1 < contrib/drop-tld.diff and + compile. From Saksham Manchanda (Secure64). Please note that we think + this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC + lookups for downstream clients. +* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format, + contributed by Andreas Schulze. --- contrib/unbound/contrib/aaaa-filter-iterator.patch.orig +++ contrib/unbound/contrib/aaaa-filter-iterator.patch @@ -1,10 +1,10 @@ Index: trunk/doc/unbound.conf.5.in =================================================================== ---- trunk/doc/unbound.conf.5.in (revision 3587) +--- trunk/doc/unbound.conf.5.in (revision 4357) +++ trunk/doc/unbound.conf.5.in (working copy) -@@ -593,6 +593,13 @@ - possible. Best effort approach, full QNAME and original QTYPE will be sent when - upstream replies with a RCODE other than NOERROR. Default is off. +@@ -701,6 +701,13 @@ + this option in enabled. Only use if you know what you are doing. + This option only has effect when qname-minimisation is enabled. Default is off. .TP +.B aaaa\-filter: \fI +Activate behavior similar to BIND's AAAA-filter. @@ -18,7 +18,7 @@ on your private network, and are not allowed to be returned for Index: trunk/iterator/iter_scrub.c =================================================================== ---- trunk/iterator/iter_scrub.c (revision 3587) +--- trunk/iterator/iter_scrub.c (revision 4357) +++ trunk/iterator/iter_scrub.c (working copy) @@ -617,6 +617,32 @@ } @@ -75,10 +75,11 @@ /* At this point, we brutally remove ALL rrsets that aren't * children of the originating zone. The idea here is that, * as far as we know, the server that we contacted is ONLY -@@ -681,6 +715,24 @@ +@@ -680,6 +714,24 @@ + prev = NULL; rrset = msg->rrset_first; while(rrset) { - ++ + /* ASN: For AAAA records only... */ + if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) { + /* ASN: If this is not a AAAA query, then remove AAAA @@ -96,13 +97,12 @@ + LDNS_RR_TYPE_AAAA, qinfo->qclass); + } + /* ASN: End of added code */ -+ + /* remove private addresses */ if( (rrset->type == LDNS_RR_TYPE_A || - rrset->type == LDNS_RR_TYPE_AAAA)) { Index: trunk/iterator/iter_utils.c =================================================================== ---- trunk/iterator/iter_utils.c (revision 3587) +--- trunk/iterator/iter_utils.c (revision 4357) +++ trunk/iterator/iter_utils.c (working copy) @@ -175,6 +175,7 @@ } @@ -114,9 +114,9 @@ Index: trunk/iterator/iterator.c =================================================================== ---- trunk/iterator/iterator.c (revision 3587) +--- trunk/iterator/iterator.c (revision 4357) +++ trunk/iterator/iterator.c (working copy) -@@ -1776,6 +1776,53 @@ +@@ -1847,6 +1847,53 @@ return 0; } @@ -170,7 +170,7 @@ /** * This is the request event state where the request will be sent to one of -@@ -1823,6 +1870,13 @@ +@@ -1894,6 +1941,13 @@ return error_response(qstate, id, LDNS_RCODE_SERVFAIL); } @@ -184,7 +184,7 @@ /* Make sure we have a delegation point, otherwise priming failed * or another failure occurred */ if(!iq->dp) { -@@ -2922,6 +2976,61 @@ +@@ -3095,6 +3149,61 @@ return 0; } @@ -244,9 +244,9 @@ +/* ASN: End of added code */ + /* - * Return priming query results to interestes super querystates. + * Return priming query results to interested super querystates. * -@@ -2941,6 +3050,9 @@ +@@ -3114,6 +3223,9 @@ else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*) super->minfo[id])->state == DSNS_FIND_STATE) processDSNSResponse(qstate, id, super); @@ -256,7 +256,7 @@ else if(qstate->return_rcode != LDNS_RCODE_NOERROR) error_supers(qstate, id, super); else if(qstate->is_priming) -@@ -2978,6 +3090,9 @@ +@@ -3151,6 +3263,9 @@ case INIT_REQUEST_3_STATE: cont = processInitRequest3(qstate, iq, id); break; @@ -266,7 +266,7 @@ case QUERYTARGETS_STATE: cont = processQueryTargets(qstate, iq, ie, id); break; -@@ -3270,6 +3385,8 @@ +@@ -3460,6 +3575,8 @@ return "INIT REQUEST STATE (stage 2)"; case INIT_REQUEST_3_STATE: return "INIT REQUEST STATE (stage 3)"; @@ -275,7 +275,7 @@ case QUERYTARGETS_STATE : return "QUERY TARGETS STATE"; case PRIME_RESP_STATE : -@@ -3294,6 +3411,7 @@ +@@ -3484,6 +3601,7 @@ case INIT_REQUEST_STATE : case INIT_REQUEST_2_STATE : case INIT_REQUEST_3_STATE : @@ -285,9 +285,9 @@ return 0; Index: trunk/iterator/iterator.h =================================================================== ---- trunk/iterator/iterator.h (revision 3587) +--- trunk/iterator/iterator.h (revision 4357) +++ trunk/iterator/iterator.h (working copy) -@@ -113,6 +113,9 @@ +@@ -130,6 +130,9 @@ */ int* target_fetch_policy; @@ -294,10 +294,10 @@ + /** ASN: AAAA-filter flag */ + int aaaa_filter; + - /** ip6.arpa dname in wireformat, used for qname-minimisation */ - uint8_t* ip6arpa_dname; - }; -@@ -163,6 +166,14 @@ + /** lock on ratelimit counter */ + lock_basic_type queries_ratelimit_lock; + /** number of queries that have been ratelimited */ +@@ -182,6 +185,14 @@ INIT_REQUEST_3_STATE, /** @@ -311,11 +311,12 @@ + /** * Each time a delegation point changes for a given query or a * query times out and/or wakes up, this state is (re)visited. - * This state is reponsible for iterating through a list of -@@ -346,6 +357,13 @@ + * This state is responsible for iterating through a list of +@@ -364,6 +375,13 @@ + * be used when creating the state. A higher one will be attempted. */ int refetch_glue; - ++ + /** + * ASN: This is a flag that, if true, means that this query is + * for fetching A records to populate cache and determine if we must @@ -322,15 +323,14 @@ + * return AAAA records or not. + */ + int fetch_a_for_aaaa; -+ + /** list of pending queries to authoritative servers. */ struct outbound_list outlist; - Index: trunk/pythonmod/interface.i =================================================================== ---- trunk/pythonmod/interface.i (revision 3587) +--- trunk/pythonmod/interface.i (revision 4357) +++ trunk/pythonmod/interface.i (working copy) -@@ -632,6 +632,7 @@ +@@ -851,6 +851,7 @@ int harden_dnssec_stripped; int harden_referral_path; int use_caps_bits_for_id; @@ -340,9 +340,9 @@ size_t unwanted_threshold; Index: trunk/util/config_file.c =================================================================== ---- trunk/util/config_file.c (revision 3587) +--- trunk/util/config_file.c (revision 4357) +++ trunk/util/config_file.c (working copy) -@@ -176,6 +176,7 @@ +@@ -195,6 +195,7 @@ cfg->harden_referral_path = 0; cfg->harden_algo_downgrade = 0; cfg->use_caps_bits_for_id = 0; @@ -352,9 +352,9 @@ cfg->private_domain = NULL; Index: trunk/util/config_file.h =================================================================== ---- trunk/util/config_file.h (revision 3587) +--- trunk/util/config_file.h (revision 4357) +++ trunk/util/config_file.h (working copy) -@@ -179,6 +179,8 @@ +@@ -209,6 +209,8 @@ int harden_algo_downgrade; /** use 0x20 bits in query as random ID bits */ int use_caps_bits_for_id; @@ -365,9 +365,9 @@ /** strip away these private addrs from answers, no DNS Rebinding */ Index: trunk/util/configlexer.lex =================================================================== ---- trunk/util/configlexer.lex (revision 3587) +--- trunk/util/configlexer.lex (revision 4357) +++ trunk/util/configlexer.lex (working copy) -@@ -267,6 +267,7 @@ +@@ -279,6 +279,7 @@ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) } caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) } unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } @@ -377,9 +377,9 @@ prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } Index: trunk/util/configparser.y =================================================================== ---- trunk/util/configparser.y (revision 3587) +--- trunk/util/configparser.y (revision 4357) +++ trunk/util/configparser.y (working copy) -@@ -92,6 +92,7 @@ +@@ -95,6 +95,7 @@ %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT %token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR %token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS @@ -387,7 +387,7 @@ %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE -@@ -169,6 +170,7 @@ +@@ -203,6 +204,7 @@ server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size | server_harden_referral_path | server_private_address | server_private_domain | server_extended_statistics | @@ -395,10 +395,12 @@ server_local_data_ptr | server_jostle_timeout | server_unwanted_reply_threshold | server_log_time_ascii | server_domain_insecure | server_val_sig_skew_min | -@@ -893,6 +895,15 @@ +@@ -1183,6 +1185,15 @@ + OUTYY(("P(server_caps_whitelist:%s)\n", $2)); + if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2)) yyerror("out of memory"); - } - ; ++ } ++ ; +server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG + { + OUTYY(("P(server_aaaa_filter:%s)\n", $2)); @@ -406,8 +408,6 @@ + yyerror("expected yes or no."); + else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0); + free($2); -+ } -+ ; + } + ; server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG - { - OUTYY(("P(server_private_address:%s)\n", $2)); --- contrib/unbound/contrib/create_unbound_ad_servers.sh.orig +++ contrib/unbound/contrib/create_unbound_ad_servers.sh @@ -9,12 +9,13 @@ # Variables dst_dir="/etc/opt/csw/unbound" work_dir="/tmp" -list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" +list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" # OS commands CAT=`which cat` ECHO=`which echo` WGET=`which wget` +TR=`which tr` # Check Wget installed if [ ! -f $WGET ]; then @@ -22,8 +23,10 @@ exit 1 fi +# remove special characters with tr to protect unbound.conf $WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \ $CAT $work_dir/yoyo_ad_servers | \ +$TR -d '";$\\' | \ while read line ; \ do \ $ECHO "local-zone: \"$line\" redirect" ;\ @@ -36,4 +39,4 @@ # the unbound_ad_servers file: # # include: $dst_dir/unbound_ad_servers -# \ No newline at end of file +# --- contrib/unbound/contrib/drop-tld.diff.orig +++ contrib/unbound/contrib/drop-tld.diff @@ -0,0 +1,82 @@ +diff --git a/daemon/worker.c b/daemon/worker.c +index 263fcdd..f787b70 100644 +--- a/daemon/worker.c ++++ b/daemon/worker.c +@@ -1213,6 +1213,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error, + addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); + log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass); + } ++ ++ if(worker->env.cfg->drop_tld) { ++ int lab = dname_count_labels(qinfo.qname); ++ if (lab == 2) { ++ comm_point_drop_reply(repinfo); ++ verbose(VERB_ALGO, "Dropping one label query."); ++ return 0; ++ } ++ } + if(qinfo.qtype == LDNS_RR_TYPE_AXFR || + qinfo.qtype == LDNS_RR_TYPE_IXFR) { + verbose(VERB_ALGO, "worker request: refused zone transfer."); +diff --git a/util/config_file.h b/util/config_file.h +index b3ef930..2791541 100644 +--- a/util/config_file.h ++++ b/util/config_file.h +@@ -274,6 +274,8 @@ struct config_file { + int prefetch_key; + /** deny queries of type ANY with an empty answer */ + int deny_any; ++ /** Drop TLD queries from clients **/ ++ int drop_tld; + + /** chrootdir, if not "" or chroot will be done */ + char* chrootdir; +diff --git a/util/configlexer.lex b/util/configlexer.lex +index a86ddf5..9bbedbb 100644 +--- a/util/configlexer.lex ++++ b/util/configlexer.lex +@@ -299,6 +299,7 @@ private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } + prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } + prefetch{COLON} { YDVAR(1, VAR_PREFETCH) } + deny-any{COLON} { YDVAR(1, VAR_DENY_ANY) } ++drop-tld{COLON} { YDVAR(1, VAR_DROP_TLD) } + stub-zone{COLON} { YDVAR(0, VAR_STUB_ZONE) } + name{COLON} { YDVAR(1, VAR_NAME) } + stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) } +diff --git a/util/configparser.y b/util/configparser.y +index 10227a2..567d68e 100644 +--- a/util/configparser.y ++++ b/util/configparser.y +@@ -164,6 +164,7 @@ extern struct config_parser_state* cfg_parser; + %token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM + %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT + %token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY ++%token VAR_DROP_TLD + %token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY + %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES + %token VAR_TLS_SESSION_TICKET_KEYS +@@ -266,6 +267,7 @@ content_server: server_num_threads | server_verbosity | server_port | + server_tls_cert_bundle | server_tls_additional_port | server_low_rtt | + server_fast_server_permil | server_fast_server_num | server_tls_win_cert | + server_tcp_connection_limit | server_log_servfail | server_deny_any | ++ server_drop_tld | + server_unknown_server_time_limit | server_log_tag_queryreply | + server_stream_wait_size | server_tls_ciphers | + server_tls_ciphersuites | server_tls_session_ticket_keys +@@ -1466,6 +1468,16 @@ server_deny_any: VAR_DENY_ANY STRING_ARG + free($2); + } + ; ++ ++server_drop_tld: VAR_DROP_TLD STRING_ARG ++ { ++ OUTYY(("P(server_drop_tld:%s)\n", $2)); ++ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) ++ yyerror("expected yes or no."); ++ else cfg_parser->cfg->drop_tld = (strcmp($2, "yes")==0); ++ free($2); ++ } ++ ; + server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG + { + OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2)); --- contrib/unbound/contrib/drop2rpz.orig +++ contrib/unbound/contrib/drop2rpz @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local +# +# unbound.conf: +# rpz: +# name: "spamhaus-drop.rpz.local." +# zonefile: "/path/tp/spamhaus-drop.rpz.local" +# rpz-log: yes +# rpz-log-name: "spamhaus-drop" +# + +use strict; +use vars qw{$o1 $o2 $o3 $o4 $m}; + +# trailing dots required +my $origin = 'drop.spamhaus.org.rpz.local.'; +my $mname = 'localhost.'; +my $rname = 'root.localhost.'; +my $ns = $mname; + +my $rpz_action = '.'; # return NXDOMAIN +#my $rpz_action = '*.'; # return NODATA +#my $rpz_action = 'rpz-drop.'; # drop the query + +print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n"; +print "$origin NS $ns\n"; +while(<>) { + if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) { + print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n"; + } else { + print "$_"; + } +} + +# add a testpoint: ask for "dns.google" +# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n"; + +exit; --- contrib/unbound/contrib/fastrpz.patch.orig +++ contrib/unbound/contrib/fastrpz.patch @@ -0,0 +1,3504 @@ +Description: based on the included patch contrib/fastrpz.patch +Author: fastrpz@farsightsecurity.com +--- +diff --git a/Makefile.in b/Makefile.in +index a20058cc..495779cc 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c + CHECKLOCK_OBJ=@CHECKLOCK_OBJ@ + DNSTAP_SRC=@DNSTAP_SRC@ + DNSTAP_OBJ=@DNSTAP_OBJ@ ++FASTRPZ_SRC=@FASTRPZ_SRC@ ++FASTRPZ_OBJ=@FASTRPZ_OBJ@ + DNSCRYPT_SRC=@DNSCRYPT_SRC@ + DNSCRYPT_OBJ=@DNSCRYPT_OBJ@ + WITH_PYTHONMODULE=@WITH_PYTHONMODULE@ +@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \ + edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \ + edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \ + cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \ +-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC) ++$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC) + COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \ + as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \ + iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \ +@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \ + validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \ + val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \ + $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \ +-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo ++$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo + COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \ + outside_network.lo + COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo +@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \ + $(srcdir)/util/config_file.h $(srcdir)/util/log.h \ + $(srcdir)/util/netevent.h + ++# fastrpz ++rpz.lo rpz.o: $(srcdir)/fastrpz/rpz.c config.h fastrpz/rpz.h fastrpz/librpz.h \ ++ $(srcdir)/util/config_file.h $(srcdir)/daemon/daemon.h \ ++ $(srcdir)/util/log.h ++ + # Python Module + pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \ + pythonmod/interface.h \ +diff --git a/config.h.in b/config.h.in +index 78d47fed..e33073e4 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, + /** the version of unbound-control that this software implements */ + #define UNBOUND_CONTROL_VERSION 1 + +- ++/* have __attribute__s used in librpz.h */ ++#undef LIBRPZ_HAVE_ATTR ++/** fastrpz librpz.so */ ++#undef FASTRPZ_LIBRPZ_PATH ++/** 0=no fastrpz 1=static link 2=dlopen() */ ++#undef FASTRPZ_LIB_OPEN ++/** turn on fastrpz response policy zones */ ++#undef ENABLE_FASTRPZ +diff --git a/configure.ac b/configure.ac +index 2b91dd3c..e6063d17 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4) + sinclude(acx_python.m4) + sinclude(ac_pkg_swig.m4) + sinclude(dnstap/dnstap.m4) ++sinclude(fastrpz/rpz.m4) + sinclude(dnscrypt/dnscrypt.m4) + + # must be numbers. ac_defun because of later processing +@@ -1778,6 +1779,9 @@ case "$enable_ipset" in + ;; + esac + ++# check for Fastrpz with fastrpz/rpz.m4 ++ck_FASTRPZ ++ + AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope]) + # on openBSD, the implicit rule make $< work. + # on Solaris, it does not work ($? is changed sources, $^ lists dependencies). +diff --git a/daemon/daemon.c b/daemon/daemon.c +index 8b0fc348..7ffb9221 100644 +--- a/daemon/daemon.c ++++ b/daemon/daemon.c +@@ -91,6 +91,9 @@ + #include "sldns/keyraw.h" + #include "respip/respip.h" + #include ++#ifdef ENABLE_FASTRPZ ++#include "fastrpz/rpz.h" ++#endif + + #ifdef HAVE_SYSTEMD + #include +@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon) + dt_apply_cfg(daemon->dtenv, daemon->cfg); + #else + fatal_exit("dnstap enabled in config but not built with dnstap support"); ++#endif ++ } ++ if(daemon->cfg->rpz_enable) { ++#ifdef ENABLE_FASTRPZ ++ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg); ++#else ++ fatal_exit("fastrpz enabled in config" ++ " but not built with fastrpz"); + #endif + } + for(i=0; inum; i++) { +@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon) + #ifdef USE_DNSCRYPT + dnsc_delete(daemon->dnscenv); + daemon->dnscenv = NULL; ++#endif ++#ifdef ENABLE_FASTRPZ ++ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client); + #endif + daemon->cfg = NULL; + } +diff --git a/daemon/daemon.h b/daemon/daemon.h +index 3effbafb..4d4c34da 100644 +--- a/daemon/daemon.h ++++ b/daemon/daemon.h +@@ -138,6 +138,11 @@ struct daemon { + /** the dnscrypt environment */ + struct dnsc_env* dnscenv; + #endif ++#ifdef ENABLE_FASTRPZ ++ /** global opaque rpz handles */ ++ struct librpz_clist *rpz_clist; ++ struct librpz_client *rpz_client; ++#endif + }; + + /** +diff --git a/daemon/worker.c b/daemon/worker.c +index eb7fdf2f..1982228d 100644 +--- a/daemon/worker.c ++++ b/daemon/worker.c +@@ -76,6 +76,9 @@ + #include "libunbound/context.h" + #include "libunbound/libworker.h" + #include "sldns/sbuffer.h" ++#ifdef ENABLE_FASTRPZ ++#include "fastrpz/rpz.h" ++#endif + #include "sldns/wire2str.h" + #include "util/shm_side/shm_main.h" + #include "dnscrypt/dnscrypt.h" +@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo, + /* not secure */ + secure = 0; + break; ++#ifdef ENABLE_FASTRPZ ++ case sec_status_rpz_rewritten: ++ case sec_status_rpz_drop: ++ fatal_exit("impossible cached RPZ sec_status"); ++ break; ++#endif + } + } ++#ifdef ENABLE_FASTRPZ ++ if(repinfo->rpz) { ++ /* Scan the cached answer for RPZ hits. ++ * ret=1 use cache entry ++ * ret=-1 rewritten response already sent or dropped ++ * ret=0 deny a cached entry exists ++ */ ++ int ret = rpz_worker_cache(worker, msg->rep, qinfo, ++ id, flags, edns, repinfo); ++ if(ret != 1) ++ return ret; ++ } ++#endif + /* return this delegation from the cache */ + edns_bak = *edns; + edns->edns_version = EDNS_ADVERTISED_VERSION; +@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, + *is_secure_answer = 0; + } + } else *is_secure_answer = 0; ++#ifdef ENABLE_FASTRPZ ++ if(repinfo->rpz) { ++ /* Scan the cached answer for RPZ hits. ++ * ret=1 use cache entry ++ * ret=-1 rewritten response already sent or dropped ++ * ret=0 deny a cached entry exists ++ */ ++ int ret = rpz_worker_cache(worker, rep, qinfo, id, flags, edns, ++ repinfo); ++ if(ret != 1) { ++ rrset_array_unlock_touch(worker->env.rrset_cache, ++ worker->scratchpad, rep->ref, ++ rep->rrset_count); ++ return ret; ++ } ++ } ++#endif + + edns_bak = *edns; + edns->edns_version = EDNS_ADVERTISED_VERSION; +@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error, + log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from", + &repinfo->addr, repinfo->addrlen); + goto send_reply; ++#ifdef ENABLE_FASTRPZ ++ } else { ++ /* Start to rewrite for response policy zones. ++ * This can hit a qname trigger and be done. */ ++ if(rpz_start(worker, &qinfo, repinfo, &edns)) { ++ regional_free_all(worker->scratchpad); ++ return 0; ++ } ++#endif + } + + /* If we've found a local alias, replace the qname with the alias +@@ -1485,12 +1533,21 @@ lookup_cache: + h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); + if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) { + /* answer from cache - we have acquired a readlock on it */ +- if(answer_from_cache(worker, &qinfo, ++ ret = answer_from_cache(worker, &qinfo, + cinfo, &need_drop, &is_expired_answer, &is_secure_answer, + &alias_rrset, &partial_rep, (struct reply_info*)e->data, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, +- &edns)) { ++ &edns); ++#ifdef ENABLE_FASTRPZ ++ if(ret < 0) { ++ /* RPZ already dropped or sent a response. */ ++ lock_rw_unlock(&e->lock); ++ regional_free_all(worker->scratchpad); ++ return 0; ++ } ++#endif ++ if(ret) { + /* prefetch it if the prefetch TTL expired. + * Note that if there is more than one pass + * its qname must be that used for cache +@@ -1547,11 +1604,19 @@ lookup_cache: + lock_rw_unlock(&e->lock); + } + if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) { +- if(answer_norec_from_cache(worker, &qinfo, ++ ret = answer_norec_from_cache(worker, &qinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, +- &edns)) { ++ &edns); ++ if(ret) { + regional_free_all(worker->scratchpad); ++#ifdef ENABLE_FASTRPZ ++ if(ret < 0) { ++ /* RPZ already dropped ++ * or sent a response. */ ++ return 0; ++ } ++#endif + goto send_reply; + } + verbose(VERB_ALGO, "answer norec from cache -- " +diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in +index 38c2d298..3b07f392 100644 +--- a/doc/unbound.conf.5.in ++++ b/doc/unbound.conf.5.in +@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is + used by dns64 processing instead. Can be entered multiple times, list a + new domain for which it applies, one per line. Applies also to names + underneath the name given. ++.SS "Response Policy Zone Rewriting" ++.LP ++Response policy zone rewriting is controlled with the ++.B rpz ++clause. ++It must contain a ++.B rpz\-enable: ++option, and one or more ++.B rpz\-zone: ++options. ++It will usually also contain ++.B rpz\-option: ++clauses with general rewriting options or specifying dnsrpzd parameters. ++Beneath the surface, the text in ++.B rpz\-zone: \fI<"domain">\fR ++is converted to \fI"zone domain\\n"\fR and added to the configuration string ++given to ++\fIlibrpz\fR(3). ++The text in ++.B rpz-option \fI<"text">\fR ++is also added to that configuration string. ++.LP ++If using chroot, then the chroot directory must contain the \fIdnsrpzd\fR(3) ++command and the shared libraries that it uses. ++Those can be found with the \fIldd\fR(1) command. ++.LP ++Resolver zone and rewriting options and response policy zone triggers and ++actions are described in \fIlibrpz\fR(3). ++The separate control file that specifies the policy zones maintained by ++the dnsrpzd daemon is described in \fIdnsrpzd\fR(8). ++.LP ++Many installations need a local whitelist that exempts local ++domains from rewriting. ++Whitelist records can be in zones transferred by dnsrpzd from ++authorities or in a local zone file. ++.TP ++.B rpz-enable: \fI ++enables Fastrpz. ++If not enabled, the other options in the ++.B rpz: ++clause are ignored. ++.TP ++.B rpz-zone: \fI<"zone and options"> ++specifies a policy zone and optional per-zone rewriting parameters. ++.TP ++.B rpz-option: \fI<"option"> ++specifies general Fastrpz options. ++.LP ++Fastrpz is available only on POSIX compliant UNIX-like systems with the ++\fImmap\fR(2) system call. ++.LP ++Fastrpz in Unbound differs from rpz and fastrpz in BIND by ++.RS 3 ++.HP 4 ++RPZ-CLIENT-IP triggers can only be used in the first policy zone ++specified with ++.B rpz-zone: ++.HP ++Policy zone rewriting is disabled by the DO bit in DNS requests ++even when no DNSSEC signatures are supplied by authorities. ++.HP ++Unbound local zones are not subject to rpz rewriting. ++.HP ++Like Fastrpz with BIND but unlike classic BIND rpz, ++the ADDITIONAL sections of rewritten responses contain the SOA record from ++the policy zone used to rewrite the response. ++.RE ++.P ++.nf ++# example Fastrpz settings for use with chroot on Freebsd ++rpz: ++ rpz-zone: "rpz.example.org" ++ rpz-zone: "other.rpz.example.org ip-as-ns yes" ++ rpz-option: "dnsrpzd ./dnsrpzd" ++.fi + .SS "DNSCrypt Options" + .LP + The +diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h +new file mode 100644 +index 00000000..645279d1 +--- /dev/null ++++ b/fastrpz/librpz.h +@@ -0,0 +1,957 @@ ++/* ++ * Define the interface from a DNS resolver to the Response Policy Zone ++ * library, librpz. ++ * ++ * This file should be included only the interface functions between the ++ * resolver and librpz to avoid name space pollution. ++ * ++ * Copyright (c) 2016-2017 Farsight Security, Inc. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Fastrpz version 1.2.10 ++ */ ++ ++#ifndef LIBRPZ_H ++#define LIBRPZ_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* ++ * Allow either ordinary or dlopen() linking. ++ */ ++#ifdef LIBRPZ_INTERNAL ++#define LIBDEF(t,s) extern t s; ++#define LIBDEF_F(f) LIBDEF(librpz_##f##_t, librpz_##f) ++#else ++#define LIBDEF(t,s) ++#define LIBDEF_F(f) ++#endif ++ ++/* ++ * Response Policy Zone triggers. ++ * Comparisons of trigger precedences require ++ * LIBRPZ_TRIG_CLIENT_IP < LIBRPZ_TRIG_QNAME < LIBRPZ_TRIG_IP ++ * < LIBRPZ_TRIG_NSDNAME < LIBRPZ_TRIG_NSIP} ++ */ ++typedef enum { ++ LIBRPZ_TRIG_BAD =0, ++ LIBRPZ_TRIG_CLIENT_IP =1, ++ LIBRPZ_TRIG_QNAME =2, ++ LIBRPZ_TRIG_IP =3, ++ LIBRPZ_TRIG_NSDNAME =4, ++ LIBRPZ_TRIG_NSIP =5 ++} librpz_trig_t; ++#define LIBRPZ_TRIG_SIZE 3 /* sizeof librpz_trig_t in bits */ ++typedef uint8_t librpz_tbit_t; /* one bit for each of the TRIGS_NUM ++ * trigger types */ ++ ++ ++/* ++ * Response Policy Zone Actions or policies ++ */ ++typedef enum { ++ LIBRPZ_POLICY_UNDEFINED =0, /* an empty entry or no decision yet */ ++ LIBRPZ_POLICY_DELETED =1, /* placeholder for a deleted policy */ ++ ++ LIBRPZ_POLICY_PASSTHRU =2, /* 'passthru': do not rewrite */ ++ LIBRPZ_POLICY_DROP =3, /* 'drop': do not respond */ ++ LIBRPZ_POLICY_TCP_ONLY =4, /* 'tcp-only': answer UDP with TC=1 */ ++ LIBRPZ_POLICY_NXDOMAIN =5, /* 'nxdomain': answer with NXDOMAIN */ ++ LIBRPZ_POLICY_NODATA =6, /* 'nodata': answer with ANCOUNT=0 */ ++ LIBRPZ_POLICY_RECORD =7, /* rewrite with the policy's RR */ ++ ++ /* only in client configurations to override the zone */ ++ LIBRPZ_POLICY_GIVEN, /* 'given': what policy record says */ ++ LIBRPZ_POLICY_DISABLED, /* at most log */ ++ LIBRPZ_POLICY_CNAME, /* answer with 'cname x' */ ++} librpz_policy_t; ++#define LIBRPZ_POLICY_BITS 4 ++ ++/* ++ * Special policies that appear as targets of CNAMEs ++ * NXDOMAIN is signaled by a CNAME with a "." target. ++ * NODATA is signaled by a CNAME with a "*." target. ++ */ ++#define LIBRPZ_RPZ_PREFIX "rpz-" ++#define LIBRPZ_RPZ_PASSTHRU LIBRPZ_RPZ_PREFIX"passthru" ++#define LIBRPZ_RPZ_DROP LIBRPZ_RPZ_PREFIX"drop" ++#define LIBRPZ_RPZ_TCP_ONLY LIBRPZ_RPZ_PREFIX"tcp-only" ++ ++ ++typedef uint16_t librpz_dznum_t; /* dnsrpzd zone # in [0,DZNUM_MAX] */ ++typedef uint8_t librpz_cznum_t; /* client zone # in [0,CZNUM_MAX] */ ++ ++ ++/* ++ * CIDR block ++ */ ++typedef struct librpz_prefix { ++ union { ++ struct in_addr in; ++ struct in6_addr in6; ++ } addr; ++ uint8_t family; ++ uint8_t len; ++} librpz_prefix_t; ++ ++/* ++ * A domain ++ */ ++typedef uint8_t librpz_dsize_t; ++typedef struct librpz_domain { ++ librpz_dsize_t size; /* of only .d */ ++ uint8_t d[0]; /* variable length wire format */ ++} librpz_domain_t; ++ ++/* ++ * A maximal domain buffer ++ */ ++typedef struct librpz_domain_buf { ++ librpz_dsize_t size; ++ uint8_t d[NS_MAXCDNAME]; ++} librpz_domain_buf_t; ++ ++/* ++ * A resource record without the owner name. ++ * C compilers say that sizeof(librpz_rr_t)=12 instead of 10. ++ */ ++typedef struct { ++ uint16_t type; /* network byte order */ ++ uint16_t class; /* network byte order */ ++ uint32_t ttl; /* network byte order */ ++ uint16_t rdlength; /* network byte order */ ++ uint8_t rdata[0]; /* variable length */ ++} librpz_rr_t; ++ ++/* ++ * The database file might be mapped with different starting addresses ++ * by concurrent clients (resolvers), and so all pointers are offsets. ++ */ ++typedef uint32_t librpz_idx_t; ++#define LIBRPZ_IDX_NULL 0 ++#define LIBRPZ_IDX_MIN 1 ++#define LIBRPZ_IDX_BAD ((librpz_idx_t)-1) ++/** ++ * Partial decoded results of a set of RPZ queries for a single DNS response ++ * or interation through the mapped file. ++ */ ++typedef int16_t librpz_result_id_t; ++typedef struct librpz_result { ++ librpz_idx_t next_rr; ++ librpz_result_id_t hit_id; /* trigger ID from resolver */ ++ librpz_policy_t zpolicy; /* policy from zone */ ++ librpz_policy_t policy; /* adjusted by client configuration */ ++ librpz_dznum_t dznum; /* dnsrpzd zone number */ ++ librpz_cznum_t cznum; /* librpz client zone number */ ++ librpz_trig_t trig:LIBRPZ_TRIG_SIZE; ++ bool log:1; /* log rewrite given librpz_log_level */ ++} librpz_result_t; ++ ++ ++/** ++ * librpz trace or log levels. ++ */ ++typedef enum { ++ LIBRPZ_LOG_FATAL =0, /* always print fatal errors */ ++ LIBRPZ_LOG_ERROR =1, /* errors have this level */ ++ LIBRPZ_LOG_TRACE1 =2, /* big events such as dnsrpzd starts */ ++ LIBRPZ_LOG_TRACE2 =3, /* smaller dnsrpzd zone transfers */ ++ LIBRPZ_LOG_TRACE3 =4, /* librpz hits */ ++ LIBRPZ_LOG_TRACE4 =5, /* librpz lookups */ ++ LIBRPZ_LOG_INVALID =999, ++} librpz_log_level_t; ++typedef librpz_log_level_t (librpz_log_level_val_t)(librpz_log_level_t level); ++LIBDEF_F(log_level_val) ++ ++/** ++ * Logging function that can be supplied by the resolver. ++ * @param level is one of librpz_log_level_t ++ * @param ctx is for use by the resolver's logging system. ++ * NULL mean a context-free message. ++ */ ++typedef void(librpz_log_fnc_t)(librpz_log_level_t level, void *ctx, ++ const char *buf); ++ ++/** ++ * Point librpz logging functions to the resolver's choice. ++ */ ++typedef void (librpz_set_log_t)(librpz_log_fnc_t *new_log, const char *prog_nm); ++LIBDEF_F(set_log) ++ ++ ++/** ++ * librpz error messages are put in these buffers. ++ * Use a structure intead of naked char* to let the compiler check the length. ++ * A function defined with "foo(char buf[120])" can be called with ++ * "char sbuf[2]; foo(sbuf)" and suffer a buffer overrun. ++ */ ++typedef struct { ++ char c[120]; ++} librpz_emsg_t; ++ ++ ++#ifdef LIBRPZ_HAVE_ATTR ++#define LIBRPZ_UNUSED __attribute__((unused)) ++#define LIBRPZ_PF(f,l) __attribute__((format(printf,f,l))) ++#define LIBRPZ_NORET __attribute__((__noreturn__)) ++#else ++#define LIBRPZ_UNUSED ++#define LIBRPZ_PF(f,l) ++#define LIBRPZ_NORET ++#endif ++ ++#ifdef HAVE_BUILTIN_EXPECT ++#define LIBRPZ_LIKELY(c) __builtin_expect(!!(c), 1) ++#define LIBRPZ_UNLIKELY(c) __builtin_expect(!!(c), 0) ++#else ++#define LIBRPZ_LIKELY(c) (c) ++#define LIBRPZ_UNLIKELY(c) (c) ++#endif ++ ++typedef bool (librpz_parse_log_opt_t)(librpz_emsg_t *emsg, const char *arg); ++LIBDEF_F(parse_log_opt) ++ ++typedef void (librpz_vpemsg_t)(librpz_emsg_t *emsg, ++ const char *p, va_list args); ++LIBDEF_F(vpemsg) ++typedef void (librpz_pemsg_t)(librpz_emsg_t *emsg, ++ const char *p, ...) LIBRPZ_PF(2,3); ++LIBDEF_F(pemsg) ++ ++typedef void (librpz_vlog_t)(librpz_log_level_t level, void *ctx, ++ const char *p, va_list args); ++LIBDEF_F(vlog) ++typedef void (librpz_log_t)(librpz_log_level_t level, void *ctx, ++ const char *p, ...) LIBRPZ_PF(3,4); ++LIBDEF_F(log) ++ ++typedef void (librpz_fatal_t)(int ex_code, ++ const char *p, ...) LIBRPZ_PF(2,3); ++extern void librpz_fatal(int ex_code, ++ const char *p, ...) LIBRPZ_PF(2,3) LIBRPZ_NORET; ++ ++typedef void (librpz_rpz_assert_t)(const char *file, unsigned line, ++ const char *p, ...) LIBRPZ_PF(3,4); ++extern void librpz_rpz_assert(const char *file, unsigned line, ++ const char *p, ...) LIBRPZ_PF(3,4) LIBRPZ_NORET; ++ ++typedef void (librpz_rpz_vassert_t)(const char *file, uint line, ++ const char *p, va_list args); ++extern void librpz_rpz_vassert(const char *file, uint line, ++ const char *p, va_list args) LIBRPZ_NORET; ++ ++ ++/* ++ * As far as clients are concerned, all relative pointers or indexes in a ++ * version of the mapped file except trie node parent pointers remain valid ++ * forever. A client must release a version so that it can be garbage ++ * collected by the file system. When dnsrpzd needs to expand the file, ++ * it copies the old file to a new, larger file. Clients can continue ++ * using the old file. ++ * ++ * Versions can also appear in a single file. Old nodes and trie values ++ * within the file are not destroyed until all clients using the version ++ * that contained the old values release the version. ++ * ++ * A client is marked as using version by connecting to the deamon. It is ++ * marked as using all subsequent versions. A client releases all versions ++ * by closing the connection or a range of versions by updating is slot ++ * in the shared memory version table. ++ * ++ * As far as clients are concerned, there are the following possible librpz ++ * failures: ++ * - malloc() or other fatal internal librpz problems indicated by ++ * a failing return from a librpz function ++ * All operations will fail until client handle is destroyed and ++ * recreated with librpz_client_detach() and librpz_client_create(). ++ * - corrupt database detected by librpz code, corrupt database detected ++ * by dnsrpzd, or disconnection from the daemon. ++ * Current operations will fail. ++ * ++ * Clients assume that the file has already been unlinked before ++ * the corrupt flag is set so that they do not race with the server ++ * over the corruption of a single file. A client that finds the ++ * corrupt set knows that dnsrpzd has already crashed with ++ * abort() and is restarting. The client can re-connect to dnsrpzd ++ * and retransmit its configuration, backing off as usual if anything ++ * goes wrong. ++ * ++ * Searchs of the database by a client do not need locks against dnsrpzd or ++ * other clients, but a lock is used to protect changes to the connection ++ * by competing threads in the client. The client provides fuctions ++ * to serialize the conncurrent use of any single client handle. ++ * Functions that do nothing are appropriate for applications that are ++ * not "threaded" or that do not share client handles among threads. ++ * Otherwise, functions must be provided to librpz_clientcreate(). ++ * Something like the following works with pthreads: ++ * ++ * static void ++ * lock(void *mutex) { assert(pthread_mutex_lock(mutex) == 0); } ++ * ++ * static void ++ * unlock(void *mutex) { assert(pthread_mutex_unlock(mutex) == 0); } ++ * ++ * static void ++ * mutex_destroy(void *mutex) { assert(pthread_mutex_destroy(mutex) == 0); } ++ * ++ * ++ * ++ * At every instant, all of the data and pointers in the mapped file are valid. ++ * Changes to trie node or other data are always made so that it and ++ * all pointers in and to it remain valid for a time. Old versions are ++ * eventually discarded. ++ * ++ * Dnsrpzd periodically defines a new version by setting asside all changes ++ * made since the previous version was defined. Subsequent changes ++ * made (only!) by dnsrpzd will be part of the next version. ++ * ++ * To discard an old version, dnsrpzd must know that all clients have stopped ++ * using that version. Clients do that by using part of the mapped file ++ * to tell dnsrpzd the oldest version that each client is using. ++ * Dnsrpzd assigns each connecting client an entry in the cversions array ++ * in the mapped file. The client puts version numbers into that entry ++ * to signal to dnsrpzd which versions that can be discarded. ++ * Dnsrpzd is free, as far as that client is concerned, to discard all ++ * numerically smaller versions. A client can disclaim all versions with ++ * the version number VERSIONS_ALL or 0. ++ * ++ * The race between a client changing its entry and dnsrpzd discarding a ++ * version is resolved by allowing dnsrpzd to discard all versions ++ * smaller or equal to the client's version number. If dnsrpzd is in ++ * the midst of discarding or about to discard version N when the ++ * client asserts N, no harm is done. The client depends only on ++ * the consistency of version N+1. ++ * ++ * This version mechanism depends in part on not being exercised too frequently ++ * Version numbers are 32 bits long and dnsrpzd creates new versions ++ * at most once every 30 seconds. ++ */ ++ ++ ++/* ++ * Lock functions for concurrent use of a single librpz_client_t client handle. ++ */ ++typedef void(librpz_mutex_t)(void *mutex); ++ ++/* ++ * List of connections to dnsrpzd daemons. ++ */ ++typedef struct librpz_clist librpz_clist_t; ++ ++/* ++ * Client's handle on dnsrpzd. ++ */ ++typedef struct librpz_client librpz_client_t; ++ ++/** ++ * Create the list of connections to the dnsrpzd daemon. ++ * @param[out] emsg: error message ++ * @param lock: start exclusive access to the client handle ++ * @param unlock: end exclusive access to the client handle ++ * @param mutex_destroy: release the lock ++ * @param mutex: pointer to the lock for the client handle ++ * @param log_ctx: NULL or resolver's context log messages ++ */ ++typedef librpz_clist_t *(librpz_clist_create_t)(librpz_emsg_t *emsg, ++ librpz_mutex_t *lock, ++ librpz_mutex_t *unlock, ++ librpz_mutex_t *mutex_destroy, ++ void *mutex, void *log_ctx); ++LIBDEF_F(clist_create) ++ ++ ++/** ++ * Release the list of dnsrpzd connections. ++ */ ++typedef void (librpz_clist_detach_t)(librpz_clist_t **clistp); ++LIBDEF_F(clist_detach) ++ ++/** ++ * Create a librpz client handle. ++ * @param[out] emsg: error message ++ * @param: list of dnsrpzd connections ++ * @param cstr: string of configuration settings separated by ';' or '\n' ++ * @param use_expired: true to not ignore expired zones ++ * @return client handle or NULL if the handle could not be created ++ */ ++typedef librpz_client_t *(librpz_client_create_t)(librpz_emsg_t *emsg, ++ librpz_clist_t *clist, ++ const char *cstr, ++ bool use_expired); ++LIBDEF_F(client_create) ++ ++/** ++ * Start (if necessary) dnsrpzd and connect to it. ++ * @param[out] emsg: error message ++ * @param client handle ++ * @param optional: true if it is ok if starting the daemon is not allowed ++ */ ++typedef bool (librpz_connect_t)(librpz_emsg_t *emsg, librpz_client_t *client, ++ bool optional); ++LIBDEF_F(connect) ++ ++/** ++ * Start to destroy a librpz client handle. ++ * It will not be destroyed until the last set of RPZ queries represented ++ * by a librpz_rsp_t ends. ++ * @param client handle to be released ++ * @return false on error ++ */ ++typedef void (librpz_client_detach_t)(librpz_client_t **clientp); ++LIBDEF_F(client_detach) ++ ++/** ++ * State for a set of RPZ queries for a single DNS response ++ * or for listing the database. ++ */ ++typedef struct librpz_rsp librpz_rsp_t; ++ ++/** ++ * Start a set of RPZ queries for a single DNS response. ++ * @param[out] emsg: error message for false return or *rspp=NULL ++ * @param[out] rspp created context or NULL ++ * @param[out] min_ns_dotsp: NULL or pointer to configured MIN-NS-DOTS value ++ * @param client state ++ * @param have_rd: RD=1 in the DNS request ++ * @param have_do: DO=1 in the DNS request ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_create_t)(librpz_emsg_t *emsg, librpz_rsp_t **rspp, ++ int *min_ns_dotsp, librpz_client_t *client, ++ bool have_rd, bool have_do); ++LIBDEF_F(rsp_create) ++ ++/** ++ * Finish RPZ work for a DNS response. ++ */ ++typedef void (librpz_rsp_detach_t)(librpz_rsp_t **rspp); ++LIBDEF_F(rsp_detach) ++ ++/** ++ * Get the final, accumulated result of a set of RPZ queries. ++ * Yield LIBRPZ_POLICY_UNDEFINED if ++ * - there were no hits, ++ * - there was a dispositive hit, be we have not recursed and are required ++ * to recurse so that evil DNS authories will not know we are using RPZ ++ * - we have a hit and have recursed, but later data such as NSIP could ++ * override ++ * @param[out] emsg ++ * @param[out] result describes the hit ++ * or result->policy=LIBRPZ_POLICY_UNDEFINED without a hit ++ * @param[out] result: current policy rewrite values ++ * @param recursed: recursion has now been done even if it was not done ++ * when the hit was found ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_result_t)(librpz_emsg_t *emsg, librpz_result_t *result, ++ bool recursed, const librpz_rsp_t *rsp); ++LIBDEF_F(rsp_result) ++ ++/** ++ * Might looking for a trigger be worthwhile? ++ * @param trig: look for this type of trigger ++ * @param ipv6: true if trig is LIBRPZ_TRIG_CLIENT_IP, LIBRPZ_TRIG_IP, ++ * or LIBRPZ_TRIG_NSIP and the IP address is IPv6 ++ * @return: true if looking could be worthwhile ++ */ ++typedef bool (librpz_have_trig_t)(librpz_trig_t trig, bool ipv6, ++ const librpz_rsp_t *rsp); ++LIBDEF_F(have_trig) ++ ++/** ++ * Might looking for NSDNAME and NSIP triggers be worthwhile? ++ * @return: true if looking could be worthwhile ++ */ ++typedef bool (librpz_have_ns_trig_t)(const librpz_rsp_t *rsp); ++LIBDEF_F(have_ns_trig) ++ ++/** ++ * Convert the found client IP trie key to a CIDR block ++ * @param[out] emsg ++ * @param[out] prefix trigger ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_clientip_prefix_t)(librpz_emsg_t *emsg, ++ librpz_prefix_t *prefix, ++ librpz_rsp_t *rsp); ++LIBDEF_F(rsp_clientip_prefix) ++ ++/** ++ * Compute the owner name of the found or result trie key, usually to log it. ++ * An IP address key might be returned as 8.0.0.0.127.rpz-client-ip. ++ * example.com. might be a qname trigger. example.com.rpz-nsdname. could ++ * be an NSDNAME trigger. ++ * @param[out] emsg ++ * @param[out] owner domain ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_domain_t)(librpz_emsg_t *emsg, ++ librpz_domain_buf_t *owner, ++ librpz_rsp_t *rsp); ++LIBDEF_F(rsp_domain) ++ ++/** ++ * Get the next RR of the LIBRPZ_POLICY_RECORD result after an initial use of ++ * librpz_rsp_result() or librpz_itr_node() or after a previous use of ++ * librpz_rsp_rr(). The RR is in uncompressed wire format including type, ++ * class, ttl and length in network byte order. ++ * @param[out] emsg ++ * @param[out] typep: optional host byte order record type or ns_t_invalid (0) ++ * @param[out] classp: class such as ns_c_in ++ * @param[out] ttlp: TTL ++ * @param[out] rrp: optionall malloc() buffer containting the next RR or ++ * NULL after the last RR ++ * @param[out] result: current policy rewrite values ++ * @param qname: used construct a wildcard CNAME ++ * @param qname_size ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_rr_t)(librpz_emsg_t *emsg, uint16_t *typep, ++ uint16_t *classp, uint32_t *ttlp, ++ librpz_rr_t **rrp, librpz_result_t *result, ++ const uint8_t *qname, size_t qname_size, ++ librpz_rsp_t *rsp); ++LIBDEF_F(rsp_rr) ++ ++/** ++ * Get the next RR of the LIBRPZ_POLICY_RECORD result. ++ * @param[out] emsg ++ * @param[out] ttlp: TTL ++ * @param[out] rrp: malloc() buffer with SOA RR without owner name ++ * @param[out] result: current policy rewrite values ++ * @param[out] origin: SOA owner name ++ * @param[out] origin_size ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_soa_t)(librpz_emsg_t *emsg, uint32_t *ttlp, ++ librpz_rr_t **rrp, librpz_domain_buf_t *origin, ++ librpz_result_t *result, librpz_rsp_t *rsp); ++LIBDEF_F(rsp_soa) ++ ++/** ++ * Get the SOA serial number for a policy zone to compare with a known value ++ * to check whether a zone tranfer is complete. ++ */ ++typedef bool (librpz_soa_serial_t)(librpz_emsg_t *emsg, uint32_t *serialp, ++ const char *domain_nm, librpz_rsp_t *rsp); ++LIBDEF_F(soa_serial) ++ ++/** ++ * Save the current policy checking state. ++ * @param[out] emsg ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_push_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp); ++LIBDEF_F(rsp_push) ++#define LIBRPZ_RSP_STACK_DEPTH 3 ++ ++/** ++ * Restore the previous policy checking state. ++ * @param[out] emsg ++ * @param[out] result: NULL or restored policy rewrite values ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_pop_t)(librpz_emsg_t *emsg, librpz_result_t *result, ++ librpz_rsp_t *rsp); ++LIBDEF_F(rsp_pop) ++ ++/** ++ * Discard the most recently save policy checking state. ++ * @param[out] emsg ++ * @param[out] result: NULL or restored policy rewrite values ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_pop_discard_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp); ++LIBDEF_F(rsp_pop_discard) ++ ++/** ++ * Disable a zone. ++ * @param[out] emsg ++ * @param znum ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_rsp_forget_zone_t)(librpz_emsg_t *emsg, ++ librpz_cznum_t znum, librpz_rsp_t *rsp); ++LIBDEF_F(rsp_forget_zone) ++ ++/** ++ * Apply RPZ to an IP address. ++ * @param[out] emsg ++ * @param addr: address to check ++ * @param ipv6: true for 16 byte IPv6 instead of 4 byte IPv4 ++ * @param trig LIBRPZ_TRIG_CLIENT_IP, LIBRPZ_TRIG_IP, or LIBRPZ_TRIG_NSIP ++ * @param hit_id: caller chosen ++ * @param recursed: recursion has been done ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_ck_ip_t)(librpz_emsg_t *emsg, ++ const void *addr, uint family, ++ librpz_trig_t trig, librpz_result_id_t hit_id, ++ bool recursed, librpz_rsp_t *rsp); ++LIBDEF_F(ck_ip) ++ ++/** ++ * Apply RPZ to a wire-format domain. ++ * @param[out] emsg ++ * @param domain in wire format ++ * @param domain_size ++ * @param trig LIBRPZ_TRIG_QNAME or LIBRPZ_TRIG_NSDNAME ++ * @param hit_id: caller chosen ++ * @param recursed: recursion has been done ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return false on error ++ */ ++typedef bool (librpz_ck_domain_t)(librpz_emsg_t *emsg, ++ const uint8_t *domain, size_t domain_size, ++ librpz_trig_t trig, librpz_result_id_t hit_id, ++ bool recursed, librpz_rsp_t *rsp); ++LIBDEF_F(ck_domain) ++ ++/** ++ * Ask dnsrpzd to refresh a zone. ++ * @param[out] emsg error message ++ * @param librpz_domain_t domain to refresh ++ * @param client context ++ * @return false after error ++ */ ++typedef bool (librpz_zone_refresh_t)(librpz_emsg_t *emsg, const char *domain, ++ librpz_rsp_t *rsp); ++LIBDEF_F(zone_refresh) ++ ++/** ++ * Get a string describing the the databasse ++ * @param license: include the license ++ * @param cfiles: include the configuration file names ++ * @param listens: include the local notify IP addresses ++ * @param[out] emsg error message if the result is null ++ * @param client context ++ * @return malloc'ed string or NULL after error ++ */ ++typedef char *(librpz_db_info_t)(librpz_emsg_t *emsg, ++ bool license, bool cfiles, bool listens, ++ librpz_rsp_t *rsp); ++LIBDEF_F(db_info) ++ ++/** ++ * Start a context for listing the nodes and/or zones in the mapped file ++ * @param[out] emsg: error message for false return or *rspp=NULL ++ * @param[out[ rspp created context or NULL ++ * @param client context ++ * @return false after error ++ */ ++typedef bool (librpz_itr_start_t)(librpz_emsg_t *emsg, librpz_rsp_t **rspp, ++ librpz_client_t *client); ++LIBDEF_F(itr_start) ++ ++/** ++ * Get mapped file memory allocation statistics. ++ * @param[out] emsg: error message ++ * @param rsp state from librpz_itr_start() ++ * @return malloc'ed string or NULL after error ++ */ ++typedef char *(librpz_mf_stats_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp); ++LIBDEF_F(mf_stats) ++ ++/** ++ * Get versions currently used by clients. ++ * @param[out] emsg: error message ++ * @param[in,out] rsp: state from librpz_itr_start() ++ * @return malloc'ed string or NULL after error ++ */ ++typedef char *(librpz_vers_stats_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp); ++LIBDEF_F(vers_stats) ++ ++/** ++ * Allocate a string describing the next zone or "" after the last zone. ++ * @param[out] emsg ++ * @param all_zones to list all instead of only requested zones ++ * @param[in,out] rsp state from librpz_rsp_start() ++ * @return malloc'ed string or NULL after error ++ */ ++typedef char *(librpz_itr_zone_t)(librpz_emsg_t *emsg, bool all_zones, ++ librpz_rsp_t *rsp); ++LIBDEF_F(itr_zone) ++ ++/** ++ * Describe the next trie node while dumping the database. ++ * @param[out] emsg ++ * @param[out] result describes node ++ * or result->policy=LIBRPZ_POLICY_UNDEFINED after the last node. ++ * @param all_zones to list all instead of only requested zones ++ * @param[in,out] rsp state from librpz_itr_start() ++ * @return: false on error ++ */ ++typedef bool (librpz_itr_node_t)(librpz_emsg_t *emsg, librpz_result_t *result, ++ bool all_zones, librpz_rsp_t *rsp); ++LIBDEF_F(itr_node) ++ ++/** ++ * RPZ policy to string with a backup buffer of POLICY2STR_SIZE size ++ */ ++typedef const char *(librpz_policy2str_t)(librpz_policy_t policy, ++ char *buf, size_t buf_size); ++#define POLICY2STR_SIZE sizeof("policy xxxxxx") ++LIBDEF_F(policy2str) ++ ++/** ++ * Trigger type to string. ++ */ ++typedef const char *(librpz_trig2str_t)(librpz_trig_t trig); ++LIBDEF_F(trig2str) ++ ++/** ++ * Convert a number of seconds to a zone file duration string ++ */ ++typedef const char *(librpz_secs2str_t)(time_t secs, ++ char *buf, size_t buf_size); ++#define SECS2STR_SIZE sizeof("1234567w7d24h59m59s") ++LIBDEF_F(secs2str) ++ ++/** ++ * Parse a duration with 's', 'm', 'h', 'd', and 'w' units. ++ */ ++typedef bool (librpz_str2secs_t)(librpz_emsg_t *emsg, time_t *val, ++ const char *str0); ++LIBDEF_F(str2secs) ++ ++/** ++ * Translate selected rtypes to strings ++ */ ++typedef const char *(librpz_rtype2str_t)(uint type, char *buf, size_t buf_size); ++#define RTYPE2STR_SIZE sizeof("type xxxxx") ++LIBDEF_F(rtype2str) ++ ++/** ++ * Local version of ns_name_ntop() for portability. ++ */ ++typedef int (librpz_domain_ntop_t)(const u_char *src, char *dst, size_t dstsiz); ++LIBDEF_F(domain_ntop) ++ ++/** ++ * Local version of ns_name_pton(). ++ */ ++typedef int (librpz_domain_pton2_t)(const char *src, u_char *dst, size_t dstsiz, ++ size_t *dstlen, bool lower); ++LIBDEF_F(domain_pton2) ++ ++typedef union socku socku_t; ++typedef socku_t *(librpz_mk_inet_su_t)(socku_t *su, const struct in_addr *addrp, ++ in_port_t port); ++LIBDEF_F(mk_inet_su) ++ ++typedef socku_t *(librpz_mk_inet6_su_t)(socku_t *su, const ++ struct in6_addr *addrp, ++ uint32_t scope_id, in_port_t port); ++LIBDEF_F(mk_inet6_su) ++ ++typedef bool (librpz_str2su_t)(socku_t *sup, const char *str); ++LIBDEF_F(str2su) ++ ++typedef char *(librpz_su2str_t)(char *str, size_t str_len, const socku_t *su); ++LIBDEF_F(su2str) ++#define SU2STR_SIZE (INET6_ADDRSTRLEN+1+6+1) ++ ++ ++/** ++ * default path to dnsrpzd ++ */ ++const char *librpz_dnsrpzd_path; ++ ++ ++#undef LIBDEF ++ ++/* ++ * This is the dlopen() interface to librpz. ++ */ ++typedef const struct { ++ const char *dnsrpzd_path; ++ const char *version; ++ librpz_parse_log_opt_t *parse_log_opt; ++ librpz_log_level_val_t *log_level_val; ++ librpz_set_log_t *set_log; ++ librpz_vpemsg_t *vpemsg; ++ librpz_pemsg_t *pemsg; ++ librpz_vlog_t *vlog; ++ librpz_log_t *log; ++ librpz_fatal_t *fatal LIBRPZ_NORET; ++ librpz_rpz_assert_t *rpz_assert LIBRPZ_NORET; ++ librpz_rpz_vassert_t *rpz_vassert LIBRPZ_NORET; ++ librpz_clist_create_t *clist_create; ++ librpz_clist_detach_t *clist_detach; ++ librpz_client_create_t *client_create; ++ librpz_connect_t *connect; ++ librpz_client_detach_t *client_detach; ++ librpz_rsp_create_t *rsp_create; ++ librpz_rsp_detach_t *rsp_detach; ++ librpz_rsp_result_t *rsp_result; ++ librpz_have_trig_t *have_trig; ++ librpz_have_ns_trig_t *have_ns_trig; ++ librpz_rsp_clientip_prefix_t *rsp_clientip_prefix; ++ librpz_rsp_domain_t *rsp_domain; ++ librpz_rsp_rr_t *rsp_rr; ++ librpz_rsp_soa_t *rsp_soa; ++ librpz_soa_serial_t *soa_serial; ++ librpz_rsp_push_t *rsp_push; ++ librpz_rsp_pop_t *rsp_pop; ++ librpz_rsp_pop_discard_t *rsp_pop_discard; ++ librpz_rsp_forget_zone_t *rsp_forget_zone; ++ librpz_ck_ip_t *ck_ip; ++ librpz_ck_domain_t *ck_domain; ++ librpz_zone_refresh_t *zone_refresh; ++ librpz_db_info_t *db_info; ++ librpz_itr_start_t *itr_start; ++ librpz_mf_stats_t *mf_stats; ++ librpz_vers_stats_t *vers_stats; ++ librpz_itr_zone_t *itr_zone; ++ librpz_itr_node_t *itr_node; ++ librpz_policy2str_t *policy2str; ++ librpz_trig2str_t *trig2str; ++ librpz_secs2str_t *secs2str; ++ librpz_str2secs_t *str2secs; ++ librpz_rtype2str_t *rtype2str; ++ librpz_domain_ntop_t *domain_ntop; ++ librpz_domain_pton2_t *domain_pton2; ++ librpz_mk_inet_su_t *mk_inet_su; ++ librpz_mk_inet6_su_t *mk_inet6_su; ++ librpz_str2su_t *str2su; ++ librpz_su2str_t *su2str; ++} librpz_0_t; ++extern librpz_0_t librpz_def_0; ++ ++/* ++ * Future versions can be upward compatible by defining LIBRPZ_DEF as ++ * librpz_X_t. ++ */ ++#define LIBRPZ_DEF librpz_def_0 ++#define LIBRPZ_DEF_STR "librpz_def_0" ++ ++typedef librpz_0_t librpz_t; ++extern librpz_t *librpz; ++ ++ ++#if LIBRPZ_LIB_OPEN == 2 ++#include ++ ++/** ++ * link-load librpz ++ * @param[out] emsg: error message ++ * @param[in,out] dl_handle: NULL or pointer to new dlopen handle ++ * @param[in] path: librpz.so path ++ * @return address of interface structure or NULL on failure ++ */ ++static inline librpz_t * ++librpz_lib_open(librpz_emsg_t *emsg, void **dl_handle, const char *path) ++{ ++ void *handle; ++ librpz_t *new_librpz; ++ ++ emsg->c[0] = '\0'; ++ ++ /* ++ * Close a previously opened handle on librpz.so. ++ */ ++ if (dl_handle != NULL && *dl_handle != NULL) { ++ if (dlclose(*dl_handle) != 0) { ++ snprintf(emsg->c, sizeof(librpz_emsg_t), ++ "dlopen(NULL): %s", dlerror()); ++ return (NULL); ++ } ++ *dl_handle = NULL; ++ } ++ ++ /* ++ * First try the main executable of the process in case it was ++ * linked to librpz. ++ * Do not worry if we cannot search the main executable of the process. ++ */ ++ handle = dlopen(NULL, RTLD_NOW | RTLD_LOCAL); ++ if (handle != NULL) { ++ new_librpz = dlsym(handle, LIBRPZ_DEF_STR); ++ if (new_librpz != NULL) { ++ if (dl_handle != NULL) ++ *dl_handle = handle; ++ return (new_librpz); ++ } ++ if (dlclose(handle) != 0) { ++ snprintf(emsg->c, sizeof(librpz_emsg_t), ++ "dlsym(NULL, "LIBRPZ_DEF_STR"): %s", ++ dlerror()); ++ return (NULL); ++ } ++ } ++ ++ if (path == NULL || path[0] == '\0') { ++ snprintf(emsg->c, sizeof(librpz_emsg_t), ++ "librpz not linked and no dlopen() path provided"); ++ return (NULL); ++ } ++ ++ handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); ++ if (handle == NULL) { ++ snprintf(emsg->c, sizeof(librpz_emsg_t), "dlopen(%s): %s", ++ path, dlerror()); ++ return (NULL); ++ } ++ new_librpz = dlsym(handle, LIBRPZ_DEF_STR); ++ if (new_librpz != NULL) { ++ if (dl_handle != NULL) ++ *dl_handle = handle; ++ return (new_librpz); ++ } ++ snprintf(emsg->c, sizeof(librpz_emsg_t), ++ "dlsym(%s, "LIBRPZ_DEF_STR"): %s", ++ path, dlerror()); ++ dlclose(handle); ++ return (NULL); ++} ++ ++#elif defined(LIBRPZ_LIB_OPEN) ++ ++/* ++ * Statically link to the librpz.so DSO on systems without dlopen() ++ */ ++static inline librpz_t * ++librpz_lib_open(librpz_emsg_t *emsg, void **dl_handle, const char *path) ++{ ++ (void)(path); ++ ++ if (dl_handle != NULL) ++ *dl_handle = NULL; ++ ++#if LIBRPZ_LIB_OPEN == 1 ++ emsg->c[0] = '\0'; ++ return (&LIBRPZ_DEF); ++#else ++ snprintf(emsg->c, sizeof(librpz_emsg_t), ++ "librpz not available via ./configure"); ++ return (NULL); ++#endif /* LIBRPZ_LIB_OPEN */ ++} ++#endif /* LIBRPZ_LIB_OPEN */ ++ ++#endif /* LIBRPZ_H */ +diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c +new file mode 100644 +index 00000000..c5ab7801 +--- /dev/null ++++ b/fastrpz/rpz.c +@@ -0,0 +1,1352 @@ ++/* ++ * fastrpz/rpz.c - interface to the fastrpz response policy zone library ++ * ++ * Optimize no-rewrite cases for speed but optimize rewriting for ++ * simplicity and size. ++ */ ++ ++#include "config.h" ++ ++#ifdef ENABLE_FASTRPZ ++#include "daemon/daemon.h" ++#define LIBRPZ_LIB_OPEN FASTRPZ_LIB_OPEN ++#include "fastrpz/rpz.h" ++#include "daemon/worker.h" ++#include "iterator/iter_delegpt.h" ++#include "iterator/iter_utils.h" ++#include "iterator/iterator.h" ++#include "util/data/dname.h" ++#include "util/data/msgencode.h" ++#include "util/data/msgparse.h" ++#include "util/data/msgreply.h" ++#include "util/log.h" ++#include "util/netevent.h" ++#include "util/net_help.h" ++#include "util/regional.h" ++#include "util/storage/slabhash.h" ++#include "services/cache/dns.h" ++#include "services/cache/rrset.h" ++#include "services/mesh.h" ++#include "sldns/sbuffer.h" ++#include "sldns/rrdef.h" ++ ++ ++typedef enum state { ++ /* No more rewriting */ ++ st_off = 1, ++ /* Send SERVFAIL */ ++ st_servfail, ++ /* No dispositive hit yet */ ++ st_unknown, ++ /* Let the iterator resolve a CNAME or get a delegation point. */ ++ st_iterate, ++ /* Let the iterator resolve NS to check NSIP or NSDNAME triggers. */ ++ st_ck_ns, ++ /* We have an answer */ ++ st_rewritten, ++} st_t; ++ ++ ++/* RPZ state pointed to by struct comm_reply */ ++typedef struct commreply_rpz { ++ /* librpz state */ ++ librpz_rsp_t* rsp; ++ /* ID for log messages */ ++ int log_id; ++ ++ /* from configuration */ ++ int min_ns_dots; ++ ++ /* Running in the iterator */ ++ bool iterating; ++ ++ /* current and previous state and librpz result */ ++ st_t st; ++ st_t saved_st[LIBRPZ_RSP_STACK_DEPTH-1]; ++ librpz_result_t result; ++ ++ /* Stop adding CNAMEs to the prepend list before this owner name. */ ++ librpz_domain_buf_t cname_hit; ++ /* It is not the first CNAME */ ++ bool cname_hit_2nd; ++ librpz_result_id_t hit_id; ++} commreply_rpz_t; ++ ++ ++/* Generate an ID for log messages. */ ++static int log_id; ++ ++librpz_t *librpz; ++ ++ ++static void LIBRPZ_NORET ++rpz_assert(const char *s) ++{ ++ fatal_exit("%s", s); ++ exit(1); ++} ++#define RPZ_ASSERT(c) ((c) ? (void)0 : rpz_assert(#c), (void)0) ++ ++/* ++ * librpz client handle locking ++ */ ++static void ++lock_destroy(void* mutex) ++{ ++ lock_basic_destroy(mutex); ++ free(mutex); ++} ++ ++static void ++lock(void* mutex) ++{ ++ lock_basic_lock(mutex); ++} ++ ++static void ++unlock(void* mutex) ++{ ++ lock_basic_unlock(mutex); ++} ++ ++ ++static void ++log_fnc(librpz_log_level_t level, void* ATTR_UNUSED(ctx), const char* buf) ++{ ++ /* Setting librpz_log_level overrides the unbound "verbose" level. */ ++ if(level > LIBRPZ_LOG_TRACE1 && ++ level <= librpz->log_level_val(LIBRPZ_LOG_INVALID)) ++ level = LIBRPZ_LOG_TRACE1; ++ ++ switch(level) { ++ case LIBRPZ_LOG_FATAL: ++ case LIBRPZ_LOG_ERROR: /* errors */ ++ default: ++ log_err("rpz: %s", buf); ++ break; ++ ++ case LIBRPZ_LOG_TRACE1: /* big events such as dnsrpzd starts */ ++ verbose(VERB_OPS, "rpz: %s", buf); ++ break; ++ ++ case LIBRPZ_LOG_TRACE2: /* smaller dnsrpzd zone transfers */ ++ verbose(VERB_DETAIL, "rpz: %s", buf); ++ break; ++ ++ case LIBRPZ_LOG_TRACE3: /* librpz hits */ ++ verbose(VERB_QUERY, "rpz: %s", buf); ++ break; ++ ++ case LIBRPZ_LOG_TRACE4: /* librpz lookups */ ++ verbose(VERB_CLIENT, "rpz: %s", buf); ++ break; ++ } ++} ++ ++ ++/* Release the librpz version. */ ++static void ++rpz_off(commreply_rpz_t* rpz, st_t st) ++{ ++ if(!rpz) ++ return; ++ rpz->st = st; ++ librpz->rsp_detach(&rpz->rsp); ++} ++ ++ ++static void LIBRPZ_PF(2,3) ++log_fail(commreply_rpz_t* rpz, const char* p, ...) ++{ ++ va_list args; ++ ++ if(rpz->st == st_servfail) ++ return; ++ ++ va_start(args, p); ++ librpz->vlog(LIBRPZ_LOG_ERROR, rpz, p, args); ++ va_end(args); ++ if(!rpz) ++ return; ++ rpz_off(rpz, st_servfail); ++} ++ ++ ++/* Announce a rewrite. */ ++static void ++log_rewrite(uint8_t* qname, librpz_policy_t policy, const char* msg, ++ commreply_rpz_t* rpz) ++{ ++ char policy_buf[POLICY2STR_SIZE]; ++ char qname_nm[LDNS_MAX_DOMAINLEN+1]; ++ librpz_domain_buf_t tdomain; ++ char tdomain_nm[LDNS_MAX_DOMAINLEN+1]; ++ librpz_emsg_t emsg; ++ ++ if(rpz->st == st_servfail || !rpz->result.log) ++ return; ++ if(librpz->log_level_val(LIBRPZ_LOG_INVALID) < LIBRPZ_LOG_TRACE1) ++ return; ++ ++ dname_str(qname, qname_nm); ++ ++ if(!librpz->rsp_domain(&emsg, &tdomain, rpz->rsp)) { ++ librpz->log(LIBRPZ_LOG_ERROR, rpz, "%s", emsg.c); ++ return; ++ } ++ dname_str(tdomain.d, tdomain_nm); ++ ++ librpz->log(LIBRPZ_LOG_TRACE3, rpz, "%srewriting %s via %s %s to %s", ++ msg, qname_nm, tdomain_nm, ++ librpz->trig2str(rpz->result.trig), ++ librpz->policy2str(policy, policy_buf, ++ sizeof(policy_buf))); ++} ++ ++ ++/* Connect to and start dnsrpzd if necessary for the unbound daemon. ++ * Require "rpz-conf: path" to specify the rpz configuration file. ++ * The unbound server directory name is the default rpz working ++ * directory. If unbound uses chroot, then the dnsrpzd working ++ * directory must be in the chroot tree. ++ * The database and socket are closed and re-opened. ++ */ ++void ++rpz_init(librpz_clist_t** pclist, librpz_client_t** pclient, ++ const struct config_file* cfg) ++{ ++ lock_basic_type* mutex; ++ librpz_emsg_t emsg; ++ ++ if(!librpz) { ++ librpz = librpz_lib_open(&emsg, NULL, FASTRPZ_LIBRPZ_PATH); ++ if(!librpz) ++ fatal_exit("rpz: %s", emsg.c); ++ } ++ ++ librpz->set_log(&log_fnc, NULL); ++ ++ if(!cfg->rpz_cstr) ++ fatal_exit("rpz: rpz-zone: not set"); ++ ++ librpz->client_detach(pclient); ++ librpz->clist_detach(pclist); ++ ++ mutex = malloc(sizeof(*mutex)); ++ if(!mutex) ++ fatal_exit("rpz: no memory for lock"); ++ lock_basic_init(mutex); ++ ++ *pclist = librpz->clist_create(&emsg, &lock, &unlock, &lock_destroy, ++ mutex, NULL); ++ if(!pclist) ++ fatal_exit("rpz: %s", emsg.c); ++ ++ *pclient = librpz->client_create(&emsg, *pclist, cfg->rpz_cstr, false); ++ if(!*pclient) ++ fatal_exit("rpz: %s", emsg.c); ++ ++ if(!librpz->connect(&emsg, *pclient, true)) ++ fatal_exit("rpz: %s", emsg.c); ++ ++ verbose(VERB_OPS, "rpz: librpz version %s", librpz->version); ++} ++ ++ ++/* Stop using librpz on behalf of a worker thread. */ ++void ++rpz_delete(librpz_clist_t** pclist, librpz_client_t** pclient) ++{ ++ if(librpz) { ++ librpz->client_detach(pclient); ++ librpz->clist_detach(pclist); ++ } ++} ++ ++ ++/* Release the librpz resources held for a DNS client request. */ ++void ++rpz_end(struct comm_reply* commreply) ++{ ++ if(!commreply->rpz) ++ return; ++ rpz_off(commreply->rpz, commreply->rpz->st); ++ free(commreply->rpz); ++ commreply->rpz = NULL; ++} ++ ++ ++static bool ++push_st(commreply_rpz_t* rpz) ++{ ++ librpz_emsg_t emsg; ++ ++ if(rpz->st == st_off || rpz->st == st_servfail) { ++ librpz->log(LIBRPZ_LOG_ERROR, rpz, ++ "state %d in push_st()", rpz->st); ++ return false; ++ } ++ if(!librpz->rsp_push(&emsg, rpz->rsp)) ++ log_fail(rpz, "%s", emsg.c); ++ memmove(&rpz->saved_st[1], &rpz->saved_st[0], ++ sizeof(rpz->saved_st) - sizeof(rpz->saved_st[0])); ++ rpz->saved_st[0] = rpz->st; ++ return rpz->st != st_servfail; ++} ++ ++ ++static bool ++pop_st(commreply_rpz_t* rpz) ++{ ++ librpz_emsg_t emsg; ++ ++ if(rpz->rsp && !librpz->rsp_pop(&emsg, &rpz->result, rpz->rsp)) ++ log_fail(rpz, "%s", emsg.c); ++ if(rpz->st != st_servfail) ++ rpz->st = rpz->saved_st[0]; ++ memmove(&rpz->saved_st[0], &rpz->saved_st[1], ++ sizeof(rpz->saved_st) - sizeof(rpz->saved_st[0])); ++ return rpz->st != st_servfail; ++} ++ ++static bool ++pop_discard_st(commreply_rpz_t* rpz) ++{ ++ librpz_emsg_t emsg; ++ ++ if(rpz->rsp && !librpz->rsp_pop_discard(&emsg, rpz->rsp)) ++ log_fail(rpz, "%s", emsg.c); ++ memmove(&rpz->saved_st[0], &rpz->saved_st[1], ++ sizeof(rpz->saved_st) - sizeof(rpz->saved_st[0])); ++ return rpz->st != st_servfail; ++} ++ ++/* Check a rewrite attempt for errors and a disabled zone. */ ++static bool /* true=repeat the check */ ++ck_after(uint8_t* qname, bool recursed, librpz_trig_t trig, ++ commreply_rpz_t* rpz) ++{ ++ librpz_emsg_t emsg; ++ ++ if(rpz->st == st_servfail) ++ return false; ++ ++ if(!librpz->rsp_result(&emsg, &rpz->result, recursed, rpz->rsp)) { ++ log_fail(rpz, "%s", emsg.c); ++ return false; ++ } ++ ++ if(rpz->result.policy == LIBRPZ_POLICY_DISABLED) { ++ /* Log the hit on the disabled zone, do not try the zone again, ++ * and restore the state from before the check to forget the hit ++ * before trying again. */ ++ log_rewrite(qname, rpz->result.zpolicy, "disabled ", rpz); ++ if(!librpz->rsp_forget_zone(&emsg, rpz->result.cznum, rpz->rsp)) ++ log_fail(rpz, "%s", emsg.c); ++ return pop_st(rpz); ++ } ++ ++ /* Complain about and forget client-IP address hit that is not ++ * dispositive. Client-IP triggers have the highest priority ++ * within a policy zone, but can be overridden by any hit in a policy ++ * earlier in the client's (resolver's) list of zones, including ++ * policies that cannot be hit until after recursion. If we allowed ++ * client-IP triggers in secondary zones, then than two DNS requests ++ * that differ only in DNS client-IP addresses could properly ++ * have differing results. The Unbound iterator treats identical ++ * DNS requests the same regardless of DNS client-IP address. ++ * struct query_info would need to be modified to have an optional ++ * librpz_prefix_t containing the prefix of the client-IP address hit ++ * from librpz->rsp_clientip_prefix(). Adding to struct query_info ++ * would require finding and changing the many and obscure places ++ * including the Unbound tests to memset(0) the struct query_info ++ * that they create. */ ++ if(trig == LIBRPZ_TRIG_CLIENT_IP) { ++ if(rpz->result.cznum != 0) { ++ log_rewrite(qname, rpz->result.policy, ++ "ignore secondary ", rpz); ++ if(!pop_st(rpz)) ++ log_fail(rpz, "%s", emsg.c); ++ return (false); ++ } ++ } ++ ++ /* Forget the state from before the check and keep the new state ++ * if we do not have a hit on a disabled policy zone. */ ++ pop_discard_st(rpz); ++ return false; ++} ++ ++ ++/* Get the next RR from the policy record. */ ++static bool ++next_rr(librpz_rr_t** rrp, const uint8_t* qname, size_t qname_len, ++ commreply_rpz_t* rpz) ++{ ++ librpz_emsg_t emsg; ++ ++ if(!librpz->rsp_rr(&emsg, NULL, NULL, NULL, rrp, &rpz->result, ++ qname, qname_len, rpz->rsp)) { ++ log_fail(rpz, "%s", emsg.c); ++ *rrp = NULL; ++ return false; ++ } ++ return true; ++} ++ ++ ++static bool /* false=fatal error to be logged */ ++add_rr(struct sldns_buffer* pkt, const uint8_t* owner, size_t owner_len, ++ librpz_rr_t* rr, commreply_rpz_t* rpz) ++{ ++ size_t rdlength; ++ ++ rdlength = ntohs(rr->rdlength); ++ ++ if(!sldns_buffer_available(pkt, owner_len + 10 + rdlength)) { ++ log_fail(rpz, "comm_reply buffer exhausted"); ++ free(rr); ++ return false; ++ } ++ sldns_buffer_write(pkt, owner, owner_len); ++ /* sizeof(librpz_rr_t)=12 instead of 10 */ ++ sldns_buffer_write(pkt, rr, 10 + rdlength); ++ return true; ++} ++ ++ ++/* Convert a fake incoming DNS message to an Unbound struct dns_msg */ ++static void ++pkt2dns_msg(struct dns_msg** dnsmsg, struct sldns_buffer* pkt, ++ commreply_rpz_t* rpz, struct regional* region) ++{ ++ struct msg_parse* msgparse; ++ ++ msgparse = regional_alloc(region, sizeof(*msgparse)); ++ if(!msgparse) { ++ log_fail(rpz, "out of memory for msgparse"); ++ *dnsmsg = NULL; ++ return; ++ } ++ memset(msgparse, 0, sizeof(*msgparse)); ++ if(parse_packet(pkt, msgparse, region) != LDNS_RCODE_NOERROR) { ++ log_fail(rpz, "packet parse error"); ++ *dnsmsg = NULL; ++ return; ++ } ++ *dnsmsg = dns_alloc_msg(pkt, msgparse, region); ++ if(!*dnsmsg) { ++ log_fail(rpz, "dns_alloc_msg() failed"); ++ *dnsmsg = NULL; ++ return; ++ } ++ (*dnsmsg)->rep->security = sec_status_rpz_rewritten; ++} ++ ++ ++static bool /* false=SERVFAIL */ ++ck_ip_rrset(const void* vdata, int family, librpz_trig_t trig, ++ uint8_t* qname, commreply_rpz_t* rpz) ++{ ++ const struct packed_rrset_data* data; ++ uint rr_n; ++ size_t len; ++ librpz_emsg_t emsg; ++ ++ data = vdata; ++ ++ /* Loop to ignore disabled zones. */ ++ do { ++ if(!push_st(rpz)) ++ return false; ++ for(rr_n = 0; rr_n < data->count; ++rr_n) { ++ len = data->rr_len[rr_n]; ++ /* Skip bogus including negative placeholding rdata. */ ++ if((family == AF_INET && ++ len != sizeof(struct in_addr)+2) || ++ (family == AF_INET6 && ++ len != sizeof(struct in6_addr)+2)) ++ continue; ++ if(!librpz->ck_ip(&emsg, data->rr_data[rr_n]+2, ++ family, trig, rpz->hit_id, true, ++ rpz->rsp)) { ++ log_fail(rpz, "%s", emsg.c); ++ return false; ++ } ++ } ++ } while(ck_after(qname, true, trig, rpz)); ++ return rpz->st != st_servfail; ++} ++ ++ ++static bool /* false=SERVFAIL */ ++ck_dname(uint8_t* dname, size_t dname_size, librpz_trig_t trig, ++ uint8_t* qname, bool recursed, commreply_rpz_t* rpz) ++{ ++ librpz_emsg_t emsg; ++ ++ /* Refuse to check the root. */ ++ if(dname_is_root(dname)) ++ return rpz->st != st_servfail; ++ ++ /* Loop to ignore disabled zones. */ ++ do { ++ if(!push_st(rpz)) ++ return false; ++ if(!librpz->ck_domain(&emsg, dname, dname_size, trig, ++ rpz->hit_id, recursed, rpz->rsp)) { ++ log_fail(rpz, "%s", emsg.c); ++ return false; ++ } ++ } while(ck_after(qname, recursed, trig, rpz)); ++ ++ return rpz->st != st_servfail; ++} ++ ++ ++/* Check the IPv4 or IPv6 addresses for one NS name. */ ++static bool /* false=st_servfail */ ++ck_1nsip(uint8_t* nsname, size_t nsname_size, int family, int qtype, ++ bool* have_ns, commreply_rpz_t* rpz, struct module_env* env) ++{ ++ struct ub_packed_rrset_key* akey; ++ ++ akey = rrset_cache_lookup(env->rrset_cache, nsname, nsname_size, ++ qtype, LDNS_RR_CLASS_IN, 0, 0, 0); ++ if(akey) { ++ *have_ns = true; ++ ++ if(!ck_ip_rrset(akey->entry.data, family, LIBRPZ_TRIG_NSIP, ++ nsname, rpz)) { ++ lock_rw_unlock(&akey->entry.lock); ++ return false; ++ } ++ lock_rw_unlock(&akey->entry.lock); ++ } ++ return true; ++} ++ ++ ++static bool /* false=st_servfail */ ++ck_qname(uint8_t* qname, size_t qname_len, ++ bool recursed, /* recursion done */ ++ bool wait_ns, /* willing to iterate for NS data */ ++ commreply_rpz_t* rpz, struct module_env* env) ++{ ++ uint8_t* dname; ++ size_t dname_size; ++ int cur_lab; ++ struct ub_packed_rrset_key* nskey; ++ const struct packed_rrset_data* nsdata; ++ uint8_t* nsname; ++ size_t nsname_size; ++ uint rr_n; ++ bool have_ns, tried_ns; ++ ++ if(!ck_dname(qname, qname_len, LIBRPZ_TRIG_QNAME, qname, false, rpz)) ++ return false; ++ ++ /* Do not waste time looking for NSDNAME and NSIP hits when there ++ * are no currently relevant triggers. */ ++ if(!librpz->have_ns_trig(rpz->rsp)) ++ return true; ++ ++ have_ns = false; ++ tried_ns = false; ++ dname = qname; ++ dname_size = qname_len; ++ for(cur_lab = dname_count_labels(dname) - 2; ++ cur_lab > rpz->min_ns_dots; ++ --cur_lab) { ++ tried_ns = true; ++ dname_remove_label(&dname, &dname_size); ++ nskey = rrset_cache_lookup(env->rrset_cache, dname, dname_size, ++ LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, ++ 0, 0, 0); ++ if(!nskey) ++ continue; ++ ++ nsdata = (const struct packed_rrset_data*)nskey->entry.data; ++ for(rr_n = 0; ++ rr_n < nsdata->count && rpz->st == st_unknown; ++ ++rr_n) { ++ nsname = nsdata->rr_data[rr_n]+2; ++ nsname_size = nsdata->rr_len[rr_n]; ++ if(nsname_size <= 2) ++ continue; ++ nsname_size -= 2; ++ if(!ck_dname(nsname, nsname_size, LIBRPZ_TRIG_NSDNAME, ++ qname, recursed, rpz)) ++ return false; ++ if(!ck_1nsip(nsname, nsname_size, AF_INET, ++ LDNS_RR_TYPE_A, &have_ns, rpz, env)) ++ return false; ++ if(!ck_1nsip(nsname, nsname_size, AF_INET6, ++ LDNS_RR_TYPE_AAAA, &have_ns, rpz, env)) ++ return false; ++ } ++ lock_rw_unlock(&nskey->entry.lock); ++ } ++ ++ /* If we failed to find NS records, then stop building the response ++ * before a CNAME with this owner name. */ ++ if(!have_ns && tried_ns && (!recursed || wait_ns)) { ++ rpz->cname_hit.size = qname_len; ++ RPZ_ASSERT(rpz->cname_hit.size <= sizeof(rpz->cname_hit.d)); ++ memcpy(rpz->cname_hit.d, qname, qname_len); ++ rpz->result.hit_id = rpz->hit_id; ++ rpz->st = st_ck_ns; ++ } ++ return true; ++} ++ ++ ++/* ++ * Are we ready to rewrite the response? ++ */ ++static bool /* true=send rewritten response */ ++ck_result(uint8_t* qname, bool recursed, ++ commreply_rpz_t* rpz, const struct comm_point* commpoint) ++{ ++ librpz_emsg_t emsg; ++ ++ switch(rpz->st) { ++ case st_off: ++ case st_servfail: ++ case st_rewritten: ++ return false; ++ case st_unknown: ++ break; ++ case st_iterate: ++ return false; ++ case st_ck_ns: ++ /* An NSDNAME or NSIP check failed for lack of cached data. */ ++ return false; ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_worker_cache()", ++ rpz->st); ++ } ++ ++ /* Wait for a trigger. */ ++ if(rpz->result.policy == LIBRPZ_POLICY_UNDEFINED) { ++ if(recursed && ++ rpz->result.zpolicy != LIBRPZ_POLICY_UNDEFINED && ++ !librpz->rsp_result(&emsg, &rpz->result, true, rpz->rsp)) { ++ log_fail(rpz, "%s", emsg.c); ++ return false; ++ } ++ if(rpz->result.policy == LIBRPZ_POLICY_UNDEFINED) ++ return false; ++ } ++ ++ if(rpz->result.policy == LIBRPZ_POLICY_PASSTHRU) { ++ log_rewrite(qname, rpz->result.policy, "", rpz); ++ rpz_off(rpz, st_off); ++ return false; ++ } ++ ++ /* The TCP-only policy answers UDP requests with truncated responses. */ ++ if(rpz->result.policy == LIBRPZ_POLICY_TCP_ONLY && ++ commpoint->type == comm_tcp) { ++ rpz_off(rpz, st_off); ++ return false; ++ } ++ ++ return true; ++} ++ ++ ++/* ++ * Convert an RPZ hit to a struct dns_msg ++ */ ++static void ++get_result_msg(struct dns_msg** dnsmsg, struct query_info* qinfo, ++ uint16_t id, uint16_t flags, bool recursed, commreply_rpz_t* rpz, ++ struct comm_point* commpoint, struct regional* region) ++{ ++ librpz_rr_t* rr; ++ librpz_domain_buf_t origin; ++ struct sldns_buffer* pkt; ++ uint16_t num_rrs; ++ librpz_emsg_t emsg; ++ ++ *dnsmsg = NULL; ++ if(!ck_result(qinfo->qname, recursed, rpz, commpoint)) ++ return; ++ ++ rpz->st = st_rewritten; ++ ++ if(rpz->result.policy == LIBRPZ_POLICY_DROP) { ++ log_rewrite(qinfo->qname, rpz->result.policy, "", rpz); ++ /* Make a fake cached message to carry ++ * sec_status_rpz_drop and be dropped. */ ++ error_encode(commpoint->buffer, LDNS_RCODE_NOERROR, ++ qinfo, id, flags, NULL); ++ pkt2dns_msg(dnsmsg, commpoint->buffer, rpz, region); ++ (*dnsmsg)->rep->security = sec_status_rpz_drop; ++ return; ++ } ++ ++ /* Create a DNS message of the RPZ data. ++ * In many cases that message could be sent directly to the DNS client, ++ * but sometimes iteration must be used to resolve a CNAME. ++ * This need not be fast, because rewriting responses should be rare. ++ * Therefore, use the simpler but slower tactic of generating a ++ * parsed version of the message. */ ++ ++ flags &= ~BIT_AA; ++ flags |= BIT_QR | BIT_RA; ++ rr = NULL; ++ ++ /* The TCP-only policy answers UDP requests with truncated responses. */ ++ if(rpz->result.policy == LIBRPZ_POLICY_TCP_ONLY) { ++ flags |= BIT_TC; ++ ++ } else if(rpz->result.policy == LIBRPZ_POLICY_NXDOMAIN) { ++ flags |= LDNS_RCODE_NXDOMAIN; ++ ++ } else if(rpz->result.policy == LIBRPZ_POLICY_CNAME) { ++ if(!rpz->iterating && ++ qinfo->qtype != LDNS_RR_TYPE_CNAME) { ++ /* The new DNS message would be a CNAME and ++ * the external request was not for a CNAME. ++ * The worker must punt to the iterator so that ++ * the iterator can resolve the CNAME. */ ++ rpz->st = st_iterate; ++ return; ++ } ++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz); ++ ++ } else if(rpz->result.policy == LIBRPZ_POLICY_RECORD || ++ rpz->result.policy == LIBRPZ_POLICY_NODATA) { ++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz); ++ /* Punt to the iterator if the new DNS message would ++ * be a CNAME that must be resolved. */ ++ if(!rpz->iterating && ++ qinfo->qtype != LDNS_RR_TYPE_CNAME && ++ rr && rr->type == ntohs(LDNS_RR_TYPE_CNAME)) { ++ free(rr); ++ rpz->st = st_iterate; ++ return; ++ } ++ } ++ log_rewrite(qinfo->qname, rpz->result.policy, "", rpz); ++ ++ /* Make a buffer containing a DNS message with the RPZ data. */ ++ pkt = commpoint->buffer; ++ sldns_buffer_clear(pkt); ++ if(sldns_buffer_remaining(pkt) < LDNS_HEADER_SIZE) { ++ log_fail(rpz, "comm_reply buffer too small for header"); ++ if(rr) ++ free(rr); ++ return; ++ } ++ ++ /* Install ID, flags, QDCOUNT=1, ANCOUNT=# of RPZ RRs, NSCOUNT=0, ++ * and ARCOUNT=1 for the RPZ SOA. */ ++ sldns_buffer_write_u16(pkt, id); ++ sldns_buffer_write_u16(pkt, flags); ++ sldns_buffer_write_u16(pkt, 1); /* QDCOUNT */ ++ sldns_buffer_write_u16(pkt, 0); /* ANCOUNT will be set later */ ++ sldns_buffer_write_u16(pkt, 0); /* NSCOUNT */ ++ sldns_buffer_write_u16(pkt, 1); /* ARCOUNT */ ++ ++ /* Install the question with the LDNS_RR_CLASS_RPZ bit to ++ * to distinguish this supposed cache entry from the real deal. */ ++ sldns_buffer_write(pkt, qinfo->qname, qinfo->qname_len); ++ sldns_buffer_write_u16(pkt, qinfo->qtype); ++ sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_IN); ++ ++ /* Install the RPZ RRs in the answer section */ ++ num_rrs = 0; ++ while(rr) { ++ /* Include only the requested RRs. */ ++ if(qinfo->qtype == LDNS_RR_TYPE_ANY || ++ rr->type == htons(qinfo->qtype) || ++ rr->type == htons(LDNS_RR_TYPE_CNAME)) { ++ if(!add_rr(pkt, qinfo->qname, qinfo->qname_len, ++ rr, rpz)) ++ return; ++ ++ ++num_rrs; ++ } ++ free(rr); ++ ++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz); ++ } ++ /* Finish ANCOUNT. */ ++ if(num_rrs != 0) ++ sldns_buffer_write_u16_at(pkt, 6, num_rrs); ++ ++ /* All rewritten responses have an identifying SOA record in the ++ * additional section. */ ++ if(!librpz->rsp_soa(&emsg, NULL, &rr, &origin, ++ &rpz->result, rpz->rsp)) { ++ log_fail(rpz, "no soa"); ++ return; ++ } ++ if(!add_rr(pkt, origin.d, origin.size, rr, rpz)) ++ return; ++ free(rr); ++ ++ /* Create a dns_msg representation of the fake incoming message. */ ++ sldns_buffer_flip(pkt); ++ pkt2dns_msg(dnsmsg, pkt, rpz, region); ++} ++ ++ ++/* Check the RRs in the ANSWER section of a reply_info. */ ++static void ++ck_reply(struct reply_info* reply, uint8_t* qname, bool wait_ns, ++ commreply_rpz_t* rpz, struct module_env* env) ++{ ++ struct ub_packed_rrset_key* rrset; ++ enum sldns_enum_rr_type type; ++ uint rrset_n; ++ ++ /* Check the RRs in the ANSWER section. */ ++ rpz->cname_hit.size = 0; ++ rpz->cname_hit_2nd = false; ++ for(rrset_n = 0; rrset_n < reply->an_numrrsets; ++rrset_n) { ++ /* Check all of the RRs before deciding. */ ++ if(rpz->st != st_unknown) ++ return; ++ ++ rrset = reply->rrsets[rrset_n]; ++ if(ntohs(rrset->rk.rrset_class) != LDNS_RR_CLASS_IN) ++ continue; ++ type = ntohs(rrset->rk.type); ++ ++ if(type == LDNS_RR_TYPE_A) { ++ if(!ck_ip_rrset(rrset->entry.data, AF_INET, ++ LIBRPZ_TRIG_IP, qname, rpz)) ++ break; ++ ++ } else if(type == LDNS_RR_TYPE_AAAA) { ++ if(!ck_ip_rrset(rrset->entry.data, AF_INET6, ++ LIBRPZ_TRIG_IP, qname, rpz)) ++ break; ++ ++ } else if(type == LDNS_RR_TYPE_CNAME) { ++ /* Check CNAME owners unless we already have a hit. */ ++ ++rpz->hit_id; ++ if(!ck_qname(rrset->rk.dname, rrset->rk.dname_len, ++ true, wait_ns, rpz, env)) ++ break; ++ ++ /* Do not worry about the CNAME if it did not hit, ++ * but note the miss so that it can be prepended ++ * if we do hit. */ ++ if(rpz->result.hit_id != rpz->hit_id) { ++ rpz->cname_hit_2nd = true; ++ continue; ++ } ++ ++ /* Stop after hitting a CNAME. ++ * The iterator must be used to include CNAMEs before ++ * the CNAME that hit in the rewritten response. */ ++ rpz->cname_hit.size = rrset->rk.dname_len; ++ RPZ_ASSERT(rpz->cname_hit.size <= sizeof(rpz->cname_hit.d)); ++ memcpy(rpz->cname_hit.d, rrset->rk.dname, ++ rpz->cname_hit.size); ++ break; ++ } ++ } ++} ++ ++ ++static void ++worker_servfail(struct worker* worker, struct query_info* qinfo, ++ uint16_t id, uint16_t flags, struct comm_reply* commreply) ++{ ++ error_encode(commreply->c->buffer, LDNS_RCODE_SERVFAIL, ++ qinfo, id, flags, NULL); ++ regional_free_all(worker->scratchpad); ++ comm_point_send_reply(commreply); ++} ++ ++ ++/* Send an RPZ answer before the iterator has started. ++ * @return: 1=continue normal unbound processing ++ * 0=punt to the iterator ++ * -1=rewritten response already sent or dropped. */ ++static int ++worker_send(struct dns_msg* dnsmsg, struct worker* worker, ++ struct query_info* qinfo, uint16_t id, uint16_t flags, ++ struct edns_data* edns, struct comm_reply* commreply) ++{ ++ switch (commreply->rpz->st) { ++ case st_off: ++ return 1; ++ case st_servfail: ++ worker_servfail(worker, qinfo, id, flags, commreply); ++ return -1; ++ case st_unknown: ++ return 1; ++ case st_iterate: ++ case st_ck_ns: ++ return 0; /* punt to the iterator */ ++ case st_rewritten: ++ break; ++ default: ++ fatal_exit("impossible RPZ state %d in worker_send()", ++ commreply->rpz->st); ++ } ++ ++ if(dnsmsg->rep->security == sec_status_rpz_drop) { ++ regional_free_all(worker->scratchpad); ++ comm_point_drop_reply(commreply); ++ return -1; ++ } ++ ++ edns->edns_version = EDNS_ADVERTISED_VERSION; ++ edns->udp_size = EDNS_ADVERTISED_SIZE; ++ edns->ext_rcode = 0; ++ edns->bits = 0; /* rewritten response cannot verify. */ ++ if(!reply_info_answer_encode(qinfo, dnsmsg->rep, ++ id, flags | BIT_QR, ++ commreply->c->buffer, 0, 1, ++ worker->scratchpad, ++ edns->udp_size, edns, 0, 0)) { ++ worker_servfail(worker, qinfo, id, flags, commreply); ++ } else { ++ regional_free_all(worker->scratchpad); ++ comm_point_send_reply(commreply); ++ } ++ return -1; ++} ++ ++ ++/* Set commreply to an RPZ context if the response might be rewritten. ++ * Try to answer now with a hit allowed before recursion (iteration). */ ++bool /* true=response sent or dropped */ ++rpz_start(struct worker* worker, struct query_info* qinfo, ++ struct comm_reply* commreply, struct edns_data* edns) ++{ ++ commreply_rpz_t* rpz; ++ uint16_t id, flags; ++ struct dns_msg* dnsmsg; ++ int family; ++ const void* addr; ++ librpz_emsg_t emsg; ++ ++ /* Quit if rpz not configured. */ ++ if(!worker->daemon->rpz_client) ++ return false; ++ ++ /* Rewrite only the Internet class */ ++ if(qinfo->qclass != LDNS_RR_CLASS_IN) ++ return false; ++ ++ rpz = commreply->rpz; ++ RPZ_ASSERT(!rpz); ++ ++ dnsmsg = NULL; ++ id = htons(sldns_buffer_read_u16_at(commreply->c->buffer, 0)); ++ flags = sldns_buffer_read_u16_at(commreply->c->buffer, 2); ++ ++ rpz = malloc(sizeof(*rpz)); ++ if(!rpz) { ++ librpz->log(LIBRPZ_LOG_ERROR, NULL, "no memory for rpz"); ++ return 0 > worker_send(dnsmsg, worker, qinfo, ++ id, flags, edns, commreply); ++ } ++ memset(rpz, 0, sizeof(*rpz)); ++ rpz->st = st_unknown; ++ commreply->rpz = rpz; ++ ++ /* Make a new ID for log messages */ ++ rpz->log_id = __sync_add_and_fetch(&log_id, 1); ++ ++ /* Get access to the librpz data. */ ++ if(!librpz->rsp_create(&emsg, &rpz->rsp, &rpz->min_ns_dots, ++ worker->daemon->rpz_client, ++ (flags & BIT_RD) != 0, ++ (edns->bits & EDNS_DO) != 0)) { ++ log_fail(rpz, "%s", emsg.c); ++ return false; ++ } ++ /* Quit if benign reasons prevent rewriting. */ ++ if(!rpz->rsp) { ++ rpz->st = st_off; ++ librpz->log(LIBRPZ_LOG_TRACE1, rpz, "%s", emsg.c); ++ return false; ++ } ++ ++ /* Check the client IP address. ++ * Do not use commreply->srctype because it is often 0. */ ++ family = ((struct sockaddr*)&commreply->addr)->sa_family; ++ switch(family) { ++ case AF_INET: ++ addr = &((struct sockaddr_in*)&commreply->addr)->sin_addr; ++ break; ++ case AF_INET6: ++ addr = &((struct sockaddr_in6*)&commreply->addr)->sin6_addr; ++ break; ++ default: ++ /* Maybe the client is on a UNIX domain socket. */ ++ librpz->log(LIBRPZ_LOG_TRACE2, rpz, ++ "unknown client address family %d", family); ++ addr = NULL; ++ break; ++ } ++ /* Loop to ignore disabled zones. */ ++ while(addr) { ++ if(!push_st(rpz)) ++ break; ++ if(!librpz->ck_ip(&emsg, addr, family, LIBRPZ_TRIG_CLIENT_IP, ++ rpz->hit_id, true, rpz->rsp)) { ++ log_fail(rpz, "%s", emsg.c); ++ break; ++ } ++ if(!ck_after(qinfo->qname, false, LIBRPZ_TRIG_CLIENT_IP, rpz)) ++ break; ++ } ++ if(rpz->st == st_servfail) ++ return 0 > worker_send(dnsmsg, worker, qinfo, ++ id, flags, edns, commreply); ++ ++ /* Check the QNAME and possibly replace a client-IP hit. */ ++ ck_qname(qinfo->qname, qinfo->qname_len, false, true, ++ rpz, &worker->env); ++ ++ get_result_msg(&dnsmsg, qinfo, id, flags, false, ++ rpz, commreply->c, worker->scratchpad); ++ return 0 > worker_send(dnsmsg, worker, qinfo, ++ id, flags, edns, commreply); ++} ++ ++ ++/* Check a cached reply before iteration. ++ * @return: 1=use cache entry ++ * 0=deny a cached entry exists in order to punt to the iterator ++ * -1=rewritten response already sent or dropped */ ++int ++rpz_worker_cache(struct worker* worker, struct reply_info* reply, ++ struct query_info* qinfo, uint16_t id, uint16_t flags, ++ struct edns_data* edns, struct comm_reply* commreply) ++{ ++ commreply_rpz_t* rpz; ++ struct dns_msg* dnsmsg; ++ st_t new_st; ++ librpz_rr_t* rr; ++ ++ dnsmsg = NULL; ++ ++ rpz = commreply->rpz; ++ switch(rpz->st) { ++ case st_off: ++ return 1; /* Send the cache entry. */ ++ case st_servfail: ++ return worker_send(dnsmsg, worker, qinfo, id, flags, ++ edns, commreply); ++ case st_unknown: ++ break; ++ case st_iterate: ++ case st_ck_ns: ++ return 0; /* Punt to the iterator. */ ++ case st_rewritten: ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_worker_cache()", ++ rpz->st); ++ } ++ ++ /* Check the RRs in the ANSWER section. */ ++ if(!push_st(rpz)) ++ return worker_send(dnsmsg, worker, qinfo, id, flags, edns, ++ commreply); ++ ++ ck_reply(reply, qinfo->qname, true, rpz, &worker->env); ++ if(!ck_result(qinfo->qname, true, rpz, commreply->c)) ++ return worker_send(dnsmsg, worker, qinfo, id, flags, edns, ++ commreply); ++ ++ if(rpz->cname_hit.size != 0) { ++ /* Punt to the iterator if leading CNAMEs must be ++ * included in the rewritten response. */ ++ rpz->cname_hit.size = 0; ++ new_st = st_iterate; ++ ++ } else if(rpz->result.policy == LIBRPZ_POLICY_CNAME) { ++ /* Punt if the rewritten response is to a CNAME. */ ++ new_st = st_iterate; ++ ++ } else { ++ if(rpz->result.policy == LIBRPZ_POLICY_RECORD) { ++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz); ++ if(rr) { ++ /* Punt we are rewriting to a CNAME. */ ++ if(rr->type == ntohs(LDNS_RR_TYPE_CNAME)) { ++ free(rr); ++ rpz->st = st_iterate; ++ } else { ++ free(rr); ++ } ++ } ++ } ++ get_result_msg(&dnsmsg, qinfo, id, flags, true, ++ rpz, commreply->c, worker->scratchpad); ++ new_st = rpz->st; ++ } ++ ++ switch(new_st) { ++ case st_off: ++ case st_servfail: ++ break; ++ case st_unknown: ++ pop_discard_st(rpz); ++ break; ++ case st_iterate: ++ case st_ck_ns: ++ if(pop_st(rpz)) ++ rpz->st = new_st; ++ break; ++ case st_rewritten: ++ pop_discard_st(rpz); ++ break; ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_worker_cache()", ++ rpz->st); ++ } ++ ++ return worker_send(dnsmsg, worker, qinfo, id, flags, edns, commreply); ++} ++ ++ ++/* Check a cache hit or miss for the iterator. ++ * A cache miss can already have a QNAME hit that was ignored before checking ++ * the iterator because of "QNAME-WAIT-RECURSE yes". ++ * Cache hits are treated like responses from authorities. */ ++bool /* false=SERVFAIL */ ++rpz_iter_cache(struct dns_msg** msg, enum response_type* type, ++ struct module_qstate* qstate, struct iter_qstate* iq) ++{ ++ struct comm_reply* commreply; ++ commreply_rpz_t* rpz; ++ struct dns_msg* dnsmsg; ++ ++ commreply = &qstate->mesh_info->reply_list->query_reply; ++ rpz = commreply->rpz; ++ ++ rpz->iterating = true; ++ ++ switch(rpz->st) { ++ case st_off: ++ iq->rpz_rewritten = 1; /* RPZ has nothing to say. */ ++ return true; ++ case st_servfail: ++ return false; ++ case st_unknown: ++ break; ++ case st_iterate: ++ case st_ck_ns: ++ rpz->st = st_unknown; ++ if(!ck_qname(iq->qchase.qname, iq->qchase.qname_len, ++ *msg != NULL, true, rpz, qstate->env)) ++ return false; ++ /* If we must recurse regardless and if NSIP/NSDNAME ++ * checking failed, then delay in the hope that ++ * recursion will also get NS data. */ ++ if(rpz->st == st_ck_ns) ++ return true; ++ break; ++ case st_rewritten: ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_iter_cache()", ++ rpz->st); ++ } ++ ++ push_st(rpz); ++ ++ /* Check the cache hit. */ ++ if(*msg) ++ ck_reply((*msg)->rep, iq->qchase.qname, true, rpz, qstate->env); ++ ++ /* The DNS ID does not matter, because the generated dns_msg ++ * is nominally from an authority and not to the DNS client. */ ++ get_result_msg(&dnsmsg, &iq->qchase, 1, qstate->query_flags, true, ++ rpz, commreply->c, qstate->region); ++ ++ switch(rpz->st) { ++ case st_off: ++ iq->rpz_rewritten = 1; /* RPZ has nothing to say. */ ++ return true; ++ case st_servfail: ++ return false; ++ case st_unknown: ++ /* RPZ has nothing to say yet. Maybe there will be a hit ++ * later in the CNAME chain. */ ++ return pop_discard_st(rpz); ++ case st_ck_ns: ++ /* Try to get NS data for a CNAME found by ck_reply() */ ++ *type = RESPONSE_TYPE_CNAME; ++ return pop_discard_st(rpz); ++ case st_iterate: ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_iter_cache()", ++ rpz->st); ++ case st_rewritten: ++ break; ++ } ++ ++ if(*msg && rpz->cname_hit.size != 0 && rpz->cname_hit_2nd) { ++ /* We hit a CNAME owner in the cached msg after not hitting one ++ * or more CNAME owners. We need to add those leading CNAMEs ++ * to the prepend list. Tell the iterator to treat the cached ++ * message as a RESPONSE_TYPE_CNAME even if it contains answers. ++ * handle_cname_response() will stop prepending CNAMEs before ++ * the triggering CNAME. handle_cname_response() will cause ++ * a restart to resolve the target of the preceding CNAME, ++ * which is the same as the hit CNAME owner. */ ++ rpz->st = st_unknown; ++ *type = RESPONSE_TYPE_CNAME; ++ return pop_discard_st(rpz); ++ } ++ ++ *msg = dnsmsg; ++ iq->rpz_security = dnsmsg->rep->security; ++ ++ if(dnsmsg && dnsmsg->rep->an_numrrsets != 0 && ++ dnsmsg->rep->rrsets[0]->rk.type == htons(LDNS_RR_TYPE_CNAME)) { ++ /* The cached msg triggered a rule that rewrites to a ++ * CNAME that must be resolved. ++ * We have a replacement dns_msg with that CNAME and also ++ * an SOA RR in the ADDITIONAL section that the iterator ++ * will lose as it adds the CNAME to the prepend list. ++ * Save the SOA RR in iq->rpz_soa. */ ++ iq->rpz_soa = dnsmsg->rep->rrsets[1]; ++ iq->rpz_rewritten = 1; ++ *type = RESPONSE_TYPE_CNAME; ++ return true; ++ } ++ ++ /* Otherwise we have rewritten to zero or more non-CNAME RRs. ++ * (DNAMEs are not supported.) ++ * Tell the iterator to send the rewritten message. */ ++ *type = RESPONSE_TYPE_ANSWER; ++ iq->rpz_rewritten = 1; ++ return true; ++} ++ ++ ++/* Check a RESPONSE_TYPE_ANSWER response from an authority in the iterator. */ ++rpz_iter_resp_t ++rpz_iter_resp(struct module_qstate* qstate, struct iter_qstate* iq, ++ struct dns_msg** resp, bool* is_cname) ++{ ++ struct comm_reply* commreply; ++ commreply_rpz_t* rpz; ++ struct reply_info* rep; ++ ++ *is_cname = false; ++ ++ commreply = &qstate->mesh_info->reply_list->query_reply; ++ rpz = commreply->rpz; ++ switch(rpz->st) { ++ case st_off: ++ case st_servfail: ++ case st_iterate: ++ case st_rewritten: ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_iter_resp()", ++ rpz->st); ++ case st_ck_ns: ++ case st_unknown: ++ break; ++ } ++ ++ /* We know !iq->rpz_rewritten and so the response was after a simple ++ * cache miss when the original QNAME did not trigger a response ++ * or after a CNAME whose owner name did hit but was then forgotten ++ * with pop_st(). ++ * In either case, it is necessary to check the QNAME here. ++ * Checking the QNAME will not lose a better hit. */ ++ rpz->st = st_unknown; ++ ck_qname(iq->qchase.qname, iq->qchase.qname_len, true, false, ++ rpz, qstate->env); ++ ++ /* Check the RRs in the ANSWER section. */ ++ if(!push_st(rpz)) ++ return rpz_iter_resp_fail; ++ ck_reply(iq->response->rep, iq->qchase.qname, false, rpz, qstate->env); ++ get_result_msg(resp, &qstate->qinfo, 1, qstate->query_flags, true, ++ rpz, commreply->c, qstate->region); ++ switch(rpz->st) { ++ case st_off: ++ iq->rpz_rewritten = 1; /* Do not come back. */ ++ return rpz_iter_resp_done; ++ case st_servfail: /* Send SERVFAIL */ ++ return rpz_iter_resp_fail; ++ case st_unknown: ++ case st_ck_ns: ++ return rpz_iter_resp_done; /* continue without change */ ++ case st_iterate: ++ default: ++ fatal_exit("impossible RPZ state %d in rpz_iter_resp()", ++ rpz->st); ++ case st_rewritten: ++ /* Tell the iterator to use handle_cname_response() to ++ * prepend any preceding CNAMEs. ++ * We have a replacement dns_msg that also has an SOA RR in the ++ * ADDITIONAL section that the iterator will lose if it is a ++ * CNAME. Save that SOA in that case. */ ++ rep = (*resp)->rep; ++ if(rep->an_numrrsets != 0 && ++ rep->rrsets[0]->rk.type == ntohs(LDNS_RR_TYPE_CNAME)) { ++ *is_cname = true; ++ iq->rpz_soa = rep->rrsets[1]; ++ } ++ return rpz_iter_resp_rewrite; ++ } ++} ++ ++ ++/* Tell handle_cname_response() to stop adding to the answer prepend list ++ * after adding CNAME with a target that hits a QNAME trigger. ++ * Do not change any RPZ state, but expect the call of handle_cname_response() ++ * to try to resolve the CNAME and hit the same QNAME trigger and rewrite ++ * the response. */ ++rpz_cname_t ++rpz_cname(struct module_qstate* qstate, ++ uint8_t* oname, size_t oname_size) ++{ ++ struct mesh_reply* reply_list; ++ struct comm_reply* commreply; ++ commreply_rpz_t* rpz; ++ rpz_cname_t ret; ++ ++ /* Quit if RPZ is off */ ++ reply_list = qstate->mesh_info->reply_list; ++ if(!reply_list) ++ return rpz_cname_prepend; ++ commreply = &reply_list->query_reply; ++ rpz = commreply->rpz; ++ ++ if(!rpz || rpz->st == st_off) ++ return rpz_cname_prepend; ++ ++ /* Stop on a 2nd or later CNAME for rpz_iter_resp(). */ ++ if(rpz->cname_hit.size != 0) { ++ if(!query_dname_compare(rpz->cname_hit.d, oname)) ++ return rpz_cname_stop; ++ return rpz_cname_prepend; ++ } ++ ++ if(rpz->st != st_unknown) ++ fatal_exit("impossible RPZ state %d in rpz_cname()", rpz->st); ++ ++ ret = rpz_cname_prepend; ++ if(!push_st(rpz)) ++ return rpz_cname_fail; ++ /* Stop before prepending a CNAME that would preempt a ++ * rewritten response or before a possible NSDNAME or NSIP trigger. */ ++ ++rpz->hit_id; ++ ck_qname(oname, oname_size, true, true, rpz, qstate->env); ++ if(rpz->st != st_unknown) ++ ret = rpz_cname_stop; ++ if(!pop_st(rpz)) ++ return rpz_cname_fail; ++ return ret; ++} ++ ++#endif /* ENABLE_FASTRPZ */ +diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h +new file mode 100644 +index 00000000..5d7e31c5 +--- /dev/null ++++ b/fastrpz/rpz.h +@@ -0,0 +1,138 @@ ++/* ++ * fastrpz/rpz.h - interface to the fastrpz response policy zone library ++ * ++ * Copyright (c) 2016 Farsight Security, Inc. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#ifndef UNBOUND_FASTRPZ_RPZ_H ++#define UNBOUND_FASTRPZ_RPZ_H ++ ++#ifndef PACKAGE_VERSION ++/* Ensure that config.h has been included to correctly set ENABLE_FASTRPZ */ ++#include "config.h" ++#endif ++ ++#ifdef ENABLE_FASTRPZ ++ ++#include "librpz.h" ++ ++#include "daemon/daemon.h" ++#include "util/config_file.h" ++ ++struct comm_point; /* forward references */ ++struct comm_reply; ++struct dns_msg; ++struct edns_data; ++struct iter_qstate; ++struct query_info; ++struct reply_info; ++enum response_type; /* iterator/iter_utils.h */ ++ ++ ++struct commreply_rpz; ++ ++/** ++ * Connect to the librpz database. ++ * @param pclist: future pointer to opaque librpz client data ++ * @param pclient: future pointer to opaque librpz client data ++ * @param cfg: parsed unbound configuration ++ */ ++void rpz_init(librpz_clist_t** pclist, librpz_client_t** pclient, ++ const struct config_file* cfg); ++ ++/** ++ * Disconnect from the librpz database ++ * @param client: opaque librpz client data ++ */ ++void rpz_delete(librpz_clist_t** pclist, librpz_client_t** pclient); ++ ++/** ++ * Start working on a DNS request and check for client IP address triggers. ++ * @param worker: the DNS request context ++ * @param qinfo: the DNS question ++ * @param[in,out] commreply: the answer ++ * @param c: where to send the response ++ * @param[in,out] edns for the DO flag ++ * @return true if response already sent or dropped ++ */ ++bool rpz_start(struct worker* worker, struct query_info* qinfo, ++ struct comm_reply* commreply, struct edns_data* edns); ++ ++/** ++ * Release resources held for a DNS request ++ * @param rspp: pointer to pointer to rpz client context. ++ */ ++void rpz_end(struct comm_reply* comm_rep); ++ ++/** ++ * Check a cached reply for RPZ hits before iteration ++ * @param worker: the DNS request context ++ * @param casheresp: cache reply ++ * @param qinfo: the DNS question ++ * @param id from the DNS request ++ * @param flags from the DNS request ++ * @param[in,out] edns for the DO flag ++ * @param[in,out] commreply: RPZ state ++ * @return 1=use cache entry, -1=rewritten response already sent or dropped, ++ * 0=deny a cached entry exists ++ */ ++int rpz_worker_cache(struct worker* worker, struct reply_info* cacheresp, ++ struct query_info* qinfo, uint16_t id, uint16_t flags, ++ struct edns_data* edns, struct comm_reply* commreply); ++ ++/** ++ * Check for an existing RPZ CNAME rewrite with "QNAME-WAIT-RECURSE no" ++ * that needs to be resolved before resolving the external request. ++ * @param[out] msg: rewritten CNAME response. ++ * @param qstate: query state. ++ * @param iq: iterator query state. ++ * @return false=send SERVFAIL ++ */ ++bool rpz_iter_cache(struct dns_msg** msg, enum response_type* type, ++ struct module_qstate* qstate, struct iter_qstate* iq); ++ ++/** ++ * Check a response from an authority in the iterator. ++ * @param[out] type: of the final response ++ * @param qstate: query state. ++ * @param iq: iterator query state. ++ * @param is_cname: true if the rewritten response is a CNAME ++ * @return one of rpz_resp_t ++ */ ++typedef enum { ++ rpz_iter_resp_fail, /* Send SERVFAIL. */ ++ rpz_iter_resp_rewrite, /* We rewrote the response. */ ++ rpz_iter_resp_done, /* Restart to refetch glue. */ ++} rpz_iter_resp_t; ++rpz_iter_resp_t rpz_iter_resp(struct module_qstate* qstate, ++ struct iter_qstate* iq, struct dns_msg** resp, ++ bool* is_cname); ++ ++/** ++ * Check a CNAME RR ++ * @param qstate: query state. ++ * @param oname: cname owner name ++ * @param oname_size: length of oname ++ * @return: one of rpz_cname_t ++ */ ++typedef enum { ++ rpz_cname_fail, /* send SERVFAIL */ ++ rpz_cname_prepend, /* prepend CNAME as usual */ ++ rpz_cname_stop, /* stop before prepending this CNAME */ ++} rpz_cname_t; ++rpz_cname_t rpz_cname(struct module_qstate* qstate, ++ uint8_t* oname, size_t oname_size); ++ ++#endif /* ENABLE_FASTRPZ */ ++#endif /* UNBOUND_FASTRPZ_RPZ_H */ +diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4 +new file mode 100644 +index 00000000..21235355 +--- /dev/null ++++ b/fastrpz/rpz.m4 +@@ -0,0 +1,64 @@ ++# fastrpz/rpz.m4 ++ ++# ck_FASTRPZ ++# -------------------------------------------------------------------------- ++# check for Fastrpz ++# --enable-fastrpz enable Fastrpz response policy zones ++# --enable-fastrpz-dl Fastrpz delayed link [default=have dlopen] ++# --with-fastrpz-dir directory containing librpz.so ++# ++# Fastrpz can be compiled into Unbound everywhere with a reasonably ++# modern C compiler. It is enabled on systems with dlopen() and librpz.so. ++ ++AC_DEFUN([ck_FASTRPZ], ++[ ++ fastrpz_avail=yes ++ AC_MSG_CHECKING([for librpz __attribute__s]) ++ AC_TRY_COMPILE(,[ ++ extern void f(char *p __attribute__((unused)), ...) ++ __attribute__((format(printf,1,2))) __attribute__((__noreturn__));], ++ librpz_have_attr=yes ++ AC_DEFINE([LIBRPZ_HAVE_ATTR], 1, [have __attribute__s used in librpz.h]) ++ AC_MSG_RESULT([yes]), ++ librpz_have_attr=no ++ AC_MSG_RESULT([no])) ++ ++ AC_SEARCH_LIBS(dlopen, dl) ++ librpz_dl=yes ++ AC_CHECK_FUNCS(dlopen dlclose dlsym,,librpz_dl=no) ++ AC_ARG_ENABLE([fastrpz-dl], ++ [ --enable-fastrpz-dl Fastrpz delayed link [[default=$librpz_dl]]], ++ [enable_librpz_dl="$enableval"], ++ [enable_librpz_dl="$librpz_dl"]) ++ AC_ARG_WITH([fastrpz-dir], ++ [ --with-fastrpz-dir directory containing librpz.so], ++ [librpz_path="$withval/librpz.so"], [librpz_path="librpz.so"]) ++ AC_DEFINE_UNQUOTED([FASTRPZ_LIBRPZ_PATH], ["$librpz_path"], ++ [fastrpz librpz.so]) ++ if test "x$enable_librpz_dl" = "xyes"; then ++ fastrpz_lib_open=2 ++ else ++ fastrpz_lib_open=1 ++ # Add librpz.so to linked libraries if we are not using dlopen() ++ AC_SEARCH_LIBS([librpz_client_create], [rpz], [], ++ [fastrpz_lib_open=0 ++ fastrpz_avail=no]) ++ fi ++ AC_DEFINE_UNQUOTED([FASTRPZ_LIB_OPEN], [$fastrpz_lib_open], ++ [0=no fastrpz 1=static link 2=dlopen()]) ++ ++ AC_ARG_ENABLE([fastrpz], ++ AS_HELP_STRING([--enable-fastrpz],[enable Fastrpz response policy zones]), ++ [enable_fastrpz=$enableval],[enable_fastrpz=$fastrpz_avail]) ++ if test "x$enable_fastrpz" = xyes; then ++ AC_DEFINE([ENABLE_FASTRPZ], [1], [Enable fastrpz]) ++ if test "x$fastrpz_lib_open" = "x0"; then ++ AC_MSG_ERROR([[dlopen and librpz.so needed for fastrpz]]) ++ fi ++ # used in Makefile.in ++ AC_SUBST([FASTRPZ_SRC], [fastrpz/rpz.c]) ++ AC_SUBST([FASTRPZ_OBJ], [rpz.lo]) ++ elif test "x$fastrpz_avail" = "x0"; then ++ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]]) ++ fi ++]) +diff --git a/iterator/iterator.c b/iterator/iterator.c +index 1e0113a8..2fcbf547 100644 +--- a/iterator/iterator.c ++++ b/iterator/iterator.c +@@ -68,6 +68,9 @@ + #include "sldns/str2wire.h" + #include "sldns/parseutil.h" + #include "sldns/sbuffer.h" ++#ifdef ENABLE_FASTRPZ ++#include "fastrpz/rpz.h" ++#endif + + /* in msec */ + int UNKNOWN_SERVER_NICENESS = 376; +@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, + if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME && + query_dname_compare(*mname, r->rk.dname) == 0 && + !iter_find_rrset_in_prepend_answer(iq, r)) { ++#ifdef ENABLE_FASTRPZ ++ /* Stop adding CNAME rrsets to the prepend list ++ * before defining an RPZ hit. */ ++ if(!iq->rpz_rewritten) { ++ switch (rpz_cname(qstate, *mname, *mname_len)) { ++ case rpz_cname_fail: ++ /* send SERVFAIL */ ++ return 0; ++ case rpz_cname_prepend: ++ /* save the CNAME. */ ++ break; ++ case rpz_cname_stop: ++ /* Pause before adding the CNAME. */ ++ goto stop_short; ++ } ++ } ++#endif + /* Add this relevant CNAME rrset to the prepend list.*/ + if(!iter_add_prepend_answer(qstate, iq, r)) + return 0; +@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, + + /* Other rrsets in the section are ignored. */ + } ++#ifdef ENABLE_FASTRPZ ++stop_short: ; ++#endif + /* add authority rrsets to authority prepend, for wildcarded CNAMEs */ + for(i=msg->rep->an_numrrsets; irep->an_numrrsets + + msg->rep->ns_numrrsets; i++) { +@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, + uint8_t* delname; + size_t delnamelen; + struct dns_msg* msg = NULL; ++ enum response_type type; + + log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo); + /* check effort */ +@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, + } + if(msg) { + /* handle positive cache response */ +- enum response_type type = response_type_from_cache(msg, +- &iq->qchase); ++ type = response_type_from_cache(msg, &iq->qchase); + if(verbosity >= VERB_ALGO) { + log_dns_msg("msg from cache lookup", &msg->qinfo, + msg->rep); +@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, + (int)msg->rep->ttl, + (int)msg->rep->prefetch_ttl); + } ++#ifdef ENABLE_FASTRPZ ++ } ++ /* Check for an RPZ hit in the cached DNS message or an existing ++ * RPZ CNAME rewrite that can be resolved now after a hit on the QNAME ++ * or client IP address. This can involve a creating a fake cache ++ * hit. It can also involve overriding an RESPONSE_TYPE_ANSWER ++ * result from response_type_from_cache(). Or it can ignore ++ * the cached result to refetch glue. */ ++ if(!iq->rpz_rewritten && ++ qstate->mesh_info->reply_list && ++ qstate->mesh_info->reply_list->query_reply.rpz && ++ !rpz_iter_cache(&msg, &type, qstate, iq)) ++ return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + ++ if(msg) { ++#endif + if(type == RESPONSE_TYPE_CNAME) { + uint8_t* sname = 0; + size_t slen = 0; +@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, + sock_list_insert(&qstate->reply_origin, + &qstate->reply->addr, qstate->reply->addrlen, + qstate->region); ++#ifdef ENABLE_FASTRPZ ++ /* Check the response for an RPZ hit. The response has already ++ * been saved in the cache. This should have the same effect ++ * as finding that response in the cache. ++ * We have already used rpz_iter_cache() at least once. */ ++ if(!iq->rpz_rewritten && ++ qstate->mesh_info->reply_list && ++ qstate->mesh_info->reply_list->query_reply.rpz) { ++ struct dns_msg* resp; ++ bool is_cname; ++ uint8_t* sname; ++ size_t slen; ++ ++ switch (rpz_iter_resp(qstate, iq, &resp, &is_cname)) { ++ case rpz_iter_resp_fail: ++ return error_response(qstate, id, ++ LDNS_RCODE_SERVFAIL); ++ case rpz_iter_resp_rewrite: ++ /* Prepend any initial CNAMEs from the original ++ * response up to a hit. */ ++ if(!handle_cname_response(qstate, iq, ++ iq->response, ++ &sname, &slen)) ++ return error_response(qstate, id, ++ LDNS_RCODE_SERVFAIL); ++ if (resp) { ++ iq->response = resp; ++ iq->rpz_security = resp->rep->security; ++ iq->rpz_rewritten = 1; ++ ++ /* Send the rewritten record if it ++ * is not a CNAME. */ ++ if(!is_cname) ++ break; ++ ++ /* Prepend the new CNAME ++ * and restart to resolve it. */ ++ if(!handle_cname_response(qstate, iq, ++ resp, &sname, &slen)) ++ return error_response(qstate, id, ++ LDNS_RCODE_SERVFAIL); ++ } ++ iq->qchase.qname = sname; ++ iq->qchase.qname_len = slen; ++ iq->dp = NULL; ++ iq->refetch_glue = 0; ++ iq->query_restart_count++; ++ iq->sent_count = 0; ++ iq->state = INIT_REQUEST_STATE; ++ return 1; ++ ++ case rpz_iter_resp_done: ++ break; ++ } ++ } ++#endif + if(iq->minimisation_state != DONOT_MINIMISE_STATE + && !(iq->chase_flags & BIT_RD)) { + if(FLAGS_GET_RCODE(iq->response->rep->flags) != +@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, + * but only if we did recursion. The nonrecursion referral + * from cache does not need to be stored in the msg cache. */ + if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) { ++#ifdef ENABLE_FASTRPZ ++ /* Do not save RPZ rewritten messages. */ ++ if(!iq->rpz_rewritten) ++#endif + iter_dns_store(qstate->env, &qstate->qinfo, + iq->response->rep, 0, qstate->prefetch_leeway, + iq->dp&&iq->dp->has_parent_side_NS, + qstate->region, qstate->query_flags); + } + } ++#ifdef ENABLE_FASTRPZ ++ if(iq->rpz_rewritten) { ++ /* Restore RPZ marks on a rewritten response. The marks ++ * are lost if the rewrite is to a CNAME. */ ++ iq->response->rep->security = iq->rpz_security; ++ ++ /* Append the RPZ SOA to rewritten CNAME chains. */ ++ if(iq->rpz_soa) { ++ struct ub_packed_rrset_key** sets; ++ uint n; ++ ++ n = iq->response->rep->rrset_count; ++ sets = regional_alloc(qstate->region, ++ (1+n) * sizeof(*sets)); ++ if(!sets) { ++ log_err("append RPZ SOA: out of memory"); ++ return error_response(qstate, id, ++ LDNS_RCODE_SERVFAIL); ++ } ++ memcpy(sets, iq->response->rep->rrsets, ++ n * sizeof(struct ub_packed_rrset_key*)); ++ sets[n] = iq->rpz_soa; ++ iq->response->rep->rrsets = sets; ++ ++iq->response->rep->rrset_count; ++ ++iq->response->rep->ar_numrrsets; ++ } ++ } ++#endif + qstate->return_rcode = LDNS_RCODE_NOERROR; + qstate->return_msg = iq->response; + return 0; +diff --git a/iterator/iterator.h b/iterator/iterator.h +index a2f1b570..e1e4a738 100644 +--- a/iterator/iterator.h ++++ b/iterator/iterator.h +@@ -386,6 +386,16 @@ struct iter_qstate { + */ + int minimise_count; + ++ ++#ifdef ENABLE_FASTRPZ ++ /** The response has been rewritten by RPZ. */ ++ int rpz_rewritten; ++ /** RPZ SOA RR for the ADDITIONAL section */ ++ struct ub_packed_rrset_key* rpz_soa; ++ /** sec_status_rpz_rewritten or sec_status_rpz_drop if rewritten. */ ++ enum sec_status rpz_security; ++#endif ++ + /** + * Count number of time-outs. Used to prevent resolving failures when + * the QNAME minimisation QTYPE is blocked. */ +diff --git a/services/cache/dns.c b/services/cache/dns.c +index 2a5bca4a..6de8863a 100644 +--- a/services/cache/dns.c ++++ b/services/cache/dns.c +@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, + struct regional* region, uint32_t flags) + { + struct reply_info* rep = NULL; ++ ++#ifdef ENABLE_FASTRPZ ++ /* Never save RPZ rewritten data. */ ++ if (msgrep->security == sec_status_rpz_drop || ++ msgrep->security == sec_status_rpz_rewritten) ++ return 1; ++#endif ++ + /* alloc, malloc properly (not in region, like msg is) */ + rep = reply_info_copy(msgrep, env->alloc, NULL); + if(!rep) +diff --git a/services/mesh.c b/services/mesh.c +index 9114ef4c..3dc518e5 100644 +--- a/services/mesh.c ++++ b/services/mesh.c +@@ -61,6 +61,9 @@ + #include "sldns/wire2str.h" + #include "services/localzone.h" + #include "util/data/dname.h" ++#ifdef ENABLE_FASTRPZ ++#include "fastrpz/rpz.h" ++#endif + #include "respip/respip.h" + #include "services/listen_dnsport.h" + +@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep, + else secure = 0; + if(!rep && rcode == LDNS_RCODE_NOERROR) + rcode = LDNS_RCODE_SERVFAIL; ++#ifdef ENABLE_FASTRPZ ++ /* Drop the response here for LIBRPZ_POLICY_DROP after iteration. */ ++ if(rep && rep->security == sec_status_rpz_drop) { ++ log_query_info(VERB_QUERY, "rpz drop", &m->s.qinfo); ++ secure = 0; ++ } else ++#endif + /* send the reply */ + /* We don't reuse the encoded answer if either the previous or current + * response has a local alias. We could compare the alias records +@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh, + key.s.is_valrec = valrec; + key.s.qinfo = *qinfo; + key.s.query_flags = qflags; ++ key.reply_list = NULL; + /* We are searching for a similar mesh state when we DO want to + * aggregate the state. Thus unique is set to NULL. (default when we + * desire aggregation).*/ +@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns, + if(!r) + return 0; + r->query_reply = *rep; ++#ifdef ENABLE_FASTRPZ ++ /* The new reply structure owns the RPZ state. */ ++ rep->rpz = NULL; ++#endif + r->edns = *edns; + if(edns->opt_list) { + r->edns.opt_list = edns_opt_copy_region(edns->opt_list, +diff --git a/util/config_file.c b/util/config_file.c +index 52ca5a18..0660248f 100644 +--- a/util/config_file.c ++++ b/util/config_file.c +@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg) + free(cfg->dnstap_socket_path); + free(cfg->dnstap_identity); + free(cfg->dnstap_version); ++ if (cfg->rpz_cstr) ++ free(cfg->rpz_cstr); + config_deldblstrlist(cfg->ratelimit_for_domain); + config_deldblstrlist(cfg->ratelimit_below_domain); + config_delstrlist(cfg->python_script); +diff --git a/util/config_file.h b/util/config_file.h +index 8739ca2a..a2dcf215 100644 +--- a/util/config_file.h ++++ b/util/config_file.h +@@ -499,6 +499,11 @@ struct config_file { + /** true to disable DNSSEC lameness check in iterator */ + int disable_dnssec_lame_check; + ++ /** true to enable RPZ */ ++ int rpz_enable; ++ /** RPZ configuration */ ++ char* rpz_cstr; ++ + /** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */ + int ip_ratelimit; + /** number of slabs for ip_ratelimit cache */ +diff --git a/util/configlexer.lex b/util/configlexer.lex +index deedffa5..301458a3 100644 +--- a/util/configlexer.lex ++++ b/util/configlexer.lex +@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } + dnstap-log-forwarder-response-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } ++rpz{COLON} { YDVAR(0, VAR_RPZ) } ++rpz-enable{COLON} { YDVAR(1, VAR_RPZ_ENABLE) } ++rpz-zone{COLON} { YDVAR(1, VAR_RPZ_ZONE) } ++rpz-option{COLON} { YDVAR(1, VAR_RPZ_OPTION) } + disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) } + ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) } + ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) } +diff --git a/util/configparser.y b/util/configparser.y +index d471babe..cb6b1d63 100644 +--- a/util/configparser.y ++++ b/util/configparser.y +@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser; + %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES + %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES + %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES ++%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION + %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA + %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT + %token VAR_DISABLE_DNSSEC_LAME_CHECK +@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser; + + %% + toplevelvars: /* empty */ | toplevelvars toplevelvar ; +-toplevelvar: serverstart contents_server | stubstart contents_stub | ++toplevelvar: serverstart contents_server | stubstart contents_stub | rpzstart contents_rpz | + forwardstart contents_forward | pythonstart contents_py | + rcstart contents_rc | dtstart contents_dt | viewstart contents_view | + dnscstart contents_dnsc | cachedbstart contents_cachedb | +@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES + free($2); + } + ; ++rpzstart: VAR_RPZ ++ { ++ OUTYY(("\nP(rpz:)\n")); ++ } ++ ; ++contents_rpz: contents_rpz content_rpz ++ | ; ++content_rpz: rpz_enable | rpz_zone | rpz_option ++ ; ++rpz_enable: VAR_RPZ_ENABLE STRING_ARG ++ { ++ OUTYY(("P(rpz_enable:%s)\n", $2)); ++ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) ++ yyerror("expected yes or no."); ++ else cfg_parser->cfg->rpz_enable = (strcmp($2, "yes")==0); ++ free($2); ++ } ++ ; ++rpz_zone: VAR_RPZ_ZONE STRING_ARG ++ { ++ char *new_cstr, *old_cstr; ++ ++ OUTYY(("P(rpz_zone:%s)\n", $2)); ++ old_cstr = cfg_parser->cfg->rpz_cstr; ++ if(asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2) == -1) {new_cstr = NULL; yyerror("out of memory");} ++ else if(!new_cstr) ++ yyerror("out of memory"); ++ free(old_cstr); ++ cfg_parser->cfg->rpz_cstr = new_cstr; ++ } ++ ; ++rpz_option: VAR_RPZ_OPTION STRING_ARG ++ { ++ char *new_cstr, *old_cstr; ++ ++ OUTYY(("P(rpz_option:%s)\n", $2)); ++ old_cstr = cfg_parser->cfg->rpz_cstr; ++ if(asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2) == -1) {new_cstr = NULL; yyerror("out of memory");} ++ else if(!new_cstr) ++ yyerror("out of memory"); ++ free(old_cstr); ++ cfg_parser->cfg->rpz_cstr = new_cstr; ++ } ++ ; + pythonstart: VAR_PYTHON + { + OUTYY(("\nP(python:)\n")); +diff --git a/util/data/msgencode.c b/util/data/msgencode.c +index be69f628..f10773aa 100644 +--- a/util/data/msgencode.c ++++ b/util/data/msgencode.c +@@ -592,6 +592,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, + return RETVAL_OK; + } + ++#ifdef ENABLE_FASTRPZ ++/* Insert the RPZ SOA even with MINIMAL_RESPONSES */ ++static int ++insert_rpz_soa(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, ++ sldns_buffer* pkt, size_t rrsets_before, time_t timenow, ++ struct regional* region, struct compress_tree_node** tree, ++ size_t rr_offset) ++{ ++ int r; ++ size_t i, setstart; ++ ++ *num_rrs = 0; ++ for(i=0; irrsets[rrsets_before+i]->rk.type != LDNS_RR_TYPE_SOA) ++ continue; ++ setstart = sldns_buffer_position(pkt); ++ if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], ++ pkt, num_rrs, timenow, region, ++ 1, 0, tree, LDNS_SECTION_ADDITIONAL, ++ LDNS_RR_TYPE_ANY, 0, rr_offset)) ++ != RETVAL_OK) { ++ sldns_buffer_set_position(pkt, setstart); ++ return r; ++ } ++ } ++ return RETVAL_OK; ++} ++ ++#endif + /** store query section in wireformat buffer, return RETVAL */ + static int + insert_query(struct query_info* qinfo, struct compress_tree_node** tree, +@@ -779,6 +808,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, + } + sldns_buffer_write_u16_at(buffer, 10, arcount); + } ++#ifdef ENABLE_FASTRPZ ++ } else if(rep->security == sec_status_rpz_rewritten) { ++ /* Insert the RPZ SOA for rpz even with MINIMAL_RESPONSES */ ++ r = insert_rpz_soa(rep, rep->ar_numrrsets, &arcount, buffer, ++ rep->an_numrrsets + rep->ns_numrrsets, ++ timenow, region, &tree, rr_offset); ++ if(r!= RETVAL_OK) { ++ if(r != RETVAL_TRUNC) ++ return 0; ++ /* no need to set TC bit, this is the additional */ ++ sldns_buffer_write_u16_at(buffer, 10, arcount); ++ } ++#endif + } + sldns_buffer_flip(buffer); + return 1; +diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c +index 4b0294f9..3b3838f6 100644 +--- a/util/data/packed_rrset.c ++++ b/util/data/packed_rrset.c +@@ -256,6 +256,10 @@ sec_status_to_string(enum sec_status s) + case sec_status_insecure: return "sec_status_insecure"; + case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail"; + case sec_status_secure: return "sec_status_secure"; ++#ifdef ENABLE_FASTRPZ ++ case sec_status_rpz_rewritten: return "sec_status_rpz_rewritten"; ++ case sec_status_rpz_drop: return "sec_status_rpz_drop"; ++#endif + } + return "unknown_sec_status_value"; + } +diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h +index 729877ba..ccd1a0c2 100644 +--- a/util/data/packed_rrset.h ++++ b/util/data/packed_rrset.h +@@ -193,7 +193,15 @@ enum sec_status { + sec_status_secure_sentinel_fail, + /** SECURE means that the object (RRset or message) validated + * according to local policy. */ +- sec_status_secure ++ sec_status_secure, ++#ifdef ENABLE_FASTRPZ ++ /** RPZ_REWRITTEN means that the response has been rewritten by ++ * rpz and so cannot be verified. */ ++ sec_status_rpz_rewritten, ++ /** RPZ_DROP means that the response has been rewritten by rpz ++ * as silence. */ ++ sec_status_rpz_drop ++#endif + }; + + /** +diff --git a/util/netevent.c b/util/netevent.c +index 9fe5da2d..037e70d1 100644 +--- a/util/netevent.c ++++ b/util/netevent.c +@@ -57,6 +57,9 @@ + #ifdef HAVE_OPENSSL_ERR_H + #include + #endif ++#ifdef ENABLE_FASTRPZ ++#include "fastrpz/rpz.h" ++#endif + + /* -------- Start of local definitions -------- */ + /** if CMSG_ALIGN is not defined on this platform, a workaround */ +@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) + struct cmsghdr* cmsg; + #endif /* S_SPLINT_S */ + ++#ifdef ENABLE_FASTRPZ ++ rep.rpz = NULL; ++#endif + rep.c = (struct comm_point*)arg; + log_assert(rep.c->type == comm_udp); + +@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg) + int i; + struct sldns_buffer *buffer; + ++#ifdef ENABLE_FASTRPZ ++ rep.rpz = NULL; ++#endif + rep.c = (struct comm_point*)arg; + log_assert(rep.c->type == comm_udp); + +@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg) + (void)comm_point_send_udp_msg(rep.c, buffer, + (struct sockaddr*)&rep.addr, rep.addrlen); + } ++#ifdef ENABLE_FASTRPZ ++ rpz_end(&rep); ++#endif + if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for + another UDP port. Note rep.c cannot be reused with TCP fd. */ + break; +@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo) + repinfo->c->tcp_timeout_msec); + } + } ++#ifdef ENABLE_FASTRPZ ++ rpz_end(repinfo); ++#endif + } + + void +@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo) + return; + log_assert(repinfo->c); + log_assert(repinfo->c->type != comm_tcp_accept); ++#ifdef ENABLE_FASTRPZ ++ rpz_end(repinfo); ++#endif + if(repinfo->c->type == comm_udp) + return; + if(repinfo->c->tcp_req_info) +@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec) + { + verbose(VERB_ALGO, "comm point start listening %d (%d msec)", + c->fd==-1?newfd:c->fd, msec); ++#ifdef ENABLE_FASTRPZ ++ rpz_end(&c->repinfo); ++#endif + if(c->type == comm_tcp_accept && !c->tcp_free) { + /* no use to start listening no free slots. */ + return; +diff --git a/util/netevent.h b/util/netevent.h +index d80c72b3..0233292f 100644 +--- a/util/netevent.h ++++ b/util/netevent.h +@@ -120,6 +120,10 @@ struct comm_reply { + /** return type 0 (none), 4(IP4), 6(IP6) */ + int srctype; + /* DnsCrypt context */ ++#ifdef ENABLE_FASTRPZ ++ /** per-request RPZ state */ ++ struct commreply_rpz* rpz; ++#endif + #ifdef USE_DNSCRYPT + uint8_t client_nonce[crypto_box_HALF_NONCEBYTES]; + uint8_t nmkey[crypto_box_BEFORENMBYTES]; +diff --git a/validator/validator.c b/validator/validator.c +index c3ca0a27..15251988 100644 +--- a/validator/validator.c ++++ b/validator/validator.c +@@ -2761,6 +2761,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, + default: + /* NSEC proof did not work, try next */ + break; ++#ifdef ENABLE_FASTRPZ ++ case sec_status_rpz_rewritten: ++ case sec_status_rpz_drop: ++ fatal_exit("impossible RPZ sec_status"); ++ break; ++#endif + } + + sec = nsec3_prove_nods(qstate->env, ve, +@@ -2794,6 +2800,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, + default: + /* NSEC3 proof did not work */ + break; ++#ifdef ENABLE_FASTRPZ ++ case sec_status_rpz_rewritten: ++ case sec_status_rpz_drop: ++ fatal_exit("impossible RPZ sec_status"); ++ break; ++#endif + } + + /* Apparently, no available NSEC/NSEC3 proved NODATA, so --- contrib/unbound/contrib/libunbound.pc.in.orig +++ contrib/unbound/contrib/libunbound.pc.in @@ -7,7 +7,8 @@ Description: Library with validating, recursive, and caching DNS resolver URL: http://www.unbound.net Version: @PACKAGE_VERSION@ -Requires: -Libs: -L${libdir} -lunbound @SSLLIB@ @LIBS@ -Libs.private: @LDFLAGS@ -Cflags: -I${includedir} +Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@ +Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@ +Libs: -L${libdir} -lunbound +Libs.private: @SSLLIB@ @LIBS@ +Cflags: -I${includedir} --- contrib/unbound/contrib/libunbound.so.conf.orig +++ contrib/unbound/contrib/libunbound.so.conf @@ -0,0 +1,42 @@ +# See ltrace.conf(5) for description of syntax of this file. +typedef ub_type = enum(TYPE_A=1,TYPE_NS=2,TYPE_SOA=6,TYPE_MX=15,TYPE_TXT=16,TYPE_AAAA=28,TYPE_DS=43,TYPE_DNSKEY=48,TYPE_TLSA=52,TYPE_ANY=255); +typedef ub_class = enum(CLASS_IN=1,CLASS_CH=3,CLASS_NONE=254,CLASS_ANY=255); +typedef ub_rcode = enum(RCODE_NOERROR,RCODE_FORMERR,RCODE_SERVFAIL,RCODE_NXDOMAIN,RCODE_NOTIMPL,RCODE_REFUSED,RCODE_YXDOMAIN,RCODE_YXRRSET,RCODE_NXRRSET,RCODE_NOTAUTH,RCODE_NOTZONE); +typedef ub_havedata = enum(no_data, have_data); +typedef ub_nxdomain = enum(name_exists, nxdomain); +typedef ub_secure = enum(not_secure, secure); +typedef ub_bogus = enum(not_bogus, bogus); +typedef ub_result = struct(string, ub_type, ub_class, array(void*,zero)*, array(int,zero)*, string, ub_rcode, void*, int, ub_havedata, ub_nxdomain, ub_secure, ub_bogus, string, int); +typedef ub_ctx = void; +ub_ctx* ub_ctx_create(void); +void ub_ctx_delete(ub_ctx*); +int ub_ctx_set_option(ub_ctx*, string, string); +int ub_ctx_get_option(ub_ctx*, string, +string*); +int ub_ctx_config(ub_ctx*, string); +int ub_ctx_set_fwd(ub_ctx*, string); +int ub_ctx_set_tls(ub_ctx*, bool(int)); +int ub_ctx_set_stub(ub_ctx*, string, string, bool(int)); +int ub_ctx_resolvconf(ub_ctx*, string); +int ub_ctx_hosts(ub_ctx*, string); +int ub_ctx_add_ta(ub_ctx*, string); +int ub_ctx_add_ta_file(ub_ctx*, string); +int ub_ctx_add_ta_autr(ub_ctx*, string); +int ub_ctx_trustedkeys(ub_ctx*, string); +int ub_ctx_debugout(ub_ctx*, void*); +int ub_ctx_debuglevel(ub_ctx*, int); +int ub_ctx_async(ub_ctx*, bool(int)); +int ub_poll(ub_ctx*); +int ub_wait(ub_ctx*); +int ub_fd(ub_ctx*); +int ub_process(ub_ctx*); +int ub_resolve(ub_ctx*, string, ub_type, ub_class, +ub_result**); +int ub_resolve_async(ub_ctx*, string, ub_type, ub_class, void*, void*, +int*); +int ub_cancel(ub_ctx*, int); +void ub_resolve_free(ub_result*); +string ub_strerror(int); +int ub_ctx_print_local_zones(ub_ctx*); +int ub_ctx_zone_add(ub_ctx*, string, string); +int ub_ctx_zone_remove(ub_ctx*, string); +int ub_ctx_data_add(ub_ctx*, string); +int ub_ctx_data_remove(ub_ctx*, string); +string ub_version(void); --- contrib/unbound/contrib/parseunbound.pl.orig +++ contrib/unbound/contrib/parseunbound.pl @@ -91,7 +91,7 @@ $allstats{$inthread}->{outstandingexc} = $4; } elsif ( $line =~ m/info: average recursion processing time ([0-9\.]+) sec/ ) { - $allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to milisec. + $allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to millisec. } elsif ( $line =~ m/info: histogram of recursion processing times/ ) { next; @@ -103,7 +103,7 @@ } elsif ( $line =~ m/info: lower\(secs\) upper\(secs\) recursions/ ) { # since after this line we're unsure if we get these numbers - # at all, we sould consider this marker as the end of the + # at all, we should consider this marker as the end of the # block. Chances that we're parsing a file halfway written # at this stage are small. Bold statement. $donestats{$inthread} = 1; --- contrib/unbound/contrib/redirect-bogus.patch.orig +++ contrib/unbound/contrib/redirect-bogus.patch @@ -0,0 +1,344 @@ +Index: daemon/worker.c +=================================================================== +--- daemon/worker.c (revision 4191) ++++ daemon/worker.c (working copy) +@@ -663,8 +663,21 @@ + if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep, + LDNS_RCODE_SERVFAIL, edns, worker->scratchpad)) + goto bail_out; +- error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, +- qinfo, id, flags, edns); ++ if (qinfo->qtype == LDNS_RR_TYPE_A && ++ worker->env.cfg->redirect_bogus_ipv4) { ++ /* BAD cached */ ++ fixed_address_encode(repinfo->c->buffer, ++ LDNS_RCODE_NOERROR, qinfo, id, flags, edns, ++ worker->env.cfg->redirect_bogus_ipv4); ++ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA && ++ worker->env.cfg->redirect_bogus_ipv6) { ++ fixed_address_encode(repinfo->c->buffer, ++ LDNS_RCODE_NOERROR, qinfo, id, flags, edns, ++ worker->env.cfg->redirect_bogus_ipv6); ++ } else { ++ error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, ++ qinfo, id, flags, edns); ++ } + rrset_array_unlock_touch(worker->env.rrset_cache, + worker->scratchpad, rep->ref, rep->rrset_count); + if(worker->stats.extended) { +Index: doc/unbound.conf.5.in +=================================================================== +--- doc/unbound.conf.5.in (revision 4191) ++++ doc/unbound.conf.5.in (working copy) +@@ -1244,6 +1244,18 @@ + This can make ordinary queries complete (if repeatedly queried for), + and enter the cache, whilst also mitigating the traffic flow by the + factor given. ++.TP 5 ++.B redirect-bogus-ipv4: \fI ++Set a fixed address for DNSSEC failures that are cached ++Instead of responding to A queries with SERVFAIL, respond ++with NOERROR and the address specified here ++The TTL of the response will be 5 seconds ++.TP 5 ++.B redirect-bogus-ipv6: \fI ++Set a fixed address for DNSSEC failures that are cached ++Instead of responding to AAAA queries with SERVFAIL, respond ++with NOERROR and the address specified here ++The TTL of the response will be 5 seconds + .SS "Remote Control Options" + In the + .B remote\-control: +Index: services/mesh.c +=================================================================== +--- services/mesh.c (revision 4191) ++++ services/mesh.c (working copy) +@@ -1006,6 +1006,7 @@ + struct timeval end_time; + struct timeval duration; + int secure; ++ int bogus_override = 0; + /* Copy the client's EDNS for later restore, to make sure the edns + * compare is with the correct edns options. */ + struct edns_data edns_bak = r->edns; +@@ -1016,6 +1017,7 @@ + rcode = LDNS_RCODE_SERVFAIL; + if(m->s.env->cfg->stat_extended) + m->s.env->mesh->ans_bogus++; ++ bogus_override = 1; + } + if(rep && rep->security == sec_status_secure) + secure = 1; +@@ -1047,17 +1049,34 @@ + } else if(rcode) { + m->s.qinfo.qname = r->qname; + m->s.qinfo.local_alias = r->local_alias; +- if(rcode == LDNS_RCODE_SERVFAIL) { +- if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, +- rep, rcode, &r->edns, m->s.region)) +- r->edns.opt_list = NULL; +- } else { +- if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode, +- &r->edns, m->s.region)) +- r->edns.opt_list = NULL; ++ if(bogus_override && m->s.qinfo.qtype == LDNS_RR_TYPE_A && ++ m->s.env->cfg->redirect_bogus_ipv4) { ++ fixed_address_encode(r->query_reply.c->buffer, ++ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid, ++ r->qflags, &r->edns, ++ m->s.env->cfg->redirect_bogus_ipv4); ++ } else if(bogus_override && ++ m->s.qinfo.qtype == LDNS_RR_TYPE_AAAA && ++ m->s.env->cfg->redirect_bogus_ipv6) { ++ fixed_address_encode(r->query_reply.c->buffer, ++ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid, ++ r->qflags, &r->edns, ++ m->s.env->cfg->redirect_bogus_ipv6); ++ } else { ++ if(rcode == LDNS_RCODE_SERVFAIL) { ++ if(!inplace_cb_reply_servfail_call(m->s.env, ++ &m->s.qinfo, &m->s, ++ rep, rcode, &r->edns, m->s.region)) ++ r->edns.opt_list = NULL; ++ } else { ++ if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, ++ &m->s, rep, rcode, &r->edns, ++ m->s.region)) ++ r->edns.opt_list = NULL; ++ } ++ error_encode(r->query_reply.c->buffer, rcode, ++ &m->s.qinfo, r->qid, r->qflags, &r->edns); + } +- error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo, +- r->qid, r->qflags, &r->edns); + comm_point_send_reply(&r->query_reply); + } else { + size_t udp_size = r->edns.udp_size; +Index: util/config_file.c +=================================================================== +--- util/config_file.c (revision 4191) ++++ util/config_file.c (working copy) +@@ -273,6 +273,8 @@ + cfg->ratelimit_factor = 10; + cfg->qname_minimisation = 0; + cfg->qname_minimisation_strict = 0; ++ cfg->redirect_bogus_ipv4 = NULL; ++ cfg->redirect_bogus_ipv6 = NULL; + cfg->shm_enable = 0; + cfg->shm_key = 11777; + cfg->dnscrypt = 0; +@@ -602,6 +604,10 @@ + } + oi[cfg->num_out_ifs++] = d; + cfg->out_ifs = oi; ++ } else if (strcmp(opt, "redirect-bogus-ipv4:") == 0) { ++ cfg->redirect_bogus_ipv4 = strdup(val); ++ } else if (strcmp(opt, "redirect-bogus-ipv6:") == 0) { ++ cfg->redirect_bogus_ipv6 = strdup(val); + } else { + /* unknown or unsupported (from the set_option interface): + * interface, outgoing-interface, access-control, +@@ -1250,6 +1256,12 @@ + free(cfg->dnstap_version); + config_deldblstrlist(cfg->ratelimit_for_domain); + config_deldblstrlist(cfg->ratelimit_below_domain); ++ if (cfg->redirect_bogus_ipv4) { ++ free(cfg->redirect_bogus_ipv4); ++ } ++ if (cfg->redirect_bogus_ipv6) { ++ free(cfg->redirect_bogus_ipv6); ++ } + #ifdef USE_IPSECMOD + free(cfg->ipsecmod_hook); + config_delstrlist(cfg->ipsecmod_whitelist); +Index: util/config_file.h +=================================================================== +--- util/config_file.h (revision 4191) ++++ util/config_file.h (working copy) +@@ -444,6 +444,9 @@ + /** minimise QNAME in strict mode, minimise according to RFC. + * Do not apply fallback */ + int qname_minimisation_strict; ++ /** construct fake responses for DNSSEC failures */ ++ char *redirect_bogus_ipv4; ++ char *redirect_bogus_ipv6; + /** SHM data - true if shm is enabled */ + int shm_enable; + /** SHM data - key for the shm */ +Index: util/configlexer.lex +=================================================================== +--- util/configlexer.lex (revision 4191) ++++ util/configlexer.lex (working copy) +@@ -410,6 +410,8 @@ + response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) } + response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) } + response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) } ++redirect-bogus-ipv4{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV4) } ++redirect-bogus-ipv6{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV6) } + dnscrypt{COLON} { YDVAR(0, VAR_DNSCRYPT) } + dnscrypt-enable{COLON} { YDVAR(1, VAR_DNSCRYPT_ENABLE) } + dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) } +Index: util/configparser.y +=================================================================== +--- util/configparser.y (revision 4191) ++++ util/configparser.y (working copy) +@@ -44,6 +44,7 @@ + #include + #include + ++#include "sldns/str2wire.h" + #include "util/configyyrename.h" + #include "util/config_file.h" + #include "util/net_help.h" +@@ -141,6 +142,7 @@ + %token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW + %token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1 + %token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING ++%token VAR_REDIRECT_BOGUS_IPV4 VAR_REDIRECT_BOGUS_IPV6 + %token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY + %token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER + %token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT +@@ -228,6 +230,7 @@ + server_access_control_tag_data | server_access_control_view | + server_qname_minimisation_strict | server_serve_expired | + server_fake_dsa | server_log_identity | server_use_systemd | ++ server_redirect_bogus_ipv4 | server_redirect_bogus_ipv6 | + server_response_ip_tag | server_response_ip | server_response_ip_data | + server_shm_enable | server_shm_key | server_fake_sha1 | + server_hide_trustanchor | server_trust_anchor_signaling | +@@ -1873,6 +1876,34 @@ + #endif + } + ; ++server_redirect_bogus_ipv4: VAR_REDIRECT_BOGUS_IPV4 STRING_ARG ++ { ++ uint8_t data[4]; ++ size_t data_len = 4; ++ OUTYY(("P(name:%s)\n", $2)); ++ if(cfg_parser->cfg->redirect_bogus_ipv4) { ++ yyerror("redirect-bogus-ipv4, can only use one address"); ++ } ++ if(sldns_str2wire_a_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) { ++ yyerror("redirect-bogus-ipv4, not a valid IPv4 address"); ++ } ++ free(cfg_parser->cfg->redirect_bogus_ipv4); ++ cfg_parser->cfg->redirect_bogus_ipv4 = $2; ++ } ++server_redirect_bogus_ipv6: VAR_REDIRECT_BOGUS_IPV6 STRING_ARG ++ { ++ uint8_t data[16]; ++ size_t data_len = 16; ++ OUTYY(("P(name:%s)\n", $2)); ++ if(cfg_parser->cfg->redirect_bogus_ipv6) { ++ yyerror("redirect-bogus-ipv6, can only use one address"); ++ } ++ if(sldns_str2wire_aaaa_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) { ++ yyerror("redirect-bogus-ipv6, not a valid IPv6 address"); ++ } ++ free(cfg_parser->cfg->redirect_bogus_ipv6); ++ cfg_parser->cfg->redirect_bogus_ipv6 = $2; ++ } + stub_name: VAR_NAME STRING_ARG + { + OUTYY(("P(name:%s)\n", $2)); +Index: util/data/msgencode.c +=================================================================== +--- util/data/msgencode.c (revision 4191) ++++ util/data/msgencode.c (working copy) +@@ -48,6 +48,7 @@ + #include "util/regional.h" + #include "util/net_help.h" + #include "sldns/sbuffer.h" ++#include "sldns/str2wire.h" + #include "services/localzone.h" + + /** return code that means the function ran out of memory. negative so it does +@@ -914,3 +915,63 @@ + attach_edns_record(buf, &es); + } + } ++ ++void ++fixed_address_encode(sldns_buffer* buf, int r, struct query_info* qinfo, ++ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* data) ++{ ++ uint16_t flags; ++ uint8_t addr_data[16]; ++ size_t addr_len = 16; ++ if (qinfo->qtype == LDNS_RR_TYPE_A) { ++ sldns_str2wire_a_buf(data, addr_data, &addr_len); ++ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA) { ++ sldns_str2wire_aaaa_buf(data, addr_data, &addr_len); ++ } else { ++ return error_encode(buf, LDNS_RCODE_NOERROR, qinfo, qid, qflags, edns); ++ } ++ sldns_buffer_clear(buf); ++ sldns_buffer_write(buf, &qid, sizeof(uint16_t)); ++ flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/ ++ flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */ ++ sldns_buffer_write_u16(buf, flags); ++ if(qinfo) flags = 1; ++ else flags = 0; ++ sldns_buffer_write_u16(buf, flags); ++ sldns_buffer_write_u16(buf, 1); ++ flags = 0; ++ sldns_buffer_write(buf, &flags, sizeof(uint16_t)); ++ sldns_buffer_write(buf, &flags, sizeof(uint16_t)); ++ if(qinfo) { ++ // query ++ if(sldns_buffer_current(buf) == qinfo->qname) ++ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len); ++ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len); ++ sldns_buffer_write_u16(buf, qinfo->qtype); ++ sldns_buffer_write_u16(buf, qinfo->qclass); ++ // faked answer ++ if(sldns_buffer_current(buf) == qinfo->qname) ++ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len); ++ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len); ++ sldns_buffer_write_u16(buf, qinfo->qtype); ++ sldns_buffer_write_u16(buf, qinfo->qclass); ++ sldns_buffer_write_u16(buf, 0); ++ // TTL. Should we make this configurable too? ++ sldns_buffer_write_u16(buf, 5); ++ sldns_buffer_write_u16(buf, addr_len); ++ sldns_buffer_write(buf, addr_data, addr_len); ++ fflush(stderr); ++ } ++ sldns_buffer_flip(buf); ++ if(edns) { ++ struct edns_data es = *edns; ++ es.edns_version = EDNS_ADVERTISED_VERSION; ++ es.udp_size = EDNS_ADVERTISED_SIZE; ++ es.ext_rcode = 0; ++ es.bits &= EDNS_DO; ++ if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) > ++ edns->udp_size) ++ return; ++ attach_edns_record(buf, &es); ++ } ++} +Index: util/data/msgencode.h +=================================================================== +--- util/data/msgencode.h (revision 4191) ++++ util/data/msgencode.h (working copy) +@@ -128,4 +128,20 @@ + void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo, + uint16_t qid, uint16_t qflags, struct edns_data* edns); + ++/** ++ * Encode a fixed address response. ++ * This is a fake answer to either an A or AAA query ++ * ++ * It will answer with that address ++ * ++ * @param pkt: where to store the packet. ++ * @param r: RCODE value to encode. ++ * @param qinfo: if not NULL, the query is included. ++ * @param qid: query ID to set in packet. network order. ++ * @param qflags: original query flags (to copy RD and CD bits). host order. ++ * @param edns: if not NULL, this is the query edns info, ++ * and an edns reply is attached. Only attached if EDNS record fits reply. ++ */ ++void fixed_address_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo, ++ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* address); + #endif /* UTIL_DATA_MSGENCODE_H */ --- contrib/unbound/contrib/unbound-fuzzme.patch.orig +++ contrib/unbound/contrib/unbound-fuzzme.patch @@ -0,0 +1,148 @@ +>From cc9b927f8f29d989ddb8415fe6508a538546abca Mon Sep 17 00:00:00 2001 +From: Jacob Hoffman-Andrews +Date: Wed, 2 Jan 2019 22:52:51 -0800 +Subject: [PATCH] Add unbound-fuzzme. + +This is a small program that simply parses a packet provided on stdout, +for the purposes of fuzzing. +--- + .gitignore | 1 + + Makefile.in | 22 ++++++++++++++++++++-- + smallapp/unbound-fuzzme.c | 38 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 59 insertions(+), 2 deletions(-) + create mode 100644 smallapp/unbound-fuzzme.c + +diff --git a/.gitignore b/.gitignore +index f4527fd8..6163f905 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -24,6 +24,7 @@ + /unbound-checkconf + /unbound-control + /unbound-control-setup ++/unbound-fuzzme + /unbound-host + /unbound.h + /asynclook +diff --git a/Makefile.in b/Makefile.in +index af5b10f6..dacf1ab5 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -177,6 +177,10 @@ shm_main.lo remote.lo stats.lo unbound.lo \ + worker.lo @WIN_DAEMON_OBJ@ + DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \ + $(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@ ++FUZZME_SRC=smallapp/unbound-fuzzme.c ++FUZZME_OBJ=unbound-fuzzme.lo ++FUZZME_OBJ_LINK=$(FUZZME_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \ ++$(COMPAT_OBJ) + CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c + CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo + CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \ +@@ -252,6 +256,7 @@ RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \ + rsrc_unbound_checkconf.o + + ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \ ++ $(FUZZME_SRC) \ + $(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \ + $(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \ + $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \ +@@ -259,6 +264,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \ + $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\ + $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) + ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \ ++ $(FUZZME_OBJ) \ + $(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \ + $(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \ + $(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \ +@@ -274,7 +280,7 @@ LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFL + + all: $(COMMON_OBJ) $(ALLTARGET) + +-alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS) $(PYUNBOUND_TARGET) ++alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup unbound-fuzzme$(EXEEXT) $(WINAPPS) $(PYUNBOUND_TARGET) + + # compat with BSD make, register suffix, and an implicit rule to actualise it. + .SUFFIXES: .lo +@@ -325,6 +331,9 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK) + unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la + $(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) + ++unbound-fuzzme$(EXEEXT): $(FUZZME_OBJ_LINK) libunbound.la ++ $(LINK) -o $@ $(FUZZME_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) ++ + unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la + $(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) + +@@ -447,7 +456,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y + + clean: + rm -f *.o *.d *.lo *~ tags +- rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h ++ rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-fuzzme$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h + rm -f $(ALL_SRC:.c=.lint) + rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py + rm -rf autom4te.cache .libs build doc/html doc/xml +@@ -1183,6 +1192,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s + $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ + $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \ + $(srcdir)/validator/val_neg.h ++unbound-fuzzme.lo unbound-fuzzme.o: $(srcdir)/smallapp/unbound-fuzzme.c \ ++ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ ++ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \ ++ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \ ++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \ ++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ ++ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \ ++ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ ++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h + unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \ + $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ + $(srcdir)/daemon/remote.h \ +diff --git a/smallapp/unbound-fuzzme.c b/smallapp/unbound-fuzzme.c +new file mode 100644 +index 00000000..74ae5204 +--- /dev/null ++++ b/smallapp/unbound-fuzzme.c +@@ -0,0 +1,38 @@ ++/* ++ * unbound-fuzzme.c - parse a packet provided on stdin (for fuzzing). ++ * ++ */ ++#include "config.h" ++#include "util/regional.h" ++#include "util/fptr_wlist.h" ++#include "sldns/sbuffer.h" ++ ++#define SZ 10000 ++ ++int main() { ++ char buffer[SZ]; ++ size_t n_read = fread(buffer, 1, SZ, stdin); ++ if (n_read == SZ) { ++ printf("input too big\n"); ++ return 1; ++ } ++ sldns_buffer *pkt = sldns_buffer_new(n_read); ++ sldns_buffer_init_frm_data(pkt, buffer, n_read); ++ ++ struct regional *region = regional_create(); ++ ++ struct msg_parse* prs; ++ struct edns_data edns; ++ prs = (struct msg_parse*)malloc(sizeof(struct msg_parse)); ++ if(!prs) { ++ printf("out of memory on incoming message\n"); ++ return 1; ++ } ++ memset(prs, 0, sizeof(*prs)); ++ memset(&edns, 0, sizeof(edns)); ++ sldns_buffer_set_position(pkt, 0); ++ if(parse_packet(pkt, prs, region) != LDNS_RCODE_NOERROR) { ++ printf("parse error\n"); ++ return 1; ++ } ++} +-- +2.17.1 + --- contrib/unbound/contrib/unbound-querycachedb.py.orig +++ contrib/unbound/contrib/unbound-querycachedb.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + +import hashlib +import sys +import struct +import socket +import time +from optparse import OptionParser + +import dns.message +import dns.name +import dns.rdataclass +import dns.rdatatype + +def _calc_hashkey(qname, secret, qtype): + qclass = 'IN' # CLASS is fixed for simplicity + hobj = hashlib.sha256() + hobj.update(dns.name.from_text(qname).to_wire()) + hobj.update(struct.pack('HH', + socket.htons(dns.rdatatype.from_text(qtype)), + socket.htons(dns.rdataclass.from_text(qclass)))) + hobj.update(secret) + return hobj.hexdigest().upper() + +def _redis_get(options, key): + import redis + return redis.Redis(options.address, int(options.port)).get(key) + +def _dump_value(options, qname, key, value): + print(';; query=%s/IN/%s' % (qname, options.qtype)) + print(';; key=%s' % key) + if value is None: + print(';; no value') + return + if len(value) < 16: + print(';; broken value, short length: %d' % len(value)) + return + now = int(time.time()) + timestamp = struct.unpack('!Q', value[-16:-8])[0] + expire = struct.unpack('!Q', value[-8:])[0] + print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' % + (now, timestamp, expire, max(expire - now, 0))) + print(dns.message.from_wire(value[:-16])) + +def main(): + parser = OptionParser(usage='usage: %prog [options] query_name') + parser.add_option("-a", "--address", dest="address", action="store", + default='127.0.0.1', help="backend-server address", + metavar='ADDRESS') + parser.add_option("-b", "--backend", dest="backend", action="store", + default='redis', help="backend name", + metavar='BACKEND') + parser.add_option("-p", "--port", dest="port", action="store", + default='6379', help="backend-server port", + metavar='PORT') + parser.add_option("-s", "--secret", dest="secret", action="store", + default='default', help="secret seed", metavar='SECRET') + parser.add_option("-t", "--qtype", dest="qtype", action="store", + default='A', help="query RR type", metavar='QTYPE') + + (options, args) = parser.parse_args() + if len(args) < 1: + parser.error('qname is missing') + if options.backend == 'redis': + get_func = _redis_get + else: + raise Exception('unknown backend name: %s\n' % options.backend) + key = _calc_hashkey(args[0], options.secret, options.qtype) + value = get_func(options, key) + _dump_value(options, args[0], key, value) + +if __name__ == '__main__': + try: + main() + except Exception as e: + sys.stderr.write('%s\n' % e) + exit(1) --- contrib/unbound/contrib/unbound.init.orig +++ contrib/unbound/contrib/unbound.init @@ -39,13 +39,13 @@ # setup root jail if [ -s /etc/localtime ]; then [ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ; - if [ ! -e ${rootdir}/etc/localtime ] || /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then + if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then cp -fp /etc/localtime ${rootdir}/etc/localtime fi; fi; if [ -s /etc/resolv.conf ]; then [ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ; - if [ ! -e ${rootdir}/etc/resolv.conf ] || /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then + if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf fi; fi; @@ -54,10 +54,10 @@ [ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1; fi; - if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then + if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then [ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ; - [ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random - mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1; + [ -e ${rootdir}/dev/urandom ] || touch ${rootdir}/dev/urandom + mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1; fi; # if not running, start it up here @@ -78,8 +78,8 @@ if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then umount ${rootdir}/dev/log >/dev/null 2>&1 fi; - if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then - umount ${rootdir}/dev/random >/dev/null 2>&1 + if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then + umount ${rootdir}/dev/urandom >/dev/null 2>&1 fi; return $retval } --- contrib/unbound/contrib/unbound.init_fedora.orig +++ contrib/unbound/contrib/unbound.init_fedora @@ -42,7 +42,7 @@ cp -fp /etc/localtime ${rootdir}/etc/localtime fi; mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1; - mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1; + mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1; mount --bind -n /var/run/unbound ${rootdir}/var/run/unbound >/dev/null 2>&1; # if not running, start it up here @@ -58,7 +58,7 @@ killproc -p $pidfile unbound retval=$? [ $retval -eq 0 ] && rm -f $lockfile - for mountfile in /dev/log /dev/random /etc/localtime /etc/resolv.conf /var/run/unbound + for mountfile in /dev/log /dev/urandom /etc/localtime /etc/resolv.conf /var/run/unbound do if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}''${mountfile}'' /proc/mounts; then umount ${rootdir}$mountfile >/dev/null 2>&1 --- contrib/unbound/contrib/unbound.service.in.orig +++ contrib/unbound/contrib/unbound.service.in @@ -0,0 +1,84 @@ +; For further details about the directives used in this unit file, including +; the below, please refer to systemd's official documentation, available at +; https://www.freedesktop.org/software/systemd/man/systemd.exec.html. +; +; +; - `ProtectSystem=strict` implies we mount the entire file system hierarchy +; read-only for the processes invoked by the unit except for the API file +; system subtrees /dev, /proc and /sys (which are protected by +; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=). +; +; - `PrivateTmp=yes` secures access to temporary files of the process, and +; makes sharing between processes via /tmp or /var/tmp impossible. +; +; - `ProtectHome=yes` makes the directories /home, /root, and /run/user +; inaccessible and empty for processes invoked by the unit. +; +; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies +; (accessible through /sys/fs/cgroup) read-only to all processes invoked by +; the unit. It also implies `MountAPIVFS=yes`. +; +; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the +; unit User and Group with read-write permissions (0755) as soon as the +; unit starts. This allows unbound to store its pidfile. The directory and +; its content are automatically removed by systemd when the unit stops. +; +; - `NoNewPrivileges=yes` ensures that the service process and all its +; children can never gain new privileges through execve(). +; +; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID +; (SUID) or set-group-ID (SGID) bits on files or directories will be denied. +; +; - `RestrictRealTime=yes` ensures that any attempts to enable realtime +; scheduling in a process invoked by the unit will be denied. +; +; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing +; is prohibited. +; +; - `LockPersonality=yes` locks down the personality system call so that the +; kernel execution domain may not be changed from the default. +; +; +[Unit] +Description=Validating, recursive, and caching DNS resolver +Documentation=man:unbound(8) +After=network.target +Before=network-online.target nss-lookup.target +Wants=nss-lookup.target + +[Install] +WantedBy=multi-user.target + +[Service] +ExecReload=+/bin/kill -HUP $MAINPID +ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p +NotifyAccess=main +Type=notify +CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW +MemoryDenyWriteExecute=true +NoNewPrivileges=true +PrivateDevices=true +PrivateTmp=true +ProtectHome=true +ProtectControlGroups=true +ProtectKernelModules=true +ProtectSystem=strict +RuntimeDirectory=unbound +ConfigurationDirectory=unbound +StateDirectory=unbound +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX +RestrictRealtime=true +SystemCallArchitectures=native +SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources +RestrictNamespaces=yes +LockPersonality=yes +RestrictSUIDSGID=yes +ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@ + +# Below rules are needed when chroot is enabled (usually it's enabled by default). +# If chroot is disabled like chrooot: "" then they may be safely removed. +TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro +TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro +BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify +BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom +BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log --- contrib/unbound/contrib/unbound.socket.in.orig +++ contrib/unbound/contrib/unbound.socket.in @@ -0,0 +1,6 @@ +[Socket] +ListenDatagram=127.0.0.1:1153 +ListenStream=127.0.0.1:1153 +# ListenStream=@UNBOUND_RUN_DIR@/control +[Install] +WantedBy=sockets.target --- contrib/unbound/contrib/unbound_munin_.orig +++ contrib/unbound/contrib/unbound_munin_ @@ -150,7 +150,7 @@ fi done # try to get it - echo $$ >$lock + if echo $$ >$lock ; then : ; else break; fi done # do not refetch if the file exists and only LEE seconds old if test -f $state; then @@ -242,6 +242,8 @@ p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE" p_config "num.query.tcp" "TCP queries" "ABSOLUTE" p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE" + p_config "num.query.tls" "TLS queries" "ABSOLUTE" + p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE" p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE" p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE" p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE" @@ -266,7 +268,6 @@ echo "graph_args --base 1024 -l 0" echo "graph_vlabel memory used in bytes" echo "graph_category DNS" - p_config "mem.total.sbrk" "Total memory" "GAUGE" p_config "mem.cache.rrset" "RRset cache memory" "GAUGE" p_config "mem.cache.message" "Message cache memory" "GAUGE" p_config "mem.mod.iterator" "Iterator module memory" "GAUGE" @@ -444,7 +445,8 @@ for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state | sed -e 's/=.*//'` total.num.queries \ total.num.cachehits total.num.prefetch num.query.tcp \ - num.query.tcpout num.query.ipv6 unwanted.queries \ + num.query.tcpout num.query.tls num.query.tls.resume \ + num.query.ipv6 unwanted.queries \ unwanted.replies; do if grep "^"$x"=" $state >/dev/null 2>&1; then print_value $x @@ -458,20 +460,6 @@ done ;; memory) - mn=`echo mem.total.sbrk | sed $ABBREV | tr . _` - get_value 'mem.total.sbrk' - if test $value -eq 0; then - chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'` - pidf=`$chk -o pidfile $conf 2>&1` - pid=`cat $pidf 2>&1` - value=`ps -p "$pid" -o rss= 2>&1` - if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then - value=`expr $value \* 1024` - else - value=0 - fi - fi - echo "$mn.value" $value for x in mem.cache.rrset mem.cache.message mem.mod.iterator \ mem.mod.validator msg.cache.count rrset.cache.count \ infra.cache.count key.cache.count; do --- contrib/unbound/contrib/unbound_portable.service.in.orig +++ contrib/unbound/contrib/unbound_portable.service.in @@ -0,0 +1,49 @@ +; This unit file is provided to run unbound as portable service. +; https://systemd.io/PORTABLE_SERVICES/ +; +; To use this unit file, please make sure you either compile unbound with the +; following options: +; +; - --with-chroot-dir="" +; +; Or put the following options in your unbound configuration file: +; +; - chroot: "" +; +; +[Unit] +Description=Validating, recursive, and caching DNS resolver +Documentation=man:unbound(8) +After=network.target +Before=network-online.target nss-lookup.target +Wants=nss-lookup.target + +[Install] +WantedBy=multi-user.target + +[Service] +ExecReload=+/bin/kill -HUP $MAINPID +ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p +NotifyAccess=main +Type=notify +CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW +MemoryDenyWriteExecute=true +NoNewPrivileges=true +PrivateDevices=true +PrivateTmp=true +ProtectHome=true +ProtectControlGroups=true +ProtectKernelModules=true +ProtectSystem=strict +RuntimeDirectory=unbound +ConfigurationDirectory=unbound +StateDirectory=unbound +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX +RestrictRealtime=true +SystemCallArchitectures=native +SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources +RestrictNamespaces=yes +LockPersonality=yes +RestrictSUIDSGID=yes +BindPaths=/run/systemd/notify +BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout --- contrib/unbound/daemon/acl_list.c.orig +++ contrib/unbound/daemon/acl_list.c @@ -111,6 +111,8 @@ control = acl_refuse_non_local; else if(strcmp(s2, "allow_snoop") == 0) control = acl_allow_snoop; + else if(strcmp(s2, "allow_setrd") == 0) + control = acl_allow_setrd; else { log_err("access control type %s unknown", str); return 0; @@ -170,6 +172,23 @@ return 1; } +/** apply acl_view string */ +static int +acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2, + struct views* vs) +{ + struct acl_addr* node; + if(!(node=acl_find_or_create(acl, str))) + return 0; + node->view = views_find_view(vs, str2, 0 /* get read lock*/); + if(!node->view) { + log_err("no view with name: %s", str2); + return 0; + } + lock_rw_unlock(&node->view->lock); + return 1; +} + /** apply acl_tag_action string */ static int acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg, @@ -210,15 +229,47 @@ /** check wire data parse */ static int -check_data(const char* data) +check_data(const char* data, const struct config_strlist* head) { char buf[65536]; uint8_t rr[LDNS_RR_BUF_SIZE]; size_t len = sizeof(rr); int res; - snprintf(buf, sizeof(buf), "%s %s", "example.com.", data); + /* '.' is sufficient for validation, and it makes the call to + * sldns_wirerr_get_type() simpler below. */ + snprintf(buf, sizeof(buf), "%s %s", ".", data); res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL, 0, NULL, 0); + + /* Reject it if we would end up having CNAME and other data (including + * another CNAME) for the same tag. */ + if(res == 0 && head) { + const char* err_data = NULL; + + if(sldns_wirerr_get_type(rr, len, 1) == LDNS_RR_TYPE_CNAME) { + /* adding CNAME while other data already exists. */ + err_data = data; + } else { + snprintf(buf, sizeof(buf), "%s %s", ".", head->str); + len = sizeof(rr); + res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, + NULL, 0, NULL, 0); + if(res != 0) { + /* This should be impossible here as head->str + * has been validated, but we check it just in + * case. */ + return 0; + } + if(sldns_wirerr_get_type(rr, len, 1) == + LDNS_RR_TYPE_CNAME) /* already have CNAME */ + err_data = head->str; + } + if(err_data) { + log_err("redirect tag data '%s' must not coexist with " + "other data.", err_data); + return 0; + } + } if(res == 0) return 1; log_err("rr data [char %d] parse error %s", @@ -258,7 +309,7 @@ } /* check data? */ - if(!check_data(data)) { + if(!check_data(data, node->tag_datas[tagid])) { log_err("cannot parse access-control-tag data: %s %s '%s'", str, tag, data); return 0; @@ -312,6 +363,27 @@ return 1; } +/** read acl view config */ +static int +read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v) +{ + struct config_str2list* np, *p = cfg->acl_view; + cfg->acl_view = NULL; + while(p) { + log_assert(p->str && p->str2); + if(!acl_list_view_cfg(acl, p->str, p->str2, v)) { + return 0; + } + /* free the items as we go to free up memory */ + np = p->next; + free(p->str); + free(p->str2); + free(p); + p = np; + } + return 1; +} + /** read acl tag actions config */ static int read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg) @@ -362,12 +434,15 @@ } int -acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg) +acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg, + struct views* v) { regional_free_all(acl->region); addr_tree_init(&acl->tree); if(!read_acl_list(acl, cfg)) return 0; + if(!read_acl_view(acl, cfg, v)) + return 0; if(!read_acl_tags(acl, cfg)) return 0; if(!read_acl_tag_actions(acl, cfg)) --- contrib/unbound/daemon/acl_list.h.orig +++ contrib/unbound/daemon/acl_list.h @@ -43,6 +43,7 @@ #ifndef DAEMON_ACL_LIST_H #define DAEMON_ACL_LIST_H #include "util/storage/dnstree.h" +#include "services/view.h" struct config_file; struct regional; @@ -62,7 +63,9 @@ /** allow full access for recursion (+RD) queries */ acl_allow, /** allow full access for all queries, recursion and cache snooping */ - acl_allow_snoop + acl_allow_snoop, + /** allow full access for recursion queries and set RD flag regardless of request */ + acl_allow_setrd }; /** @@ -75,7 +78,7 @@ * Tree of the addresses that are allowed/blocked. * contents of type acl_addr. */ - rbtree_t tree; + rbtree_type tree; }; /** @@ -100,6 +103,8 @@ struct config_strlist** tag_datas; /** size of the tag_datas array */ size_t tag_datas_size; + /* view element, NULL if none */ + struct view* view; }; /** @@ -118,9 +123,11 @@ * Process access control config. * @param acl: where to store. * @param cfg: config options. + * @param v: views structure * @return 0 on error. */ -int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg); +int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg, + struct views* v); /** * Lookup access control status for acl structure. --- contrib/unbound/daemon/cachedump.c.orig +++ contrib/unbound/daemon/cachedump.c @@ -62,7 +62,7 @@ /** dump one rrset zonefile line */ static int -dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) +dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) { char s[65535]; if(!packed_rr_to_string(k, i, now, s, sizeof(s))) { @@ -73,12 +73,13 @@ /** dump rrset key and data info */ static int -dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, +dump_rrset(RES* ssl, struct ub_packed_rrset_key* k, struct packed_rrset_data* d, time_t now) { size_t i; /* rd lock held by caller */ if(!k || !d) return 1; + if(k->id == 0) return 1; /* deleted */ if(d->ttl < now) return 1; /* expired */ /* meta line */ @@ -98,7 +99,7 @@ /** dump lruhash rrset cache */ static int -dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now) +dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now) { struct lruhash_entry* e; /* lruhash already locked by caller */ @@ -117,7 +118,7 @@ /** dump rrset cache */ static int -dump_rrset_cache(SSL* ssl, struct worker* worker) +dump_rrset_cache(RES* ssl, struct worker* worker) { struct rrset_cache* r = worker->env.rrset_cache; size_t slab; @@ -136,7 +137,7 @@ /** dump message to rrset reference */ static int -dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) +dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k) { char* nm, *tp, *cl; nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len); @@ -163,7 +164,7 @@ /** dump message entry */ static int -dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, +dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now) { size_t i; @@ -245,7 +246,7 @@ /** dump lruhash msg cache */ static int -dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h) +dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h) { struct lruhash_entry* e; struct query_info* k; @@ -273,7 +274,7 @@ /** dump msg cache */ static int -dump_msg_cache(SSL* ssl, struct worker* worker) +dump_msg_cache(RES* ssl, struct worker* worker) { struct slabhash* sh = worker->env.msg_cache; size_t slab; @@ -290,7 +291,7 @@ } int -dump_cache(SSL* ssl, struct worker* worker) +dump_cache(RES* ssl, struct worker* worker) { if(!dump_rrset_cache(ssl, worker)) return 0; @@ -301,7 +302,7 @@ /** read a line from ssl into buffer */ static int -ssl_read_buf(SSL* ssl, sldns_buffer* buf) +ssl_read_buf(RES* ssl, sldns_buffer* buf) { return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf), sldns_buffer_capacity(buf)); @@ -309,7 +310,7 @@ /** check fixed text on line */ static int -read_fixed(SSL* ssl, sldns_buffer* buf, const char* str) +read_fixed(RES* ssl, sldns_buffer* buf, const char* str) { if(!ssl_read_buf(ssl, buf)) return 0; return (strcmp((char*)sldns_buffer_begin(buf), str) == 0); @@ -317,7 +318,7 @@ /** load an RR into rrset */ static int -load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region, +load_rr(RES* ssl, sldns_buffer* buf, struct regional* region, struct ub_packed_rrset_key* rk, struct packed_rrset_data* d, unsigned int i, int is_rrsig, int* go_on, time_t now) { @@ -434,7 +435,7 @@ /** load an rrset entry */ static int -load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker) +load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker) { char* s = (char*)sldns_buffer_begin(buf); struct regional* region = worker->scratchpad; @@ -518,7 +519,7 @@ /** load rrset cache */ static int -load_rrset_cache(SSL* ssl, struct worker* worker) +load_rrset_cache(RES* ssl, struct worker* worker) { sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0; @@ -563,6 +564,7 @@ qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len); qinfo->qname_len = dname_len; qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len); + qinfo->local_alias = NULL; if(!qinfo->qname) { log_warn("error out of memory"); return NULL; @@ -573,7 +575,7 @@ /** load a msg rrset reference */ static int -load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, +load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker, struct regional *region, struct ub_packed_rrset_key** rrset, int* go_on) { @@ -618,7 +620,7 @@ /** load a msg entry */ static int -load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) +load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker) { struct regional* region = worker->scratchpad; struct query_info qinf; @@ -651,6 +653,7 @@ rep.qdcount = (uint16_t)qdcount; rep.ttl = (time_t)ttl; rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl); + rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL; rep.security = (enum sec_status)security; if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) { log_warn("error too many rrsets"); @@ -683,7 +686,7 @@ /** load msg cache */ static int -load_msg_cache(SSL* ssl, struct worker* worker) +load_msg_cache(RES* ssl, struct worker* worker) { sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0; @@ -696,7 +699,7 @@ } int -load_cache(SSL* ssl, struct worker* worker) +load_cache(RES* ssl, struct worker* worker) { if(!load_rrset_cache(ssl, worker)) return 0; @@ -707,7 +710,7 @@ /** print details on a delegation point */ static void -print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) +print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp) { char buf[257]; struct delegpt_addr* a; @@ -783,7 +786,7 @@ /** print main dp info */ static void -print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg) +print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg) { size_t i, n_ns, n_miss, n_addr, n_res, n_avail; @@ -811,7 +814,7 @@ return; } -int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, +int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, size_t nmlen, int ATTR_UNUSED(nmlabs)) { /* deep links into the iterator module */ @@ -826,6 +829,7 @@ qinfo.qname_len = nmlen; qinfo.qtype = LDNS_RR_TYPE_A; qinfo.qclass = LDNS_RR_CLASS_IN; + qinfo.local_alias = NULL; dname_str(nm, b); if(!ssl_printf(ssl, "The following name servers are used for lookup " --- contrib/unbound/daemon/cachedump.h.orig +++ contrib/unbound/daemon/cachedump.h @@ -72,6 +72,7 @@ #ifndef DAEMON_DUMPCACHE_H #define DAEMON_DUMPCACHE_H struct worker; +#include "daemon/remote.h" /** * Dump cache(s) to text @@ -80,7 +81,7 @@ * ptrs to the caches. * @return false on ssl print error. */ -int dump_cache(SSL* ssl, struct worker* worker); +int dump_cache(RES* ssl, struct worker* worker); /** * Load cache(s) from text @@ -89,7 +90,7 @@ * ptrs to the caches. * @return false on ssl error. */ -int load_cache(SSL* ssl, struct worker* worker); +int load_cache(RES* ssl, struct worker* worker); /** * Print the delegation used to lookup for this name. @@ -101,7 +102,7 @@ * @param nmlabs: labels in name. * @return false on ssl error. */ -int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, +int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, size_t nmlen, int nmlabs); #endif /* DAEMON_DUMPCACHE_H */ --- contrib/unbound/daemon/daemon.c.orig +++ contrib/unbound/daemon/daemon.c @@ -73,20 +73,29 @@ #include "util/log.h" #include "util/config_file.h" #include "util/data/msgreply.h" +#include "util/shm_side/shm_main.h" #include "util/storage/lookup3.h" #include "util/storage/slabhash.h" +#include "util/tcp_conn_limit.h" #include "services/listen_dnsport.h" #include "services/cache/rrset.h" #include "services/cache/infra.h" #include "services/localzone.h" +#include "services/view.h" #include "services/modstack.h" +#include "services/authzone.h" #include "util/module.h" #include "util/random.h" #include "util/tube.h" #include "util/net_help.h" #include "sldns/keyraw.h" +#include "respip/respip.h" #include +#ifdef HAVE_SYSTEMD +#include +#endif + /** How many quit requests happened. */ static int sig_record_quit = 0; /** How many reload requests happened. */ @@ -96,10 +105,8 @@ /** cleaner ssl memory freeup */ static void* comp_meth = NULL; #endif -#ifdef LEX_HAS_YYLEX_DESTROY /** remove buffers for parsing and init */ int ub_c_lex_destroy(void); -#endif /** used when no other sighandling happens, so we don't die * when multiple signals in quick succession are sent to us. @@ -207,12 +214,16 @@ # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS ERR_load_crypto_strings(); # endif +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) ERR_load_SSL_strings(); +#endif # ifdef USE_GOST (void)sldns_key_EVP_load_gost_id(); # endif # if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) +# ifndef S_SPLINT_S OpenSSL_add_all_algorithms(); +# endif # else OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS @@ -225,7 +236,7 @@ # if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) (void)SSL_library_init(); # else - (void)OPENSSL_init_ssl(0, NULL); + (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); # endif # if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) if(!ub_openssl_lock_init()) @@ -239,8 +250,6 @@ /* init timezone info while we are not chrooted yet */ tzset(); #endif - /* open /dev/random if needed */ - ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67); daemon->need_to_exit = 0; modstack_init(&daemon->mods); if(!(daemon->env = (struct module_env*)calloc(1, @@ -248,16 +257,39 @@ free(daemon); return NULL; } + /* init edns_known_options */ + if(!edns_known_options_init(daemon->env)) { + free(daemon->env); + free(daemon); + return NULL; + } alloc_init(&daemon->superalloc, NULL, 0); daemon->acl = acl_list_create(); if(!daemon->acl) { + edns_known_options_delete(daemon->env); free(daemon->env); free(daemon); return NULL; } + daemon->tcl = tcl_list_create(); + if(!daemon->tcl) { + acl_list_delete(daemon->acl); + edns_known_options_delete(daemon->env); + free(daemon->env); + free(daemon); + return NULL; + } if(gettimeofday(&daemon->time_boot, NULL) < 0) log_err("gettimeofday: %s", strerror(errno)); daemon->time_last_stat = daemon->time_boot; + if((daemon->env->auth_zones = auth_zones_create()) == 0) { + acl_list_delete(daemon->acl); + tcl_list_delete(daemon->tcl); + edns_known_options_delete(daemon->env); + free(daemon->env); + free(daemon); + return NULL; + } return daemon; } @@ -347,6 +379,7 @@ daemon->env)) { fatal_exit("failed to setup modules"); } + log_edns_known_options(VERB_ALGO, daemon->env); } /** @@ -394,13 +427,11 @@ int* shufport; log_assert(daemon && daemon->cfg); if(!daemon->rand) { - unsigned int seed = (unsigned int)time(NULL) ^ - (unsigned int)getpid() ^ 0x438; - daemon->rand = ub_initstate(seed, NULL); + daemon->rand = ub_initstate(NULL); if(!daemon->rand) fatal_exit("could not init random generator"); + hash_set_raninit((uint32_t)ub_random(daemon->rand)); } - hash_set_raninit((uint32_t)ub_random(daemon->rand)); shufport = (int*)calloc(65536, sizeof(int)); if(!shufport) fatal_exit("out of memory during daemon init"); @@ -541,17 +572,71 @@ void daemon_fork(struct daemon* daemon) { + int have_view_respip_cfg = 0; +#ifdef HAVE_SYSTEMD + int ret; +#endif + log_assert(daemon); - if(!acl_list_apply_cfg(daemon->acl, daemon->cfg)) + if(!(daemon->views = views_create())) + fatal_exit("Could not create views: out of memory"); + /* create individual views and their localzone/data trees */ + if(!views_apply_cfg(daemon->views, daemon->cfg)) + fatal_exit("Could not set up views"); + + if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views)) fatal_exit("Could not setup access control list"); + if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg)) + fatal_exit("Could not setup TCP connection limits"); + if(daemon->cfg->dnscrypt) { +#ifdef USE_DNSCRYPT + daemon->dnscenv = dnsc_create(); + if (!daemon->dnscenv) + fatal_exit("dnsc_create failed"); + dnsc_apply_cfg(daemon->dnscenv, daemon->cfg); +#else + fatal_exit("dnscrypt enabled in config but unbound was not built with " + "dnscrypt support"); +#endif + } + /* create global local_zones */ if(!(daemon->local_zones = local_zones_create())) fatal_exit("Could not create local zones: out of memory"); if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg)) fatal_exit("Could not set up local zones"); + /* process raw response-ip configuration data */ + if(!(daemon->respip_set = respip_set_create())) + fatal_exit("Could not create response IP set"); + if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg)) + fatal_exit("Could not set up response IP set"); + if(!respip_views_apply_cfg(daemon->views, daemon->cfg, + &have_view_respip_cfg)) + fatal_exit("Could not set up per-view response IP sets"); + daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) || + have_view_respip_cfg; + + /* read auth zonefiles */ + if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1, + &daemon->use_rpz)) + fatal_exit("auth_zones could not be setup"); + /* setup modules */ daemon_setup_modules(daemon); + /* response-ip-xxx options don't work as expected without the respip + * module. To avoid run-time operational surprise we reject such + * configuration. */ + if(daemon->use_response_ip && + modstack_find(&daemon->mods, "respip") < 0) + fatal_exit("response-ip options require respip module"); + /* RPZ response ip triggers don't work as expected without the respip + * module. To avoid run-time operational surprise we reject such + * configuration. */ + if(daemon->use_rpz && + modstack_find(&daemon->mods, "respip") < 0) + fatal_exit("RPZ requires the respip module"); + /* first create all the worker structures, so we can pass * them to the newly created threads. */ @@ -578,14 +663,34 @@ #endif signal_handling_playback(daemon->workers[0]); + if (!shm_main_init(daemon)) + log_warn("SHM has failed"); + /* Start resolver service on main thread. */ +#ifdef HAVE_SYSTEMD + ret = sd_notify(0, "READY=1"); + if(ret <= 0 && getenv("NOTIFY_SOCKET")) + fatal_exit("sd_notify failed %s: %s. Make sure that unbound has " + "access/permission to use the socket presented by systemd.", + getenv("NOTIFY_SOCKET"), + (ret==0?"no $NOTIFY_SOCKET": strerror(-ret))); +#endif log_info("start of service (%s).", PACKAGE_STRING); worker_work(daemon->workers[0]); +#ifdef HAVE_SYSTEMD + if (daemon->workers[0]->need_to_exit) + sd_notify(0, "STOPPING=1"); + else + sd_notify(0, "RELOADING=1"); +#endif log_info("service stopped (%s).", PACKAGE_STRING); /* we exited! a signal happened! Stop other threads */ daemon_stop_others(daemon); + /* Shutdown SHM */ + shm_main_shutdown(daemon); + daemon->need_to_exit = daemon->workers[0]->need_to_exit; } @@ -605,6 +710,12 @@ slabhash_clear(daemon->env->msg_cache); local_zones_delete(daemon->local_zones); daemon->local_zones = NULL; + respip_set_delete(daemon->respip_set); + daemon->respip_set = NULL; + views_delete(daemon->views); + daemon->views = NULL; + if(daemon->env->auth_zones) + auth_zones_cleanup(daemon->env->auth_zones); /* key cache is cleared by module desetup during next daemon_fork() */ daemon_remote_clear(daemon->rc); for(i=0; inum; i++) @@ -612,9 +723,15 @@ free(daemon->workers); daemon->workers = NULL; daemon->num = 0; + alloc_clear_special(&daemon->superalloc); #ifdef USE_DNSTAP dt_delete(daemon->dtenv); + daemon->dtenv = NULL; #endif +#ifdef USE_DNSCRYPT + dnsc_delete(daemon->dnscenv); + daemon->dnscenv = NULL; +#endif daemon->cfg = NULL; } @@ -634,22 +751,24 @@ slabhash_delete(daemon->env->msg_cache); rrset_cache_delete(daemon->env->rrset_cache); infra_delete(daemon->env->infra_cache); + edns_known_options_delete(daemon->env); + auth_zones_delete(daemon->env->auth_zones); } ub_randfree(daemon->rand); alloc_clear(&daemon->superalloc); acl_list_delete(daemon->acl); + tcl_list_delete(daemon->tcl); free(daemon->chroot); free(daemon->pidfile); free(daemon->env); #ifdef HAVE_SSL + listen_sslctx_delete_ticket_keys(); SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx); SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx); #endif free(daemon); -#ifdef LEX_HAS_YYLEX_DESTROY /* lex cleanup */ ub_c_lex_destroy(); -#endif /* libcrypto cleanup */ #ifdef HAVE_SSL # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) @@ -664,7 +783,7 @@ # endif # ifdef HAVE_OPENSSL_CONFIG EVP_cleanup(); -# if OPENSSL_VERSION_NUMBER < 0x10100000 +# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) ENGINE_cleanup(); # endif CONF_modules_free(); @@ -681,6 +800,9 @@ # if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) ub_openssl_lock_delete(); # endif +#ifndef HAVE_ARC4RANDOM + _ARC4_LOCK_DESTROY(); +#endif #elif defined(HAVE_NSS) NSS_Shutdown(); #endif /* HAVE_SSL or HAVE_NSS */ @@ -697,9 +819,8 @@ { daemon->cfg = cfg; config_apply(cfg); - if(!daemon->env->msg_cache || - cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) || - cfg->msg_cache_slabs != daemon->env->msg_cache->size) { + if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size, + cfg->msg_cache_slabs)) { slabhash_delete(daemon->env->msg_cache); daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs, HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size, --- contrib/unbound/daemon/daemon.h.orig +++ contrib/unbound/daemon/daemon.h @@ -53,8 +53,11 @@ struct rrset_cache; struct acl_list; struct local_zones; +struct views; struct ub_randstate; struct daemon_remote; +struct respip_set; +struct shm_main_info; #include "dnstap/dnstap_config.h" #ifdef USE_DNSTAP @@ -61,6 +64,11 @@ struct dt_env; #endif +#include "dnscrypt/dnscrypt_config.h" +#ifdef USE_DNSCRYPT +struct dnsc_env; +#endif + /** * Structure holding worker list. * Holds globally visible information. @@ -105,6 +113,8 @@ struct module_stack mods; /** access control, which client IPs are allowed to connect */ struct acl_list* acl; + /** TCP connection limit, limit connections from client IPs */ + struct tcl_list* tcl; /** local authority zones */ struct local_zones* local_zones; /** last time of statistics printout */ @@ -111,10 +121,23 @@ struct timeval time_last_stat; /** time when daemon started */ struct timeval time_boot; + /** views structure containing view tree */ + struct views* views; #ifdef USE_DNSTAP /** the dnstap environment master value, copied and changed by threads*/ struct dt_env* dtenv; #endif + struct shm_main_info* shm_info; + /** response-ip set with associated actions and tags. */ + struct respip_set* respip_set; + /** some response-ip tags or actions are configured if true */ + int use_response_ip; + /** some RPZ policies are configured */ + int use_rpz; +#ifdef USE_DNSCRYPT + /** the dnscrypt environment */ + struct dnsc_env* dnscenv; +#endif }; /** --- contrib/unbound/daemon/remote.c.orig +++ contrib/unbound/daemon/remote.c @@ -68,6 +68,8 @@ #include "services/cache/infra.h" #include "services/mesh.h" #include "services/localzone.h" +#include "services/authzone.h" +#include "services/rpz.h" #include "util/storage/slabhash.h" #include "util/fptr_wlist.h" #include "util/data/dname.h" @@ -124,7 +126,7 @@ /** divide sum of timers to get average */ static void -timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d) +timeval_divide(struct timeval* avg, const struct timeval* sum, long long d) { #ifndef S_SPLINT_S size_t leftover; @@ -141,125 +143,20 @@ #endif } -/* - * The following function was generated using the openssl utility, using - * the command : "openssl dhparam -C 2048" - * (some openssl versions reject DH that is 'too small', eg. 512). - */ -#ifndef S_SPLINT_S -static DH *get_dh2048(void) +static int +remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg) { - static unsigned char dh2048_p[]={ - 0xE7,0x36,0x28,0x3B,0xE4,0xC3,0x32,0x1C,0x01,0xC3,0x67,0xD6, - 0xF5,0xF3,0xDA,0xDC,0x71,0xC0,0x42,0x8B,0xE6,0xEB,0x8D,0x80, - 0x35,0x7F,0x09,0x45,0x30,0xE5,0xB2,0x92,0x81,0x3F,0x08,0xCD, - 0x36,0x5E,0x19,0x83,0x62,0xCC,0xAE,0x9B,0x81,0x66,0x24,0xEE, - 0x16,0x6F,0xA9,0x9E,0xF4,0x82,0x1B,0xDD,0x46,0xC7,0x33,0x5D, - 0xF4,0xCA,0xE6,0x8F,0xFC,0xD4,0xD8,0x58,0x94,0x24,0x5D,0xFF, - 0x0A,0xE8,0xEF,0x3D,0xCE,0xBB,0x50,0x94,0xE0,0x5F,0xE8,0x41, - 0xC3,0x35,0x30,0x37,0xD5,0xCB,0x8F,0x3D,0x95,0x15,0x1A,0x77, - 0x42,0xB2,0x06,0x86,0xF6,0x09,0x66,0x0E,0x9A,0x25,0x94,0x3E, - 0xD2,0x04,0x25,0x25,0x1D,0x23,0xEB,0xDC,0x4D,0x0C,0x83,0x28, - 0x2E,0x15,0x81,0x2D,0xC1,0xAF,0x8D,0x36,0x64,0xE3,0x9A,0x83, - 0x78,0xC2,0x8D,0xC0,0x9D,0xD9,0x3A,0x1C,0xC5,0x2B,0x50,0x68, - 0x07,0xA9,0x4B,0x8C,0x07,0x57,0xD6,0x15,0x03,0x4E,0x9E,0x01, - 0xF2,0x6F,0x35,0xAC,0x26,0x9C,0x92,0x68,0x61,0x13,0xFB,0x01, - 0xBA,0x22,0x36,0x01,0x55,0xB6,0x62,0xD9,0xB2,0x98,0xCE,0x5D, - 0x4B,0xA5,0x41,0xD6,0xE5,0x70,0x78,0x12,0x1F,0x64,0xB6,0x6F, - 0xB0,0x91,0x51,0x91,0x92,0xC0,0x94,0x3A,0xD1,0x28,0x4D,0x30, - 0x84,0x3E,0xE4,0xE4,0x7F,0x47,0x89,0xB1,0xB6,0x8C,0x8E,0x0E, - 0x26,0xDB,0xCD,0x17,0x07,0x2A,0x21,0x7A,0xCC,0x68,0xE8,0x57, - 0x94,0x9E,0x59,0x61,0xEC,0x20,0x34,0x26,0x0D,0x66,0x44,0xEB, - 0x6F,0x02,0x58,0xE2,0xED,0xF6,0xF3,0x1B,0xBF,0x9E,0x45,0x52, - 0x5A,0x49,0xA1,0x5B, - }; - static unsigned char dh2048_g[]={ - 0x02, - }; - DH *dh = NULL; - BIGNUM *p = NULL, *g = NULL; - - dh = DH_new(); - p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); - g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); - if (!dh || !p || !g) - goto err; - -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) - dh->p = p; - dh->g = g; -#else - if (!DH_set0_pqg(dh, p, NULL, g)) - goto err; -#endif - return dh; -err: - if (p) - BN_free(p); - if (g) - BN_free(g); - if (dh) - DH_free(dh); - return NULL; -} -#endif /* SPLINT */ - -struct daemon_remote* -daemon_remote_create(struct config_file* cfg) -{ char* s_cert; char* s_key; - struct daemon_remote* rc = (struct daemon_remote*)calloc(1, - sizeof(*rc)); - if(!rc) { - log_err("out of memory in daemon_remote_create"); - return NULL; - } - rc->max_active = 10; - - if(!cfg->remote_control_enable) { - rc->ctx = NULL; - return rc; - } rc->ctx = SSL_CTX_new(SSLv23_server_method()); if(!rc->ctx) { log_crypto_err("could not SSL_CTX_new"); - free(rc); - return NULL; + return 0; } - /* no SSLv2, SSLv3 because has defects */ - if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) - != SSL_OP_NO_SSLv2){ - log_crypto_err("could not set SSL_OP_NO_SSLv2"); - daemon_remote_delete(rc); - return NULL; + if(!listen_sslctx_setup(rc->ctx)) { + return 0; } - if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) - != SSL_OP_NO_SSLv3){ - log_crypto_err("could not set SSL_OP_NO_SSLv3"); - daemon_remote_delete(rc); - return NULL; - } - if (cfg->remote_control_use_cert == 0) { - /* No certificates are requested */ - if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL")) { - log_crypto_err("Failed to set aNULL cipher list"); - daemon_remote_delete(rc); - return NULL; - } - - /* Since we have no certificates and hence no source of - * DH params, let's generate and set them - */ - if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh2048())) { - log_crypto_err("Wanted to set DH param, but failed"); - daemon_remote_delete(rc); - return NULL; - } - return rc; - } - rc->use_cert = 1; s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); s_key = fname_after_chroot(cfg->server_key_file, cfg, 1); if(!s_cert || !s_key) { @@ -282,36 +179,52 @@ log_crypto_err("Error in SSL_CTX check_private_key"); goto setup_error; } -#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO - if(!SSL_CTX_set_ecdh_auto(rc->ctx,1)) { - log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); - } -#elif defined(USE_ECDSA) - if(1) { - EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); - if (!ecdh) { - log_crypto_err("could not find p256, not enabling ECDHE"); - } else { - if (1 != SSL_CTX_set_tmp_ecdh (rc->ctx, ecdh)) { - log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE"); - } - EC_KEY_free (ecdh); - } - } -#endif + listen_sslctx_setup_2(rc->ctx); if(!SSL_CTX_load_verify_locations(rc->ctx, s_cert, NULL)) { log_crypto_err("Error setting up SSL_CTX verify locations"); setup_error: free(s_cert); free(s_key); - daemon_remote_delete(rc); - return NULL; + return 0; } SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert)); SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL); free(s_cert); free(s_key); + return 1; +} +struct daemon_remote* +daemon_remote_create(struct config_file* cfg) +{ + struct daemon_remote* rc = (struct daemon_remote*)calloc(1, + sizeof(*rc)); + if(!rc) { + log_err("out of memory in daemon_remote_create"); + return NULL; + } + rc->max_active = 10; + + if(!cfg->remote_control_enable) { + rc->ctx = NULL; + return rc; + } + if(options_remote_is_address(cfg) && cfg->control_use_cert) { + if(!remote_setup_ctx(rc, cfg)) { + daemon_remote_delete(rc); + return NULL; + } + rc->use_cert = 1; + } else { + struct config_strlist* p; + rc->ctx = NULL; + rc->use_cert = 0; + if(!options_remote_is_address(cfg)) + for(p = cfg->control_ifs.first; p; p = p->next) { + if(p->str && p->str[0] != '/') + log_warn("control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", p->str); + } + } return rc; } @@ -363,16 +276,17 @@ struct addrinfo hints; struct addrinfo* res; struct listen_port* n; - int noproto; + 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)); + log_assert(ip); if(ip[0] == '/') { /* This looks like a local socket */ - fd = create_local_accept_sock(ip, &noproto); + fd = create_local_accept_sock(ip, &noproto, cfg->use_systemd); /* * Change socket ownership and permissions so users other * than root can access it provided they are in the same @@ -383,7 +297,7 @@ if (cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) { if(chown(ip, cfg_uid, cfg_gid) == -1) - log_err("cannot chown %u.%u %s: %s", + verbose(VERB_QUERY, "cannot chown %u.%u %s: %s", (unsigned)cfg_uid, (unsigned)cfg_gid, ip, strerror(errno)); } @@ -415,7 +329,7 @@ /* open fd */ fd = create_tcp_accept_sock(res, 1, &noproto, 0, - cfg->ip_transparent, 0, cfg->ip_freebind); + cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd); freeaddrinfo(res); } @@ -452,9 +366,9 @@ { struct listen_port* l = NULL; log_assert(cfg->remote_control_enable && cfg->control_port); - if(cfg->control_ifs) { + if(cfg->control_ifs.first) { struct config_strlist* p; - for(p = cfg->control_ifs; p; p = p->next) { + for(p = cfg->control_ifs.first; p; p = p->next) { if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) { listening_ports_free(l); return NULL; @@ -561,6 +475,7 @@ log_err("out of memory"); goto close_exit; } + n->fd = newfd; /* start in reading state */ n->c = comm_point_create_raw(rc->worker->base, newfd, 0, &remote_control_callback, n); @@ -575,23 +490,27 @@ comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT); memcpy(&n->c->repinfo.addr, &addr, addrlen); n->c->repinfo.addrlen = addrlen; - n->shake_state = rc_hs_read; - n->ssl = SSL_new(rc->ctx); - if(!n->ssl) { - log_crypto_err("could not SSL_new"); - comm_point_delete(n->c); - free(n); - goto close_exit; + if(rc->use_cert) { + n->shake_state = rc_hs_read; + n->ssl = SSL_new(rc->ctx); + if(!n->ssl) { + log_crypto_err("could not SSL_new"); + comm_point_delete(n->c); + free(n); + goto close_exit; + } + SSL_set_accept_state(n->ssl); + (void)SSL_set_mode(n->ssl, (long)SSL_MODE_AUTO_RETRY); + if(!SSL_set_fd(n->ssl, newfd)) { + log_crypto_err("could not SSL_set_fd"); + SSL_free(n->ssl); + comm_point_delete(n->c); + free(n); + goto close_exit; + } + } else { + n->ssl = NULL; } - SSL_set_accept_state(n->ssl); - (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY); - if(!SSL_set_fd(n->ssl, newfd)) { - log_crypto_err("could not SSL_set_fd"); - SSL_free(n->ssl); - comm_point_delete(n->c); - free(n); - goto close_exit; - } n->rc = rc; n->next = rc->busy_list; @@ -632,20 +551,38 @@ } int -ssl_print_text(SSL* ssl, const char* text) +ssl_print_text(RES* res, const char* text) { int r; - if(!ssl) + if(!res) return 0; - ERR_clear_error(); - if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { - verbose(VERB_QUERY, "warning, in SSL_write, peer " - "closed connection"); + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) { + verbose(VERB_QUERY, "warning, in SSL_write, peer " + "closed connection"); + return 0; + } + log_crypto_err("could not SSL_write"); return 0; } - log_crypto_err("could not SSL_write"); - return 0; + } else { + size_t at = 0; + while(at < strlen(text)) { + ssize_t r = send(res->fd, text+at, strlen(text)-at, 0); + if(r == -1) { + if(errno == EAGAIN || errno == EINTR) + continue; +#ifndef USE_WINSOCK + log_err("could not send: %s", strerror(errno)); +#else + log_err("could not send: %s", wsa_strerror(WSAGetLastError())); +#endif + return 0; + } + at += r; + } } return 1; } @@ -652,7 +589,7 @@ /** print text over the ssl connection */ static int -ssl_print_vmsg(SSL* ssl, const char* format, va_list args) +ssl_print_vmsg(RES* ssl, const char* format, va_list args) { char msg[1024]; vsnprintf(msg, sizeof(msg), format, args); @@ -660,7 +597,7 @@ } /** printf style printing to the ssl connection */ -int ssl_printf(SSL* ssl, const char* format, ...) +int ssl_printf(RES* ssl, const char* format, ...) { va_list args; int ret; @@ -671,21 +608,42 @@ } int -ssl_read_line(SSL* ssl, char* buf, size_t max) +ssl_read_line(RES* res, char* buf, size_t max) { int r; size_t len = 0; - if(!ssl) + if(!res) return 0; while(len < max) { - ERR_clear_error(); - if((r=SSL_read(ssl, buf+len, 1)) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { - buf[len] = 0; - return 1; + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) { + buf[len] = 0; + return 1; + } + log_crypto_err("could not SSL_read"); + return 0; } - log_crypto_err("could not SSL_read"); - return 0; + } else { + while(1) { + ssize_t rr = recv(res->fd, buf+len, 1, 0); + if(rr <= 0) { + if(rr == 0) { + buf[len] = 0; + return 1; + } + if(errno == EINTR || errno == EAGAIN) + continue; +#ifndef USE_WINSOCK + log_err("could not recv: %s", strerror(errno)); +#else + log_err("could not recv: %s", wsa_strerror(WSAGetLastError())); +#endif + return 0; + } + break; + } } if(buf[len] == '\n') { /* return string without \n */ @@ -710,7 +668,7 @@ } /** send the OK to the control client */ -static void send_ok(SSL* ssl) +static void send_ok(RES* ssl) { (void)ssl_printf(ssl, "ok\n"); } @@ -717,25 +675,25 @@ /** do the stop command */ static void -do_stop(SSL* ssl, struct daemon_remote* rc) +do_stop(RES* ssl, struct worker* worker) { - rc->worker->need_to_exit = 1; - comm_base_exit(rc->worker->base); + worker->need_to_exit = 1; + comm_base_exit(worker->base); send_ok(ssl); } /** do the reload command */ static void -do_reload(SSL* ssl, struct daemon_remote* rc) +do_reload(RES* ssl, struct worker* worker) { - rc->worker->need_to_exit = 0; - comm_base_exit(rc->worker->base); + worker->need_to_exit = 0; + comm_base_exit(worker->base); send_ok(ssl); } /** do the verbosity command */ static void -do_verbosity(SSL* ssl, char* str) +do_verbosity(RES* ssl, char* str) { int val = atoi(str); if(val == 0 && strcmp(str, "0") != 0) { @@ -748,11 +706,13 @@ /** print stats from statinfo */ static int -print_stats(SSL* ssl, const char* nm, struct stats_info* s) +print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) { - struct timeval avg; + struct timeval sumwait, avg; if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm, (unsigned long)s->svr.num_queries)) return 0; + if(!ssl_printf(ssl, "%s.num.queries_ip_ratelimited"SQ"%lu\n", nm, + (unsigned long)s->svr.num_queries_ip_ratelimited)) return 0; if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm, (unsigned long)(s->svr.num_queries - s->svr.num_queries_missed_cache))) return 0; @@ -760,12 +720,24 @@ (unsigned long)s->svr.num_queries_missed_cache)) return 0; if(!ssl_printf(ssl, "%s.num.prefetch"SQ"%lu\n", nm, (unsigned long)s->svr.num_queries_prefetch)) return 0; + if(!ssl_printf(ssl, "%s.num.expired"SQ"%lu\n", nm, + (unsigned long)s->svr.ans_expired)) return 0; if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm, (unsigned long)s->mesh_replies_sent)) return 0; +#ifdef USE_DNSCRYPT + if(!ssl_printf(ssl, "%s.num.dnscrypt.crypted"SQ"%lu\n", nm, + (unsigned long)s->svr.num_query_dnscrypt_crypted)) return 0; + if(!ssl_printf(ssl, "%s.num.dnscrypt.cert"SQ"%lu\n", nm, + (unsigned long)s->svr.num_query_dnscrypt_cert)) return 0; + if(!ssl_printf(ssl, "%s.num.dnscrypt.cleartext"SQ"%lu\n", nm, + (unsigned long)s->svr.num_query_dnscrypt_cleartext)) return 0; + if(!ssl_printf(ssl, "%s.num.dnscrypt.malformed"SQ"%lu\n", nm, + (unsigned long)s->svr.num_query_dnscrypt_crypted_malformed)) return 0; +#endif if(!ssl_printf(ssl, "%s.requestlist.avg"SQ"%g\n", nm, (s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)? (double)s->svr.sum_query_list_size/ - (s->svr.num_queries_missed_cache+ + (double)(s->svr.num_queries_missed_cache+ s->svr.num_queries_prefetch) : 0.0)) return 0; if(!ssl_printf(ssl, "%s.requestlist.max"SQ"%lu\n", nm, (unsigned long)s->svr.max_query_list_size)) return 0; @@ -777,7 +749,11 @@ (unsigned long)s->mesh_num_states)) return 0; if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm, (unsigned long)s->mesh_num_reply_states)) return 0; - timeval_divide(&avg, &s->mesh_replies_sum_wait, s->mesh_replies_sent); +#ifndef S_SPLINT_S + sumwait.tv_sec = s->mesh_replies_sum_wait_sec; + sumwait.tv_usec = s->mesh_replies_sum_wait_usec; +#endif + timeval_divide(&avg, &sumwait, s->mesh_replies_sent); if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ ARG_LL "d.%6.6d\n", nm, (long long)avg.tv_sec, (int)avg.tv_usec)) return 0; if(!ssl_printf(ssl, "%s.recursion.time.median"SQ"%g\n", nm, @@ -789,9 +765,9 @@ /** print stats for one thread */ static int -print_thread_stats(SSL* ssl, int i, struct stats_info* s) +print_thread_stats(RES* ssl, int i, struct ub_stats_info* s) { - char nm[16]; + char nm[32]; snprintf(nm, sizeof(nm), "thread%d", i); nm[sizeof(nm)-1]=0; return print_stats(ssl, nm, s); @@ -799,7 +775,7 @@ /** print long number */ static int -print_longnum(SSL* ssl, const char* desc, size_t x) +print_longnum(RES* ssl, const char* desc, size_t x) { if(x > 1024*1024*1024) { /* more than a Gb */ @@ -814,34 +790,38 @@ /** print mem stats */ static int -print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) +print_mem(RES* ssl, struct worker* worker, struct daemon* daemon, + struct ub_stats_info* s) { - int m; - size_t msg, rrset, val, iter; -#ifdef HAVE_SBRK - extern void* unbound_start_brk; - void* cur = sbrk(0); - if(!print_longnum(ssl, "mem.total.sbrk"SQ, - (size_t)((char*)cur - (char*)unbound_start_brk))) return 0; -#endif /* HAVE_SBRK */ + size_t msg, rrset, val, iter, respip; +#ifdef CLIENT_SUBNET + size_t subnet = 0; +#endif /* CLIENT_SUBNET */ +#ifdef USE_IPSECMOD + size_t ipsecmod = 0; +#endif /* USE_IPSECMOD */ +#ifdef USE_DNSCRYPT + size_t dnscrypt_shared_secret = 0; + size_t dnscrypt_nonce = 0; +#endif /* USE_DNSCRYPT */ msg = slabhash_get_mem(daemon->env->msg_cache); rrset = slabhash_get_mem(&daemon->env->rrset_cache->table); - val=0; - iter=0; - m = modstack_find(&worker->env.mesh->mods, "validator"); - if(m != -1) { - fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh-> - mods.mod[m]->get_mem)); - val = (*worker->env.mesh->mods.mod[m]->get_mem) - (&worker->env, m); + val = mod_get_mem(&worker->env, "validator"); + iter = mod_get_mem(&worker->env, "iterator"); + respip = mod_get_mem(&worker->env, "respip"); +#ifdef CLIENT_SUBNET + subnet = mod_get_mem(&worker->env, "subnet"); +#endif /* CLIENT_SUBNET */ +#ifdef USE_IPSECMOD + ipsecmod = mod_get_mem(&worker->env, "ipsecmod"); +#endif /* USE_IPSECMOD */ +#ifdef USE_DNSCRYPT + if(daemon->dnscenv) { + dnscrypt_shared_secret = slabhash_get_mem( + daemon->dnscenv->shared_secrets_cache); + dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache); } - m = modstack_find(&worker->env.mesh->mods, "iterator"); - if(m != -1) { - fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh-> - mods.mod[m]->get_mem)); - iter = (*worker->env.mesh->mods.mod[m]->get_mem) - (&worker->env, m); - } +#endif /* USE_DNSCRYPT */ if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset)) return 0; @@ -851,12 +831,33 @@ return 0; if(!print_longnum(ssl, "mem.mod.validator"SQ, val)) return 0; + if(!print_longnum(ssl, "mem.mod.respip"SQ, respip)) + return 0; +#ifdef CLIENT_SUBNET + if(!print_longnum(ssl, "mem.mod.subnet"SQ, subnet)) + return 0; +#endif /* CLIENT_SUBNET */ +#ifdef USE_IPSECMOD + if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, ipsecmod)) + return 0; +#endif /* USE_IPSECMOD */ +#ifdef USE_DNSCRYPT + if(!print_longnum(ssl, "mem.cache.dnscrypt_shared_secret"SQ, + dnscrypt_shared_secret)) + return 0; + if(!print_longnum(ssl, "mem.cache.dnscrypt_nonce"SQ, + dnscrypt_nonce)) + return 0; +#endif /* USE_DNSCRYPT */ + if(!print_longnum(ssl, "mem.streamwait"SQ, + (size_t)s->svr.mem_stream_wait)) + return 0; return 1; } /** print uptime stats */ static int -print_uptime(SSL* ssl, struct worker* worker, int reset) +print_uptime(RES* ssl, struct worker* worker, int reset) { struct timeval now = *worker->env.now_tv; struct timeval up, dt; @@ -875,7 +876,7 @@ /** print extended histogram */ static int -print_hist(SSL* ssl, struct stats_info* s) +print_hist(RES* ssl, struct ub_stats_info* s) { struct timehist* hist; size_t i; @@ -903,7 +904,7 @@ /** print extended stats */ static int -print_ext(SSL* ssl, struct stats_info* s) +print_ext(RES* ssl, struct ub_stats_info* s) { int i; char nm[16]; @@ -910,7 +911,7 @@ const sldns_rr_descriptor* desc; const sldns_lookup_table* lt; /* TYPE */ - for(i=0; isvr.qtype[i] == 0) continue; desc = sldns_rr_descript((uint16_t)i); @@ -937,7 +938,7 @@ (unsigned long)s->svr.qtype_big)) return 0; } /* CLASS */ - for(i=0; isvr.qclass[i] == 0) continue; lt = sldns_lookup_by_id(sldns_rr_classes, i); @@ -954,7 +955,7 @@ (unsigned long)s->svr.qclass_big)) return 0; } /* OPCODE */ - for(i=0; isvr.qopcode[i] == 0) continue; lt = sldns_lookup_by_id(sldns_opcodes, i); @@ -971,6 +972,10 @@ (unsigned long)s->svr.qtcp)) return 0; if(!ssl_printf(ssl, "num.query.tcpout"SQ"%lu\n", (unsigned long)s->svr.qtcp_outgoing)) return 0; + if(!ssl_printf(ssl, "num.query.tls"SQ"%lu\n", + (unsigned long)s->svr.qtls)) return 0; + if(!ssl_printf(ssl, "num.query.tls.resume"SQ"%lu\n", + (unsigned long)s->svr.qtls_resume)) return 0; if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n", (unsigned long)s->svr.qipv6)) return 0; /* flags */ @@ -996,7 +1001,7 @@ (unsigned long)s->svr.qEDNS_DO)) return 0; /* RCODE */ - for(i=0; i LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0) continue; @@ -1013,6 +1018,9 @@ if(!ssl_printf(ssl, "num.answer.rcode.nodata"SQ"%lu\n", (unsigned long)s->svr.ans_rcode_nodata)) return 0; } + /* iteration */ + if(!ssl_printf(ssl, "num.query.ratelimited"SQ"%lu\n", + (unsigned long)s->svr.queries_ratelimited)) return 0; /* validation */ if(!ssl_printf(ssl, "num.answer.secure"SQ"%lu\n", (unsigned long)s->svr.ans_secure)) return 0; @@ -1020,6 +1028,10 @@ (unsigned long)s->svr.ans_bogus)) return 0; if(!ssl_printf(ssl, "num.rrset.bogus"SQ"%lu\n", (unsigned long)s->svr.rrset_bogus)) return 0; + if(!ssl_printf(ssl, "num.query.aggressive.NOERROR"SQ"%lu\n", + (unsigned long)s->svr.num_neg_cache_noerror)) return 0; + if(!ssl_printf(ssl, "num.query.aggressive.NXDOMAIN"SQ"%lu\n", + (unsigned long)s->svr.num_neg_cache_nxdomain)) return 0; /* threat detection */ if(!ssl_printf(ssl, "unwanted.queries"SQ"%lu\n", (unsigned long)s->svr.unwanted_queries)) return 0; @@ -1034,21 +1046,52 @@ (unsigned)s->svr.infra_cache_count)) return 0; if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n", (unsigned)s->svr.key_cache_count)) return 0; + /* applied RPZ actions */ + for(i=0; isvr.rpz_action[i] == 0) + continue; + if(!ssl_printf(ssl, "num.rpz.action.%s"SQ"%lu\n", + rpz_action_to_string(i), + (unsigned long)s->svr.rpz_action[i])) return 0; + } +#ifdef USE_DNSCRYPT + if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n", + (unsigned)s->svr.shared_secret_cache_count)) return 0; + if(!ssl_printf(ssl, "dnscrypt_nonce.cache.count"SQ"%u\n", + (unsigned)s->svr.nonce_cache_count)) return 0; + if(!ssl_printf(ssl, "num.query.dnscrypt.shared_secret.cachemiss"SQ"%lu\n", + (unsigned long)s->svr.num_query_dnscrypt_secret_missed_cache)) return 0; + if(!ssl_printf(ssl, "num.query.dnscrypt.replay"SQ"%lu\n", + (unsigned long)s->svr.num_query_dnscrypt_replay)) return 0; +#endif /* USE_DNSCRYPT */ + if(!ssl_printf(ssl, "num.query.authzone.up"SQ"%lu\n", + (unsigned long)s->svr.num_query_authzone_up)) return 0; + if(!ssl_printf(ssl, "num.query.authzone.down"SQ"%lu\n", + (unsigned long)s->svr.num_query_authzone_down)) return 0; +#ifdef CLIENT_SUBNET + if(!ssl_printf(ssl, "num.query.subnet"SQ"%lu\n", + (unsigned long)s->svr.num_query_subnet)) return 0; + if(!ssl_printf(ssl, "num.query.subnet_cache"SQ"%lu\n", + (unsigned long)s->svr.num_query_subnet_cache)) return 0; +#endif /* CLIENT_SUBNET */ return 1; } /** do the stats command */ static void -do_stats(SSL* ssl, struct daemon_remote* rc, int reset) +do_stats(RES* ssl, struct worker* worker, int reset) { - struct daemon* daemon = rc->worker->daemon; - struct stats_info total; - struct stats_info s; + struct daemon* daemon = worker->daemon; + struct ub_stats_info total; + struct ub_stats_info s; int i; + memset(&total, 0, sizeof(total)); log_assert(daemon->num > 0); /* gather all thread statistics in one place */ for(i=0; inum; i++) { - server_stats_obtain(rc->worker, daemon->workers[i], &s, reset); + server_stats_obtain(worker, daemon->workers[i], &s, reset); if(!print_thread_stats(ssl, i, &s)) return; if(i == 0) @@ -1059,10 +1102,10 @@ total.mesh_time_median /= (double)daemon->num; if(!print_stats(ssl, "total", &total)) return; - if(!print_uptime(ssl, rc->worker, reset)) + if(!print_uptime(ssl, worker, reset)) return; if(daemon->cfg->stat_extended) { - if(!print_mem(ssl, rc->worker, daemon)) + if(!print_mem(ssl, worker, daemon, &total)) return; if(!print_hist(ssl, &total)) return; @@ -1073,7 +1116,7 @@ /** parse commandline argument domain name */ static int -parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) +parse_arg_name(RES* ssl, char* str, uint8_t** res, size_t* len, int* labs) { uint8_t nm[LDNS_MAX_DOMAINLEN+1]; size_t nmlen = sizeof(nm); @@ -1099,7 +1142,7 @@ /** find second argument, modifies string */ static int -find_arg2(SSL* ssl, char* arg, char** arg2) +find_arg2(RES* ssl, char* arg, char** arg2) { char* as = strchr(arg, ' '); char* at = strchr(arg, '\t'); @@ -1123,8 +1166,8 @@ } /** Add a new zone */ -static void -do_zone_add(SSL* ssl, struct worker* worker, char* arg) +static int +perform_zone_add(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1133,16 +1176,16 @@ enum localzone_type t; struct local_zone* z; if(!find_arg2(ssl, arg, &arg2)) - return; + return 0; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) - return; + return 0; if(!local_zone_str2type(arg2, &t)) { ssl_printf(ssl, "error not a zone type. %s\n", arg2); free(nm); - return; + return 0; } - lock_rw_wrlock(&worker->daemon->local_zones->lock); - if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, + lock_rw_wrlock(&zones->lock); + if((z=local_zones_find(zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* already present in tree */ lock_rw_wrlock(&z->lock); @@ -1149,70 +1192,328 @@ z->type = t; /* update type anyway */ lock_rw_unlock(&z->lock); free(nm); - lock_rw_unlock(&worker->daemon->local_zones->lock); - send_ok(ssl); - return; + lock_rw_unlock(&zones->lock); + return 1; } - if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen, + if(!local_zones_add_zone(zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, t)) { - lock_rw_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&zones->lock); ssl_printf(ssl, "error out of memory\n"); + return 0; + } + lock_rw_unlock(&zones->lock); + return 1; +} + +/** Do the local_zone command */ +static void +do_zone_add(RES* ssl, struct local_zones* zones, char* arg) +{ + if(!perform_zone_add(ssl, zones, arg)) return; - } - lock_rw_unlock(&worker->daemon->local_zones->lock); send_ok(ssl); } -/** Remove a zone */ +/** Do the local_zones command */ static void -do_zone_remove(SSL* ssl, struct worker* worker, char* arg) +do_zones_add(RES* ssl, struct local_zones* zones) { + char buf[2048]; + int num = 0; + while(ssl_read_line(ssl, buf, sizeof(buf))) { + if(buf[0] == 0x04 && buf[1] == 0) + break; /* end of transmission */ + if(!perform_zone_add(ssl, zones, buf)) { + if(!ssl_printf(ssl, "error for input line: %s\n", buf)) + return; + } + else + num++; + } + (void)ssl_printf(ssl, "added %d zones\n", num); +} + +/** Remove a zone */ +static int +perform_zone_remove(RES* ssl, struct local_zones* zones, char* arg) +{ uint8_t* nm; int nmlabs; size_t nmlen; struct local_zone* z; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) - return; - lock_rw_wrlock(&worker->daemon->local_zones->lock); - if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, + return 0; + lock_rw_wrlock(&zones->lock); + if((z=local_zones_find(zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* present in tree */ - local_zones_del_zone(worker->daemon->local_zones, z); + local_zones_del_zone(zones, z); } - lock_rw_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&zones->lock); free(nm); + return 1; +} + +/** Do the local_zone_remove command */ +static void +do_zone_remove(RES* ssl, struct local_zones* zones, char* arg) +{ + if(!perform_zone_remove(ssl, zones, arg)) + return; send_ok(ssl); } +/** Do the local_zones_remove command */ +static void +do_zones_remove(RES* ssl, struct local_zones* zones) +{ + char buf[2048]; + int num = 0; + while(ssl_read_line(ssl, buf, sizeof(buf))) { + if(buf[0] == 0x04 && buf[1] == 0) + break; /* end of transmission */ + if(!perform_zone_remove(ssl, zones, buf)) { + if(!ssl_printf(ssl, "error for input line: %s\n", buf)) + return; + } + else + num++; + } + (void)ssl_printf(ssl, "removed %d zones\n", num); +} + /** Add new RR data */ +static int +perform_data_add(RES* ssl, struct local_zones* zones, char* arg) +{ + if(!local_zones_add_RR(zones, arg)) { + ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg); + return 0; + } + return 1; +} + +/** Do the local_data command */ static void -do_data_add(SSL* ssl, struct worker* worker, char* arg) +do_data_add(RES* ssl, struct local_zones* zones, char* arg) { - if(!local_zones_add_RR(worker->daemon->local_zones, arg)) { - ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg); + if(!perform_data_add(ssl, zones, arg)) return; - } send_ok(ssl); } -/** Remove RR data */ +/** Do the local_datas command */ static void -do_data_remove(SSL* ssl, struct worker* worker, char* arg) +do_datas_add(RES* ssl, struct local_zones* zones) { + char buf[2048]; + int num = 0; + while(ssl_read_line(ssl, buf, sizeof(buf))) { + if(buf[0] == 0x04 && buf[1] == 0) + break; /* end of transmission */ + if(!perform_data_add(ssl, zones, buf)) { + if(!ssl_printf(ssl, "error for input line: %s\n", buf)) + return; + } + else + num++; + } + (void)ssl_printf(ssl, "added %d datas\n", num); +} + +/** Remove RR data */ +static int +perform_data_remove(RES* ssl, struct local_zones* zones, char* arg) +{ uint8_t* nm; int nmlabs; size_t nmlen; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) - return; - local_zones_del_data(worker->daemon->local_zones, nm, + return 0; + local_zones_del_data(zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN); free(nm); + return 1; +} + +/** Do the local_data_remove command */ +static void +do_data_remove(RES* ssl, struct local_zones* zones, char* arg) +{ + if(!perform_data_remove(ssl, zones, arg)) + return; send_ok(ssl); } +/** Do the local_datas_remove command */ +static void +do_datas_remove(RES* ssl, struct local_zones* zones) +{ + char buf[2048]; + int num = 0; + while(ssl_read_line(ssl, buf, sizeof(buf))) { + if(buf[0] == 0x04 && buf[1] == 0) + break; /* end of transmission */ + if(!perform_data_remove(ssl, zones, buf)) { + if(!ssl_printf(ssl, "error for input line: %s\n", buf)) + return; + } + else + num++; + } + (void)ssl_printf(ssl, "removed %d datas\n", num); +} + +/** Add a new zone to view */ +static void +do_view_zone_add(RES* ssl, struct worker* worker, char* arg) +{ + char* arg2; + struct view* v; + if(!find_arg2(ssl, arg, &arg2)) + return; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones) { + if(!(v->local_zones = local_zones_create())){ + lock_rw_unlock(&v->lock); + ssl_printf(ssl,"error out of memory\n"); + return; + } + if(!v->isfirst) { + /* Global local-zone is not used for this view, + * therefore add defaults to this view-specic + * local-zone. */ + struct config_file lz_cfg; + memset(&lz_cfg, 0, sizeof(lz_cfg)); + local_zone_enter_defaults(v->local_zones, &lz_cfg); + } + } + do_zone_add(ssl, v->local_zones, arg2); + lock_rw_unlock(&v->lock); +} + +/** Remove a zone from view */ +static void +do_view_zone_remove(RES* ssl, struct worker* worker, char* arg) +{ + char* arg2; + struct view* v; + if(!find_arg2(ssl, arg, &arg2)) + return; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones) { + lock_rw_unlock(&v->lock); + send_ok(ssl); + return; + } + do_zone_remove(ssl, v->local_zones, arg2); + lock_rw_unlock(&v->lock); +} + +/** Add new RR data to view */ +static void +do_view_data_add(RES* ssl, struct worker* worker, char* arg) +{ + char* arg2; + struct view* v; + if(!find_arg2(ssl, arg, &arg2)) + return; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones) { + if(!(v->local_zones = local_zones_create())){ + lock_rw_unlock(&v->lock); + ssl_printf(ssl,"error out of memory\n"); + return; + } + } + do_data_add(ssl, v->local_zones, arg2); + lock_rw_unlock(&v->lock); +} + +/** Add new RR data from stdin to view */ +static void +do_view_datas_add(RES* ssl, struct worker* worker, char* arg) +{ + struct view* v; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones) { + if(!(v->local_zones = local_zones_create())){ + lock_rw_unlock(&v->lock); + ssl_printf(ssl,"error out of memory\n"); + return; + } + } + do_datas_add(ssl, v->local_zones); + lock_rw_unlock(&v->lock); +} + +/** Remove RR data from view */ +static void +do_view_data_remove(RES* ssl, struct worker* worker, char* arg) +{ + char* arg2; + struct view* v; + if(!find_arg2(ssl, arg, &arg2)) + return; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones) { + lock_rw_unlock(&v->lock); + send_ok(ssl); + return; + } + do_data_remove(ssl, v->local_zones, arg2); + lock_rw_unlock(&v->lock); +} + +/** Remove RR data from stdin from view */ +static void +do_view_datas_remove(RES* ssl, struct worker* worker, char* arg) +{ + struct view* v; + v = views_find_view(worker->daemon->views, + arg, 1 /* get write lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(!v->local_zones){ + lock_rw_unlock(&v->lock); + ssl_printf(ssl, "removed 0 datas\n"); + return; + } + + do_datas_remove(ssl, v->local_zones); + lock_rw_unlock(&v->lock); +} + /** cache lookup of nameservers */ static void -do_lookup(SSL* ssl, struct worker* worker, char* arg) +do_lookup(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1228,7 +1529,7 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen, uint16_t t, uint16_t c) { - hashvalue_t h; + hashvalue_type h; struct query_info k; rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0); if(t == LDNS_RR_TYPE_SOA) @@ -1238,6 +1539,7 @@ k.qname_len = nmlen; k.qtype = t; k.qclass = c; + k.local_alias = NULL; h = query_info_hash(&k, 0); slabhash_remove(worker->env.msg_cache, h, &k); if(t == LDNS_RR_TYPE_AAAA) { @@ -1249,7 +1551,7 @@ /** flush a type */ static void -do_flush_type(SSL* ssl, struct worker* worker, char* arg) +do_flush_type(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1269,7 +1571,7 @@ /** flush statistics */ static void -do_flush_stats(SSL* ssl, struct worker* worker) +do_flush_stats(RES* ssl, struct worker* worker) { worker_stats_clear(worker); send_ok(ssl); @@ -1324,7 +1626,7 @@ /** flush infra cache */ static void -do_flush_infra(SSL* ssl, struct worker* worker, char* arg) +do_flush_infra(RES* ssl, struct worker* worker, char* arg) { struct sockaddr_storage addr; socklen_t len; @@ -1358,7 +1660,7 @@ /** flush requestlist */ static void -do_flush_requestlist(SSL* ssl, struct worker* worker) +do_flush_requestlist(RES* ssl, struct worker* worker) { mesh_delete_all(worker->env.mesh); send_ok(ssl); @@ -1392,6 +1694,8 @@ struct reply_info* d = (struct reply_info*)e->data; if(d->ttl > inf->expired) { d->ttl = inf->expired; + d->prefetch_ttl = inf->expired; + d->serve_expired_ttl = inf->expired; inf->num_msgs++; } } @@ -1415,7 +1719,7 @@ /** remove all rrsets and keys from zone from cache */ static void -do_flush_zone(SSL* ssl, struct worker* worker, char* arg) +do_flush_zone(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1493,7 +1797,7 @@ /** remove all bogus rrsets, msgs and keys from cache */ static void -do_flush_bogus(SSL* ssl, struct worker* worker) +do_flush_bogus(RES* ssl, struct worker* worker) { struct del_info inf; /* what we do is to set them all expired */ @@ -1528,7 +1832,7 @@ struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key; struct packed_rrset_data* d = (struct packed_rrset_data*)e->data; /* delete the parentside negative cache rrsets, - * these are namerserver rrsets that failed lookup, rdata empty */ + * these are nameserver rrsets that failed lookup, rdata empty */ if((k->rk.flags & PACKED_RRSET_PARENT_SIDE) && d->count == 1 && d->rrsig_count == 0 && d->rr_len[0] == 0) { d->ttl = inf->expired; @@ -1568,7 +1872,7 @@ /** remove all negative(NODATA,NXDOMAIN), and servfail messages from cache */ static void -do_flush_negative(SSL* ssl, struct worker* worker) +do_flush_negative(RES* ssl, struct worker* worker) { struct del_info inf; /* what we do is to set them all expired */ @@ -1596,7 +1900,7 @@ /** remove name rrset from cache */ static void -do_flush_name(SSL* ssl, struct worker* w, char* arg) +do_flush_name(RES* ssl, struct worker* w, char* arg) { uint8_t* nm; int nmlabs; @@ -1620,7 +1924,7 @@ /** printout a delegation point info */ static int -ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, +ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt* dp) { char buf[257]; @@ -1654,7 +1958,7 @@ /** print root forwards */ static int -print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root) +print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root) { struct delegpt* dp; dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN); @@ -1667,7 +1971,7 @@ /** parse args into delegpt */ static struct delegpt* -parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names) +parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names) { /* parse args and add in */ char* p = args; @@ -1675,6 +1979,7 @@ struct delegpt* dp = delegpt_create_mlc(nm); struct sockaddr_storage addr; socklen_t addrlen; + char* auth_name; if(!dp) { (void)ssl_printf(ssl, "error out of memory\n"); return NULL; @@ -1687,7 +1992,7 @@ p = skipwhite(p); /* position at next spot */ } /* parse address */ - if(!extstrtoaddr(todo, &addr, &addrlen)) { + if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) { if(allow_names) { uint8_t* n = NULL; size_t ln; @@ -1714,8 +2019,14 @@ return NULL; } } else { +#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) + if(auth_name) + log_err("no name verification functionality in " + "ssl library, ignored name for %s", todo); +#endif /* add address */ - if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) { + if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0, + auth_name)) { (void)ssl_printf(ssl, "error out of memory\n"); delegpt_free_mlc(dp); return NULL; @@ -1728,7 +2039,7 @@ /** do the status command */ static void -do_forward(SSL* ssl, struct worker* worker, char* args) +do_forward(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; uint8_t* root = (uint8_t*)"\000"; @@ -1759,7 +2070,7 @@ } static int -parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp, +parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp, int* insecure, int* prime) { char* zonename; @@ -1804,7 +2115,7 @@ /** do the forward_add command */ static void -do_forward_add(SSL* ssl, struct worker* worker, char* args) +do_forward_add(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -1832,7 +2143,7 @@ /** do the forward_remove command */ static void -do_forward_remove(SSL* ssl, struct worker* worker, char* args) +do_forward_remove(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -1849,7 +2160,7 @@ /** do the stub_add command */ static void -do_stub_add(SSL* ssl, struct worker* worker, char* args) +do_stub_add(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0, prime = 0; @@ -1890,7 +2201,7 @@ /** do the stub_remove command */ static void -do_stub_remove(SSL* ssl, struct worker* worker, char* args) +do_stub_remove(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -1908,7 +2219,7 @@ /** do the insecure_add command */ static void -do_insecure_add(SSL* ssl, struct worker* worker, char* arg) +do_insecure_add(RES* ssl, struct worker* worker, char* arg) { size_t nmlen; int nmlabs; @@ -1929,7 +2240,7 @@ /** do the insecure_remove command */ static void -do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) +do_insecure_remove(RES* ssl, struct worker* worker, char* arg) { size_t nmlen; int nmlabs; @@ -1944,7 +2255,7 @@ } static void -do_insecure_list(SSL* ssl, struct worker* worker) +do_insecure_list(RES* ssl, struct worker* worker) { char buf[257]; struct trust_anchor* a; @@ -1960,7 +2271,7 @@ /** do the status command */ static void -do_status(SSL* ssl, struct worker* worker) +do_status(RES* ssl, struct worker* worker) { int i; time_t uptime; @@ -1981,9 +2292,12 @@ uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec; if(!ssl_printf(ssl, "uptime: " ARG_LL "d seconds\n", (long long)uptime)) return; - if(!ssl_printf(ssl, "options:%s%s\n" , + if(!ssl_printf(ssl, "options:%s%s%s%s\n" , (worker->daemon->reuseport?" reuseport":""), - (worker->daemon->rc->accept_list?" control(ssl)":""))) + (worker->daemon->rc->accept_list?" control":""), + (worker->daemon->rc->accept_list && worker->daemon->rc->use_cert?"(ssl)":""), + (worker->daemon->rc->accept_list && worker->daemon->cfg->control_ifs.first && worker->daemon->cfg->control_ifs.first->str && worker->daemon->cfg->control_ifs.first->str[0] == '/'?"(namedpipe)":"") + )) return; if(!ssl_printf(ssl, "unbound (pid %d) is running...\n", (int)getpid())) @@ -2065,7 +2379,7 @@ /** do the dump_requestlist command */ static void -do_dump_requestlist(SSL* ssl, struct worker* worker) +do_dump_requestlist(RES* ssl, struct worker* worker) { struct mesh_area* mesh; struct mesh_state* m; @@ -2104,7 +2418,7 @@ /** the infra cache */ struct infra_cache* infra; /** the SSL connection */ - SSL* ssl; + RES* ssl; /** the time now */ time_t now; /** ssl failure? stop writing and skip the rest. If the tcp @@ -2121,10 +2435,16 @@ struct infra_data* d = (struct infra_data*)e->data; char ip_str[1024]; char name[257]; + int port; if(a->ssl_failed) return; addr_to_str(&k->addr, k->addrlen, ip_str, sizeof(ip_str)); dname_str(k->zonename, name); + port = (int)ntohs(((struct sockaddr_in*)&k->addr)->sin_port); + if(port != UNBOUND_DNS_PORT) { + snprintf(ip_str+strlen(ip_str), sizeof(ip_str)-strlen(ip_str), + "@%d", port); + } /* skip expired stuff (only backed off) */ if(d->ttl < a->now) { if(d->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { @@ -2153,7 +2473,7 @@ /** do the dump_infra command */ static void -do_dump_infra(SSL* ssl, struct worker* worker) +do_dump_infra(RES* ssl, struct worker* worker) { struct infra_arg arg; arg.infra = worker->env.infra_cache; @@ -2165,7 +2485,7 @@ /** do the log_reopen command */ static void -do_log_reopen(SSL* ssl, struct worker* worker) +do_log_reopen(RES* ssl, struct worker* worker) { struct config_file* cfg = worker->env.cfg; send_ok(ssl); @@ -2172,9 +2492,62 @@ log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); } +/** do the auth_zone_reload command */ +static void +do_auth_zone_reload(RES* ssl, struct worker* worker, char* arg) +{ + size_t nmlen; + int nmlabs; + uint8_t* nm = NULL; + struct auth_zones* az = worker->env.auth_zones; + struct auth_zone* z = NULL; + if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if(az) { + lock_rw_rdlock(&az->lock); + z = auth_zone_find(az, nm, nmlen, LDNS_RR_CLASS_IN); + if(z) { + lock_rw_wrlock(&z->lock); + } + lock_rw_unlock(&az->lock); + } + free(nm); + if(!z) { + (void)ssl_printf(ssl, "error no auth-zone %s\n", arg); + return; + } + if(!auth_zone_read_zonefile(z, worker->env.cfg)) { + lock_rw_unlock(&z->lock); + (void)ssl_printf(ssl, "error failed to read %s\n", arg); + return; + } + lock_rw_unlock(&z->lock); + send_ok(ssl); +} + +/** do the auth_zone_transfer command */ +static void +do_auth_zone_transfer(RES* ssl, struct worker* worker, char* arg) +{ + size_t nmlen; + int nmlabs; + uint8_t* nm = NULL; + struct auth_zones* az = worker->env.auth_zones; + if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if(!az || !auth_zones_startprobesequence(az, &worker->env, nm, nmlen, + LDNS_RR_CLASS_IN)) { + (void)ssl_printf(ssl, "error zone xfr task not found %s\n", arg); + free(nm); + return; + } + free(nm); + send_ok(ssl); +} + /** do the set_option command */ static void -do_set_option(SSL* ssl, struct worker* worker, char* arg) +do_set_option(RES* ssl, struct worker* worker, char* arg) { char* arg2; if(!find_arg2(ssl, arg, &arg2)) @@ -2183,6 +2556,14 @@ (void)ssl_printf(ssl, "error setting option\n"); return; } + /* effectuate some arguments */ + if(strcmp(arg, "val-override-date:") == 0) { + int m = modstack_find(&worker->env.mesh->mods, "validator"); + struct val_env* val_env = NULL; + if(m != -1) val_env = (struct val_env*)worker->env.modinfo[m]; + if(val_env) + val_env->date_override = worker->env.cfg->val_date_override; + } send_ok(ssl); } @@ -2189,13 +2570,13 @@ /* routine to printout option values over SSL */ void remote_get_opt_ssl(char* line, void* arg) { - SSL* ssl = (SSL*)arg; + RES* ssl = (RES*)arg; (void)ssl_printf(ssl, "%s\n", line); } /** do the get_option command */ static void -do_get_option(SSL* ssl, struct worker* worker, char* arg) +do_get_option(RES* ssl, struct worker* worker, char* arg) { int r; r = config_get_option(worker->env.cfg, arg, remote_get_opt_ssl, ssl); @@ -2207,7 +2588,7 @@ /** do the list_forwards command */ static void -do_list_forwards(SSL* ssl, struct worker* worker) +do_list_forwards(RES* ssl, struct worker* worker) { /* since its a per-worker structure no locks needed */ struct iter_forwards* fwds = worker->env.fwds; @@ -2235,7 +2616,7 @@ /** do the list_stubs command */ static void -do_list_stubs(SSL* ssl, struct worker* worker) +do_list_stubs(RES* ssl, struct worker* worker) { struct iter_hints_stub* z; struct trust_anchor* a; @@ -2261,11 +2642,40 @@ } } +/** do the list_auth_zones command */ +static void +do_list_auth_zones(RES* ssl, struct auth_zones* az) +{ + struct auth_zone* z; + char buf[257], buf2[256]; + lock_rw_rdlock(&az->lock); + RBTREE_FOR(z, struct auth_zone*, &az->ztree) { + lock_rw_rdlock(&z->lock); + dname_str(z->name, buf); + if(z->zone_expired) + snprintf(buf2, sizeof(buf2), "expired"); + else { + uint32_t serial = 0; + if(auth_zone_get_serial(z, &serial)) + snprintf(buf2, sizeof(buf2), "serial %u", + (unsigned)serial); + else snprintf(buf2, sizeof(buf2), "no serial"); + } + if(!ssl_printf(ssl, "%s\t%s\n", buf, buf2)) { + /* failure to print */ + lock_rw_unlock(&z->lock); + lock_rw_unlock(&az->lock); + return; + } + lock_rw_unlock(&z->lock); + } + lock_rw_unlock(&az->lock); +} + /** do the list_local_zones command */ static void -do_list_local_zones(SSL* ssl, struct worker* worker) +do_list_local_zones(RES* ssl, struct local_zones* zones) { - struct local_zones* zones = worker->daemon->local_zones; struct local_zone* z; char buf[257]; lock_rw_rdlock(&zones->lock); @@ -2286,9 +2696,8 @@ /** do the list_local_data command */ static void -do_list_local_data(SSL* ssl, struct worker* worker) +do_list_local_data(RES* ssl, struct worker* worker, struct local_zones* zones) { - struct local_zones* zones = worker->daemon->local_zones; struct local_zone* z; struct local_data* d; struct local_rrset* p; @@ -2324,12 +2733,44 @@ lock_rw_unlock(&zones->lock); } +/** do the view_list_local_zones command */ +static void +do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg) +{ + struct view* v = views_find_view(worker->daemon->views, + arg, 0 /* get read lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(v->local_zones) { + do_list_local_zones(ssl, v->local_zones); + } + lock_rw_unlock(&v->lock); +} + +/** do the view_list_local_data command */ +static void +do_view_list_local_data(RES* ssl, struct worker* worker, char* arg) +{ + struct view* v = views_find_view(worker->daemon->views, + arg, 0 /* get read lock*/); + if(!v) { + ssl_printf(ssl,"no view with name: %s\n", arg); + return; + } + if(v->local_zones) { + do_list_local_data(ssl, worker, v->local_zones); + } + lock_rw_unlock(&v->lock); +} + /** struct for user arg ratelimit list */ struct ratelimit_list_arg { /** the infra cache */ struct infra_cache* infra; /** the SSL to print to */ - SSL* ssl; + RES* ssl; /** all or only ratelimited */ int all; /** current time */ @@ -2336,6 +2777,8 @@ time_t now; }; +#define ip_ratelimit_list_arg ratelimit_list_arg + /** list items in the ratelimit table */ static void rate_list(struct lruhash_entry* e, void* arg) @@ -2354,9 +2797,27 @@ ssl_printf(a->ssl, "%s %d limit %d\n", buf, max, lim); } +/** list items in the ip_ratelimit table */ +static void +ip_rate_list(struct lruhash_entry* e, void* arg) +{ + char ip[128]; + struct ip_ratelimit_list_arg* a = (struct ip_ratelimit_list_arg*)arg; + struct ip_rate_key* k = (struct ip_rate_key*)e->key; + struct ip_rate_data* d = (struct ip_rate_data*)e->data; + int lim = infra_ip_ratelimit; + int max = infra_rate_max(d, a->now); + if(a->all == 0) { + if(max < lim) + return; + } + addr_to_str(&k->addr, k->addrlen, ip, sizeof(ip)); + ssl_printf(a->ssl, "%s %d limit %d\n", ip, max, lim); +} + /** do the ratelimit_list command */ static void -do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) +do_ratelimit_list(RES* ssl, struct worker* worker, char* arg) { struct ratelimit_list_arg a; a.all = 0; @@ -2372,9 +2833,27 @@ slabhash_traverse(a.infra->domain_rates, 0, rate_list, &a); } +/** do the ip_ratelimit_list command */ +static void +do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg) +{ + struct ip_ratelimit_list_arg a; + a.all = 0; + a.infra = worker->env.infra_cache; + a.now = *worker->env.now; + a.ssl = ssl; + arg = skipwhite(arg); + if(strcmp(arg, "+a") == 0) + a.all = 1; + if(a.infra->client_ip_rates==NULL || + (a.all == 0 && infra_ip_ratelimit == 0)) + return; + slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a); +} + /** tell other processes to execute the command */ static void -distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd) +distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd) { int i; if(!cmd || !ssl) @@ -2400,22 +2879,22 @@ /** execute a remote control command */ static void -execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, +execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, struct worker* worker) { char* p = skipwhite(cmd); /* compare command */ if(cmdcmp(p, "stop", 4)) { - do_stop(ssl, rc); + do_stop(ssl, worker); return; } else if(cmdcmp(p, "reload", 6)) { - do_reload(ssl, rc); + do_reload(ssl, worker); return; } else if(cmdcmp(p, "stats_noreset", 13)) { - do_stats(ssl, rc, 0); + do_stats(ssl, worker, 0); return; } else if(cmdcmp(p, "stats", 5)) { - do_stats(ssl, rc, 1); + do_stats(ssl, worker, 1); return; } else if(cmdcmp(p, "status", 6)) { do_status(ssl, worker); @@ -2436,14 +2915,32 @@ do_insecure_list(ssl, worker); return; } else if(cmdcmp(p, "list_local_zones", 16)) { - do_list_local_zones(ssl, worker); + do_list_local_zones(ssl, worker->daemon->local_zones); return; } else if(cmdcmp(p, "list_local_data", 15)) { - do_list_local_data(ssl, worker); + do_list_local_data(ssl, worker, worker->daemon->local_zones); return; + } else if(cmdcmp(p, "view_list_local_zones", 21)) { + do_view_list_local_zones(ssl, worker, skipwhite(p+21)); + return; + } else if(cmdcmp(p, "view_list_local_data", 20)) { + do_view_list_local_data(ssl, worker, skipwhite(p+20)); + return; } else if(cmdcmp(p, "ratelimit_list", 14)) { do_ratelimit_list(ssl, worker, p+14); return; + } else if(cmdcmp(p, "ip_ratelimit_list", 17)) { + do_ip_ratelimit_list(ssl, worker, p+17); + return; + } else if(cmdcmp(p, "list_auth_zones", 15)) { + do_list_auth_zones(ssl, worker->env.auth_zones); + return; + } else if(cmdcmp(p, "auth_zone_reload", 16)) { + do_auth_zone_reload(ssl, worker, skipwhite(p+16)); + return; + } else if(cmdcmp(p, "auth_zone_transfer", 18)) { + do_auth_zone_transfer(ssl, worker, skipwhite(p+18)); + return; } else if(cmdcmp(p, "stub_add", 8)) { /* must always distribute this cmd */ if(rc) distribute_cmd(rc, ssl, cmd); @@ -2505,13 +3002,33 @@ if(cmdcmp(p, "verbosity", 9)) { do_verbosity(ssl, skipwhite(p+9)); } else if(cmdcmp(p, "local_zone_remove", 17)) { - do_zone_remove(ssl, worker, skipwhite(p+17)); + do_zone_remove(ssl, worker->daemon->local_zones, skipwhite(p+17)); + } else if(cmdcmp(p, "local_zones_remove", 18)) { + do_zones_remove(ssl, worker->daemon->local_zones); } else if(cmdcmp(p, "local_zone", 10)) { - do_zone_add(ssl, worker, skipwhite(p+10)); + do_zone_add(ssl, worker->daemon->local_zones, skipwhite(p+10)); + } else if(cmdcmp(p, "local_zones", 11)) { + do_zones_add(ssl, worker->daemon->local_zones); } else if(cmdcmp(p, "local_data_remove", 17)) { - do_data_remove(ssl, worker, skipwhite(p+17)); + do_data_remove(ssl, worker->daemon->local_zones, skipwhite(p+17)); + } else if(cmdcmp(p, "local_datas_remove", 18)) { + do_datas_remove(ssl, worker->daemon->local_zones); } else if(cmdcmp(p, "local_data", 10)) { - do_data_add(ssl, worker, skipwhite(p+10)); + do_data_add(ssl, worker->daemon->local_zones, skipwhite(p+10)); + } else if(cmdcmp(p, "local_datas", 11)) { + do_datas_add(ssl, worker->daemon->local_zones); + } else if(cmdcmp(p, "view_local_zone_remove", 22)) { + do_view_zone_remove(ssl, worker, skipwhite(p+22)); + } else if(cmdcmp(p, "view_local_zone", 15)) { + do_view_zone_add(ssl, worker, skipwhite(p+15)); + } else if(cmdcmp(p, "view_local_data_remove", 22)) { + do_view_data_remove(ssl, worker, skipwhite(p+22)); + } else if(cmdcmp(p, "view_local_datas_remove", 23)){ + do_view_datas_remove(ssl, worker, skipwhite(p+23)); + } else if(cmdcmp(p, "view_local_data", 15)) { + do_view_data_add(ssl, worker, skipwhite(p+15)); + } else if(cmdcmp(p, "view_local_datas", 16)) { + do_view_datas_add(ssl, worker, skipwhite(p+16)); } else if(cmdcmp(p, "flush_zone", 10)) { do_flush_zone(ssl, worker, skipwhite(p+10)); } else if(cmdcmp(p, "flush_type", 10)) { @@ -2556,7 +3073,7 @@ /** handle remote control request */ static void -handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) +handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res) { int r; char pre[10]; @@ -2570,12 +3087,31 @@ fd_set_block(s->c->fd); /* try to read magic UBCT[version]_space_ string */ - ERR_clear_error(); - if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) + return; + log_crypto_err("could not SSL_read"); return; - log_crypto_err("could not SSL_read"); - return; + } + } else { + while(1) { + ssize_t rr = recv(res->fd, magic, sizeof(magic)-1, 0); + if(rr <= 0) { + if(rr == 0) return; + if(errno == EINTR || errno == EAGAIN) + continue; +#ifndef USE_WINSOCK + log_err("could not recv: %s", strerror(errno)); +#else + log_err("could not recv: %s", wsa_strerror(WSAGetLastError())); +#endif + return; + } + r = (int)rr; + break; + } } magic[6] = 0; if( r != 6 || strncmp(magic, "UBCT", 4) != 0) { @@ -2585,7 +3121,7 @@ } /* read the command line */ - if(!ssl_read_line(ssl, buf, sizeof(buf))) { + if(!ssl_read_line(res, buf, sizeof(buf))) { return; } snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION); @@ -2592,18 +3128,51 @@ if(strcmp(magic, pre) != 0) { verbose(VERB_QUERY, "control connection had bad " "version %s, cmd: %s", magic, buf); - ssl_printf(ssl, "error version mismatch\n"); + ssl_printf(res, "error version mismatch\n"); return; } verbose(VERB_DETAIL, "control cmd: %s", buf); /* figure out what to do */ - execute_cmd(rc, ssl, buf, rc->worker); + execute_cmd(rc, res, buf, rc->worker); } +/** handle SSL_do_handshake changes to the file descriptor to wait for later */ +static int +remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, + struct comm_point* c, int r, int r2) +{ + if(r2 == SSL_ERROR_WANT_READ) { + if(s->shake_state == rc_hs_read) { + /* try again later */ + return 0; + } + s->shake_state = rc_hs_read; + comm_point_listen_for_rw(c, 1, 0); + return 0; + } else if(r2 == SSL_ERROR_WANT_WRITE) { + if(s->shake_state == rc_hs_write) { + /* try again later */ + return 0; + } + s->shake_state = rc_hs_write; + comm_point_listen_for_rw(c, 0, 1); + return 0; + } else { + if(r == 0) + log_err("remote control connection closed prematurely"); + log_addr(VERB_OPS, "failed connection from", + &s->c->repinfo.addr, s->c->repinfo.addrlen); + log_crypto_err("remote control failed ssl"); + clean_point(rc, s); + } + return 0; +} + int remote_control_callback(struct comm_point* c, void* arg, int err, struct comm_reply* ATTR_UNUSED(rep)) { + RES res; struct rc_state* s = (struct rc_state*)arg; struct daemon_remote* rc = s->rc; int r; @@ -2613,38 +3182,16 @@ clean_point(rc, s); return 0; } - /* (continue to) setup the SSL connection */ - ERR_clear_error(); - r = SSL_do_handshake(s->ssl); - if(r != 1) { - int r2 = SSL_get_error(s->ssl, r); - if(r2 == SSL_ERROR_WANT_READ) { - if(s->shake_state == rc_hs_read) { - /* try again later */ - return 0; - } - s->shake_state = rc_hs_read; - comm_point_listen_for_rw(c, 1, 0); - return 0; - } else if(r2 == SSL_ERROR_WANT_WRITE) { - if(s->shake_state == rc_hs_write) { - /* try again later */ - return 0; - } - s->shake_state = rc_hs_write; - comm_point_listen_for_rw(c, 0, 1); - return 0; - } else { - if(r == 0) - log_err("remote control connection closed prematurely"); - log_addr(1, "failed connection from", - &s->c->repinfo.addr, s->c->repinfo.addrlen); - log_crypto_err("remote control failed ssl"); - clean_point(rc, s); - return 0; + if(s->ssl) { + /* (continue to) setup the SSL connection */ + ERR_clear_error(); + r = SSL_do_handshake(s->ssl); + if(r != 1) { + int r2 = SSL_get_error(s->ssl, r); + return remote_handshake_later(rc, s, c, r, r2); } + s->shake_state = rc_none; } - s->shake_state = rc_none; /* once handshake has completed, check authentication */ if (!rc->use_cert) { @@ -2667,7 +3214,9 @@ } /* if OK start to actually handle the request */ - handle_req(rc, s, s->ssl); + res.ssl = s->ssl; + res.fd = c->fd; + handle_req(rc, s, &res); verbose(VERB_ALGO, "remote control operation completed"); clean_point(rc, s); --- contrib/unbound/daemon/remote.h.orig +++ contrib/unbound/daemon/remote.h @@ -73,6 +73,8 @@ /** the ssl state */ SSL* ssl; #endif + /** file descriptor */ + int fd; /** the rc this is part of */ struct daemon_remote* rc; }; @@ -104,6 +106,19 @@ }; /** + * Connection to print to, either SSL or plain over fd + */ +struct remote_stream { +#ifdef HAVE_SSL + /** SSL structure, nonNULL if using SSL */ + SSL* ssl; +#endif + /** file descriptor for plain transfer */ + int fd; +}; +typedef struct remote_stream RES; + +/** * Create new remote control state for the daemon. * @param cfg: config file with key file settings. * @return new state, or NULL on failure. @@ -166,26 +181,26 @@ * @param text: the text. * @return false on connection failure. */ -int ssl_print_text(SSL* ssl, const char* text); +int ssl_print_text(RES* ssl, const char* text); /** * printf style printing to the ssl connection - * @param ssl: the SSL connection to print to. Blocking. + * @param ssl: the RES connection to print to. Blocking. * @param format: printf style format string. * @return success or false on a network failure. */ -int ssl_printf(SSL* ssl, const char* format, ...) +int ssl_printf(RES* ssl, const char* format, ...) ATTR_FORMAT(printf, 2, 3); /** * Read until \n is encountered - * If SSL signals EOF, the string up to then is returned (without \n). - * @param ssl: the SSL connection to read from. blocking. + * If stream signals EOF, the string up to then is returned (without \n). + * @param ssl: the RES connection to read from. blocking. * @param buf: buffer to read to. * @param max: size of buffer. * @return false on connection failure. */ -int ssl_read_line(SSL* ssl, char* buf, size_t max); +int ssl_read_line(RES* ssl, char* buf, size_t max); #endif /* HAVE_SSL */ #endif /* DAEMON_REMOTE_H */ --- contrib/unbound/daemon/stats.c.orig +++ contrib/unbound/daemon/stats.c @@ -56,72 +56,134 @@ #include "util/timehist.h" #include "util/net_help.h" #include "validator/validator.h" +#include "iterator/iterator.h" #include "sldns/sbuffer.h" #include "services/cache/rrset.h" #include "services/cache/infra.h" +#include "services/authzone.h" #include "validator/val_kcache.h" +#include "validator/val_neg.h" +#ifdef CLIENT_SUBNET +#include "edns-subnet/subnetmod.h" +#endif +#ifdef HAVE_SSL +#include +#endif /** add timers and the values do not overflow or become negative */ static void -timeval_add(struct timeval* d, const struct timeval* add) +stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec) { #ifndef S_SPLINT_S - d->tv_sec += add->tv_sec; - d->tv_usec += add->tv_usec; - if(d->tv_usec > 1000000) { - d->tv_usec -= 1000000; - d->tv_sec++; + (*d_sec) += add_sec; + (*d_usec) += add_usec; + if((*d_usec) >= 1000000) { + (*d_usec) -= 1000000; + (*d_sec)++; } #endif } -void server_stats_init(struct server_stats* stats, struct config_file* cfg) +void server_stats_init(struct ub_server_stats* stats, struct config_file* cfg) { memset(stats, 0, sizeof(*stats)); stats->extended = cfg->stat_extended; } -void server_stats_querymiss(struct server_stats* stats, struct worker* worker) +void server_stats_querymiss(struct ub_server_stats* stats, struct worker* worker) { stats->num_queries_missed_cache++; stats->sum_query_list_size += worker->env.mesh->all.count; - if(worker->env.mesh->all.count > stats->max_query_list_size) - stats->max_query_list_size = worker->env.mesh->all.count; + if((long long)worker->env.mesh->all.count > stats->max_query_list_size) + stats->max_query_list_size = (long long)worker->env.mesh->all.count; } -void server_stats_prefetch(struct server_stats* stats, struct worker* worker) +void server_stats_prefetch(struct ub_server_stats* stats, struct worker* worker) { stats->num_queries_prefetch++; /* changes the query list size so account that, like a querymiss */ stats->sum_query_list_size += worker->env.mesh->all.count; - if(worker->env.mesh->all.count > stats->max_query_list_size) - stats->max_query_list_size = worker->env.mesh->all.count; + if((long long)worker->env.mesh->all.count > stats->max_query_list_size) + stats->max_query_list_size = (long long)worker->env.mesh->all.count; } -void server_stats_log(struct server_stats* stats, struct worker* worker, +void server_stats_log(struct ub_server_stats* stats, struct worker* worker, int threadnum) { log_info("server stats for thread %d: %u queries, " - "%u answers from cache, %u recursions, %u prefetch", + "%u answers from cache, %u recursions, %u prefetch, %u rejected by " + "ip ratelimiting", threadnum, (unsigned)stats->num_queries, (unsigned)(stats->num_queries - stats->num_queries_missed_cache), (unsigned)stats->num_queries_missed_cache, - (unsigned)stats->num_queries_prefetch); + (unsigned)stats->num_queries_prefetch, + (unsigned)stats->num_queries_ip_ratelimited); log_info("server stats for thread %d: requestlist max %u avg %g " "exceeded %u jostled %u", threadnum, (unsigned)stats->max_query_list_size, (stats->num_queries_missed_cache+stats->num_queries_prefetch)? (double)stats->sum_query_list_size/ - (stats->num_queries_missed_cache+ + (double)(stats->num_queries_missed_cache+ stats->num_queries_prefetch) : 0.0, (unsigned)worker->env.mesh->stats_dropped, (unsigned)worker->env.mesh->stats_jostled); } + +#ifdef CLIENT_SUBNET +/** Set the EDNS Subnet stats. */ +static void +set_subnet_stats(struct worker* worker, struct ub_server_stats* svr, + int reset) +{ + int m = modstack_find(&worker->env.mesh->mods, "subnet"); + struct subnet_env* sne; + if(m == -1) + return; + sne = (struct subnet_env*)worker->env.modinfo[m]; + if(reset && !worker->env.cfg->stat_cumulative) { + lock_rw_wrlock(&sne->biglock); + } else { + lock_rw_rdlock(&sne->biglock); + } + svr->num_query_subnet = (long long)(sne->num_msg_nocache + sne->num_msg_cache); + svr->num_query_subnet_cache = (long long)sne->num_msg_cache; + if(reset && !worker->env.cfg->stat_cumulative) { + sne->num_msg_cache = 0; + sne->num_msg_nocache = 0; + } + lock_rw_unlock(&sne->biglock); +} +#endif /* CLIENT_SUBNET */ + +/** Set the neg cache stats. */ +static void +set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr, + int reset) +{ + int m = modstack_find(&worker->env.mesh->mods, "validator"); + struct val_env* ve; + struct val_neg_cache* neg; + if(m == -1) + return; + ve = (struct val_env*)worker->env.modinfo[m]; + if(!ve->neg_cache) + return; + neg = ve->neg_cache; + lock_basic_lock(&neg->lock); + svr->num_neg_cache_noerror = (long long)neg->num_neg_cache_noerror; + svr->num_neg_cache_nxdomain = (long long)neg->num_neg_cache_nxdomain; + if(reset && !worker->env.cfg->stat_cumulative) { + neg->num_neg_cache_noerror = 0; + neg->num_neg_cache_nxdomain = 0; + } + lock_basic_unlock(&neg->lock); +} + /** get rrsets bogus number from validator */ static size_t -get_rrset_bogus(struct worker* worker) +get_rrset_bogus(struct worker* worker, int reset) { int m = modstack_find(&worker->env.mesh->mods, "validator"); struct val_env* ve; @@ -131,56 +193,164 @@ ve = (struct val_env*)worker->env.modinfo[m]; lock_basic_lock(&ve->bogus_lock); r = ve->num_rrset_bogus; - if(!worker->env.cfg->stat_cumulative) + if(reset && !worker->env.cfg->stat_cumulative) ve->num_rrset_bogus = 0; lock_basic_unlock(&ve->bogus_lock); return r; } +/** get number of ratelimited queries from iterator */ +static size_t +get_queries_ratelimit(struct worker* worker, int reset) +{ + int m = modstack_find(&worker->env.mesh->mods, "iterator"); + struct iter_env* ie; + size_t r; + if(m == -1) + return 0; + ie = (struct iter_env*)worker->env.modinfo[m]; + lock_basic_lock(&ie->queries_ratelimit_lock); + r = ie->num_queries_ratelimited; + if(reset && !worker->env.cfg->stat_cumulative) + ie->num_queries_ratelimited = 0; + lock_basic_unlock(&ie->queries_ratelimit_lock); + return r; +} + +#ifdef USE_DNSCRYPT +/** get the number of shared secret cache miss */ +static size_t +get_dnscrypt_cache_miss(struct worker* worker, int reset) +{ + size_t r; + struct dnsc_env* de = worker->daemon->dnscenv; + if(!de) return 0; + + lock_basic_lock(&de->shared_secrets_cache_lock); + r = de->num_query_dnscrypt_secret_missed_cache; + if(reset && !worker->env.cfg->stat_cumulative) + de->num_query_dnscrypt_secret_missed_cache = 0; + lock_basic_unlock(&de->shared_secrets_cache_lock); + return r; +} + +/** get the number of replayed queries */ +static size_t +get_dnscrypt_replay(struct worker* worker, int reset) +{ + size_t r; + struct dnsc_env* de = worker->daemon->dnscenv; + + lock_basic_lock(&de->nonces_cache_lock); + r = de->num_query_dnscrypt_replay; + if(reset && !worker->env.cfg->stat_cumulative) + de->num_query_dnscrypt_replay = 0; + lock_basic_unlock(&de->nonces_cache_lock); + return r; +} +#endif /* USE_DNSCRYPT */ + void -server_stats_compile(struct worker* worker, struct stats_info* s, int reset) +server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) { int i; struct listen_list* lp; s->svr = worker->stats; - s->mesh_num_states = worker->env.mesh->all.count; - s->mesh_num_reply_states = worker->env.mesh->num_reply_states; - s->mesh_jostled = worker->env.mesh->stats_jostled; - s->mesh_dropped = worker->env.mesh->stats_dropped; - s->mesh_replies_sent = worker->env.mesh->replies_sent; - s->mesh_replies_sum_wait = worker->env.mesh->replies_sum_wait; + s->mesh_num_states = (long long)worker->env.mesh->all.count; + s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states; + s->mesh_jostled = (long long)worker->env.mesh->stats_jostled; + s->mesh_dropped = (long long)worker->env.mesh->stats_dropped; + s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent; + s->mesh_replies_sum_wait_sec = (long long)worker->env.mesh->replies_sum_wait.tv_sec; + s->mesh_replies_sum_wait_usec = (long long)worker->env.mesh->replies_sum_wait.tv_usec; s->mesh_time_median = timehist_quartile(worker->env.mesh->histogram, 0.50); /* add in the values from the mesh */ - s->svr.ans_secure += worker->env.mesh->ans_secure; - s->svr.ans_bogus += worker->env.mesh->ans_bogus; - s->svr.ans_rcode_nodata += worker->env.mesh->ans_nodata; - for(i=0; i<16; i++) - s->svr.ans_rcode[i] += worker->env.mesh->ans_rcode[i]; + s->svr.ans_secure += (long long)worker->env.mesh->ans_secure; + s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus; + s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata; + for(i=0; isvr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i]; + for(i=0; isvr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i]; timehist_export(worker->env.mesh->histogram, s->svr.hist, NUM_BUCKETS_HIST); /* values from outside network */ - s->svr.unwanted_replies = worker->back->unwanted_replies; - s->svr.qtcp_outgoing = worker->back->num_tcp_outgoing; + s->svr.unwanted_replies = (long long)worker->back->unwanted_replies; + s->svr.qtcp_outgoing = (long long)worker->back->num_tcp_outgoing; /* get and reset validator rrset bogus number */ - s->svr.rrset_bogus = get_rrset_bogus(worker); + s->svr.rrset_bogus = (long long)get_rrset_bogus(worker, reset); + /* get and reset iterator query ratelimit number */ + s->svr.queries_ratelimited = (long long)get_queries_ratelimit(worker, reset); + /* get cache sizes */ - s->svr.msg_cache_count = count_slabhash_entries(worker->env.msg_cache); - s->svr.rrset_cache_count = count_slabhash_entries(&worker->env.rrset_cache->table); - s->svr.infra_cache_count = count_slabhash_entries(worker->env.infra_cache->hosts); + s->svr.msg_cache_count = (long long)count_slabhash_entries(worker->env.msg_cache); + s->svr.rrset_cache_count = (long long)count_slabhash_entries(&worker->env.rrset_cache->table); + s->svr.infra_cache_count = (long long)count_slabhash_entries(worker->env.infra_cache->hosts); if(worker->env.key_cache) - s->svr.key_cache_count = count_slabhash_entries(worker->env.key_cache->slab); + s->svr.key_cache_count = (long long)count_slabhash_entries(worker->env.key_cache->slab); else s->svr.key_cache_count = 0; +#ifdef USE_DNSCRYPT + if(worker->daemon->dnscenv) { + s->svr.num_query_dnscrypt_secret_missed_cache = + (long long)get_dnscrypt_cache_miss(worker, reset); + s->svr.shared_secret_cache_count = (long long)count_slabhash_entries( + worker->daemon->dnscenv->shared_secrets_cache); + s->svr.nonce_cache_count = (long long)count_slabhash_entries( + worker->daemon->dnscenv->nonces_cache); + s->svr.num_query_dnscrypt_replay = + (long long)get_dnscrypt_replay(worker, reset); + } else { + s->svr.num_query_dnscrypt_secret_missed_cache = 0; + s->svr.shared_secret_cache_count = 0; + s->svr.nonce_cache_count = 0; + s->svr.num_query_dnscrypt_replay = 0; + } +#else + s->svr.num_query_dnscrypt_secret_missed_cache = 0; + s->svr.shared_secret_cache_count = 0; + s->svr.nonce_cache_count = 0; + s->svr.num_query_dnscrypt_replay = 0; +#endif /* USE_DNSCRYPT */ + if(worker->env.auth_zones) { + if(reset && !worker->env.cfg->stat_cumulative) { + lock_rw_wrlock(&worker->env.auth_zones->lock); + } else { + lock_rw_rdlock(&worker->env.auth_zones->lock); + } + s->svr.num_query_authzone_up = (long long)worker->env. + auth_zones->num_query_up; + s->svr.num_query_authzone_down = (long long)worker->env. + auth_zones->num_query_down; + if(reset && !worker->env.cfg->stat_cumulative) { + worker->env.auth_zones->num_query_up = 0; + worker->env.auth_zones->num_query_down = 0; + } + lock_rw_unlock(&worker->env.auth_zones->lock); + } + s->svr.mem_stream_wait = + (long long)tcp_req_info_get_stream_buffer_size(); + + /* Set neg cache usage numbers */ + set_neg_cache_stats(worker, &s->svr, reset); +#ifdef CLIENT_SUBNET + /* EDNS Subnet usage numbers */ + set_subnet_stats(worker, &s->svr, reset); +#else + s->svr.num_query_subnet = 0; + s->svr.num_query_subnet_cache = 0; +#endif + /* get tcp accept usage */ s->svr.tcp_accept_usage = 0; for(lp = worker->front->cps; lp; lp = lp->next) { if(lp->com->type == comm_tcp_accept) - s->svr.tcp_accept_usage += lp->com->cur_tcp_count; + s->svr.tcp_accept_usage += (long long)lp->com->cur_tcp_count; } if(reset && !worker->env.cfg->stat_cumulative) { @@ -189,7 +359,7 @@ } void server_stats_obtain(struct worker* worker, struct worker* who, - struct stats_info* s, int reset) + struct ub_stats_info* s, int reset) { uint8_t *reply = NULL; uint32_t len = 0; @@ -215,7 +385,7 @@ void server_stats_reply(struct worker* worker, int reset) { - struct stats_info s; + struct ub_stats_info s; server_stats_compile(worker, &s, reset); verbose(VERB_ALGO, "write stats replymsg"); if(!tube_write_msg(worker->daemon->workers[0]->cmd, @@ -223,12 +393,22 @@ fatal_exit("could not write stat values over cmd channel"); } -void server_stats_add(struct stats_info* total, struct stats_info* a) +void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) { total->svr.num_queries += a->svr.num_queries; + total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited; total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache; total->svr.num_queries_prefetch += a->svr.num_queries_prefetch; total->svr.sum_query_list_size += a->svr.sum_query_list_size; + total->svr.ans_expired += a->svr.ans_expired; +#ifdef USE_DNSCRYPT + total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted; + total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert; + total->svr.num_query_dnscrypt_cleartext += \ + a->svr.num_query_dnscrypt_cleartext; + total->svr.num_query_dnscrypt_crypted_malformed += \ + a->svr.num_query_dnscrypt_crypted_malformed; +#endif /* USE_DNSCRYPT */ /* the max size reached is upped to higher of both */ if(a->svr.max_query_list_size > total->svr.max_query_list_size) total->svr.max_query_list_size = a->svr.max_query_list_size; @@ -239,6 +419,8 @@ total->svr.qclass_big += a->svr.qclass_big; total->svr.qtcp += a->svr.qtcp; total->svr.qtcp_outgoing += a->svr.qtcp_outgoing; + total->svr.qtls += a->svr.qtls; + total->svr.qtls_resume += a->svr.qtls_resume; total->svr.qipv6 += a->svr.qipv6; total->svr.qbit_QR += a->svr.qbit_QR; total->svr.qbit_AA += a->svr.qbit_AA; @@ -253,20 +435,21 @@ total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata; total->svr.ans_secure += a->svr.ans_secure; total->svr.ans_bogus += a->svr.ans_bogus; - total->svr.rrset_bogus += a->svr.rrset_bogus; total->svr.unwanted_replies += a->svr.unwanted_replies; total->svr.unwanted_queries += a->svr.unwanted_queries; total->svr.tcp_accept_usage += a->svr.tcp_accept_usage; - for(i=0; isvr.qtype[i] += a->svr.qtype[i]; - for(i=0; isvr.qclass[i] += a->svr.qclass[i]; - for(i=0; isvr.qopcode[i] += a->svr.qopcode[i]; - for(i=0; isvr.ans_rcode[i] += a->svr.ans_rcode[i]; for(i=0; isvr.hist[i] += a->svr.hist[i]; + for(i=0; isvr.rpz_action[i] += a->svr.rpz_action[i]; } total->mesh_num_states += a->mesh_num_states; @@ -274,7 +457,7 @@ total->mesh_jostled += a->mesh_jostled; total->mesh_dropped += a->mesh_dropped; total->mesh_replies_sent += a->mesh_replies_sent; - timeval_add(&total->mesh_replies_sum_wait, &a->mesh_replies_sum_wait); + stats_timeval_add(&total->mesh_replies_sum_wait_sec, &total->mesh_replies_sum_wait_usec, a->mesh_replies_sum_wait_sec, a->mesh_replies_sum_wait_usec); /* the medians are averaged together, this is not as accurate as * taking the median over all of the data, but is good and fast * added up here, division later*/ @@ -281,20 +464,28 @@ total->mesh_time_median += a->mesh_time_median; } -void server_stats_insquery(struct server_stats* stats, struct comm_point* c, +void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c, uint16_t qtype, uint16_t qclass, struct edns_data* edns, struct comm_reply* repinfo) { uint16_t flags = sldns_buffer_read_u16_at(c->buffer, 2); - if(qtype < STATS_QTYPE_NUM) + if(qtype < UB_STATS_QTYPE_NUM) stats->qtype[qtype]++; else stats->qtype_big++; - if(qclass < STATS_QCLASS_NUM) + if(qclass < UB_STATS_QCLASS_NUM) stats->qclass[qclass]++; else stats->qclass_big++; stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++; - if(c->type != comm_udp) + if(c->type != comm_udp) { stats->qtcp++; + if(c->ssl != NULL) { + stats->qtls++; +#ifdef HAVE_SSL + if(SSL_session_reused(c->ssl)) + stats->qtls_resume++; +#endif + } + } if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen)) stats->qipv6++; if( (flags&BIT_QR) ) @@ -320,7 +511,7 @@ } } -void server_stats_insrcode(struct server_stats* stats, sldns_buffer* buf) +void server_stats_insrcode(struct ub_server_stats* stats, sldns_buffer* buf) { if(stats->extended && sldns_buffer_limit(buf) != 0) { int r = (int)LDNS_RCODE_WIRE( sldns_buffer_begin(buf) ); --- contrib/unbound/daemon/stats.h.orig +++ contrib/unbound/daemon/stats.h @@ -50,143 +50,24 @@ struct edns_data; struct sldns_buffer; -/** number of qtype that is stored for in array */ -#define STATS_QTYPE_NUM 256 -/** number of qclass that is stored for in array */ -#define STATS_QCLASS_NUM 256 -/** number of rcodes in stats */ -#define STATS_RCODE_NUM 16 -/** number of opcodes in stats */ -#define STATS_OPCODE_NUM 16 +/* stats struct */ +#include "libunbound/unbound.h" -/** per worker statistics */ -struct server_stats { - /** number of queries from clients received. */ - size_t num_queries; - /** number of queries that had a cache-miss. */ - size_t num_queries_missed_cache; - /** number of prefetch queries - cachehits with prefetch */ - size_t num_queries_prefetch; - - /** - * Sum of the querylistsize of the worker for - * every query that missed cache. To calculate average. - */ - size_t sum_query_list_size; - /** max value of query list size reached. */ - size_t max_query_list_size; - - /** Extended stats below (bool) */ - int extended; - - /** qtype stats */ - size_t qtype[STATS_QTYPE_NUM]; - /** bigger qtype values not in array */ - size_t qtype_big; - /** qclass stats */ - size_t qclass[STATS_QCLASS_NUM]; - /** bigger qclass values not in array */ - size_t qclass_big; - /** query opcodes */ - size_t qopcode[STATS_OPCODE_NUM]; - /** number of queries over TCP */ - size_t qtcp; - /** number of outgoing queries over TCP */ - size_t qtcp_outgoing; - /** number of queries over IPv6 */ - size_t qipv6; - /** number of queries with QR bit */ - size_t qbit_QR; - /** number of queries with AA bit */ - size_t qbit_AA; - /** number of queries with TC bit */ - size_t qbit_TC; - /** number of queries with RD bit */ - size_t qbit_RD; - /** number of queries with RA bit */ - size_t qbit_RA; - /** number of queries with Z bit */ - size_t qbit_Z; - /** number of queries with AD bit */ - size_t qbit_AD; - /** number of queries with CD bit */ - size_t qbit_CD; - /** number of queries with EDNS OPT record */ - size_t qEDNS; - /** number of queries with EDNS with DO flag */ - size_t qEDNS_DO; - /** answer rcodes */ - size_t ans_rcode[STATS_RCODE_NUM]; - /** answers with pseudo rcode 'nodata' */ - size_t ans_rcode_nodata; - /** answers that were secure (AD) */ - size_t ans_secure; - /** answers that were bogus (withheld as SERVFAIL) */ - size_t ans_bogus; - /** rrsets marked bogus by validator */ - size_t rrset_bogus; - /** unwanted traffic received on server-facing ports */ - size_t unwanted_replies; - /** unwanted traffic received on client-facing ports */ - size_t unwanted_queries; - /** usage of tcp accept list */ - size_t tcp_accept_usage; - - /** histogram data exported to array - * if the array is the same size, no data is lost, and - * if all histograms are same size (is so by default) then - * adding up works well. */ - size_t hist[NUM_BUCKETS_HIST]; - - /** number of message cache entries */ - size_t msg_cache_count; - /** number of rrset cache entries */ - size_t rrset_cache_count; - /** number of infra cache entries */ - size_t infra_cache_count; - /** number of key cache entries */ - size_t key_cache_count; -}; - /** - * Statistics to send over the control pipe when asked - * This struct is made to be memcpied, sent in binary. - */ -struct stats_info { - /** the thread stats */ - struct server_stats svr; - - /** mesh stats: current number of states */ - size_t mesh_num_states; - /** mesh stats: current number of reply (user) states */ - size_t mesh_num_reply_states; - /** mesh stats: number of reply states overwritten with a new one */ - size_t mesh_jostled; - /** mesh stats: number of incoming queries dropped */ - size_t mesh_dropped; - /** mesh stats: replies sent */ - size_t mesh_replies_sent; - /** mesh stats: sum of waiting times for the replies */ - struct timeval mesh_replies_sum_wait; - /** mesh stats: median of waiting times for replies (in sec) */ - double mesh_time_median; -}; - -/** * Initialize server stats to 0. * @param stats: what to init (this is alloced by the caller). * @param cfg: with extended statistics option. */ -void server_stats_init(struct server_stats* stats, struct config_file* cfg); +void server_stats_init(struct ub_server_stats* stats, struct config_file* cfg); /** add query if it missed the cache */ -void server_stats_querymiss(struct server_stats* stats, struct worker* worker); +void server_stats_querymiss(struct ub_server_stats* stats, struct worker* worker); /** add query if was cached and also resulted in a prefetch */ -void server_stats_prefetch(struct server_stats* stats, struct worker* worker); +void server_stats_prefetch(struct ub_server_stats* stats, struct worker* worker); /** display the stats to the log */ -void server_stats_log(struct server_stats* stats, struct worker* worker, +void server_stats_log(struct ub_server_stats* stats, struct worker* worker, int threadnum); /** @@ -197,7 +78,7 @@ * @param reset: if stats can be reset. */ void server_stats_obtain(struct worker* worker, struct worker* who, - struct stats_info* s, int reset); + struct ub_stats_info* s, int reset); /** * Compile stats into structure for this thread worker. @@ -207,7 +88,7 @@ * @param reset: if true, depending on config stats are reset. * if false, statistics are not reset. */ -void server_stats_compile(struct worker* worker, struct stats_info* s, +void server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset); /** @@ -223,7 +104,7 @@ * @param total: sum of the two entries. * @param a: to add to it. */ -void server_stats_add(struct stats_info* total, struct stats_info* a); +void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a); /** * Add stats for this query @@ -234,7 +115,7 @@ * @param edns: edns record * @param repinfo: reply info with remote address */ -void server_stats_insquery(struct server_stats* stats, struct comm_point* c, +void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c, uint16_t qtype, uint16_t qclass, struct edns_data* edns, struct comm_reply* repinfo); @@ -243,6 +124,6 @@ * @param stats: the stats * @param buf: buffer with rcode. If buffer is length0: not counted. */ -void server_stats_insrcode(struct server_stats* stats, struct sldns_buffer* buf); +void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf); #endif /* DAEMON_STATS_H */ --- contrib/unbound/daemon/unbound.c.orig +++ contrib/unbound/daemon/unbound.c @@ -67,6 +67,7 @@ #ifdef HAVE_GRP_H #include #endif +#include #ifndef S_SPLINT_S /* splint chokes on this system header file */ @@ -87,13 +88,9 @@ # include "nss.h" #endif -#ifdef HAVE_SBRK -/** global debug value to keep track of heap memory allocation */ -void* unbound_start_brk = 0; -#endif - -/** print usage. */ -static void usage(void) +/** print build options. */ +static void +print_build_options(void) { const char** m; const char *evnm="event", *evsys="", *evmethod=""; @@ -100,22 +97,11 @@ time_t t; struct timeval now; struct ub_event_base* base; - printf("usage: unbound [options]\n"); - printf(" start unbound daemon DNS resolver.\n"); - printf("-h this help\n"); - printf("-c file config file to read instead of %s\n", CONFIGFILE); - printf(" file format is described in unbound.conf(5).\n"); - printf("-d do not fork into the background.\n"); - printf("-v verbose (more times to increase verbosity)\n"); -#ifdef UB_ON_WINDOWS - printf("-w opt windows option: \n"); - printf(" install, remove - manage the services entry\n"); - printf(" service - used to start from services control panel\n"); -#endif - printf("Version %s\n", PACKAGE_VERSION); + printf("Version %s\n\n", PACKAGE_VERSION); + printf("Configure line: %s\n", CONFCMDLINE); base = ub_default_event_base(0,&t,&now); ub_get_event_sys(base, &evnm, &evsys, &evmethod); - printf("linked libs: %s %s (it uses %s), %s\n", + printf("Linked libs: %s %s (it uses %s), %s\n", evnm, evsys, evmethod, #ifdef HAVE_SSL # ifdef SSLEAY_VERSION @@ -129,13 +115,42 @@ "nettle" #endif ); - printf("linked modules:"); + printf("Linked modules:"); for(m = module_list_avail(); *m; m++) printf(" %s", *m); printf("\n"); +#ifdef USE_DNSCRYPT + printf("DNSCrypt feature available\n"); +#endif +#ifdef USE_TCP_FASTOPEN + printf("TCP Fastopen feature available\n"); +#endif + ub_event_base_free(base); + printf("\nBSD licensed, see LICENSE in source package for details.\n"); + printf("Report bugs to %s\n", PACKAGE_BUGREPORT); +} + +/** print usage. */ +static void +usage(void) +{ + printf("usage: unbound [options]\n"); + printf(" start unbound daemon DNS resolver.\n"); + printf("-h this help.\n"); + printf("-c file config file to read instead of %s\n", CONFIGFILE); + printf(" file format is described in unbound.conf(5).\n"); + printf("-d do not fork into the background.\n"); + printf("-p do not create a pidfile.\n"); + printf("-v verbose (more times to increase verbosity).\n"); + printf("-V show version number and build options.\n"); +#ifdef UB_ON_WINDOWS + printf("-w opt windows option: \n"); + printf(" install, remove - manage the services entry\n"); + printf(" service - used to start from services control panel\n"); +#endif + printf("\nVersion %s\n", PACKAGE_VERSION); printf("BSD licensed, see LICENSE in source package for details.\n"); printf("Report bugs to %s\n", PACKAGE_BUGREPORT); - ub_event_base_free(base); } #ifndef unbound_testbound @@ -246,7 +261,7 @@ /** set verbosity, check rlimits, cache settings */ static void -apply_settings(struct daemon* daemon, struct config_file* cfg, +apply_settings(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose, int debug_mode) { /* apply if they have changed */ @@ -253,10 +268,17 @@ verbosity = cmdline_verbose + cfg->verbosity; if (debug_mode > 1) { cfg->use_syslog = 0; + free(cfg->logfile); cfg->logfile = NULL; } daemon_apply_cfg(daemon, cfg); checkrlimits(cfg); + + if (cfg->use_systemd && cfg->do_daemonize) { + log_warn("use-systemd and do-daemonize should not be enabled at the same time"); + } + + log_ident_set_or_default(cfg->log_identity); } #ifdef HAVE_KILL @@ -384,10 +406,10 @@ #endif /* HAVE_DAEMON */ } -/** daemonize, drop user priviliges and chroot if needed */ +/** daemonize, drop user privileges and chroot if needed */ static void perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, - const char** cfgfile) + const char** cfgfile, int need_pidfile) { #ifdef HAVE_KILL int pidinchroot; @@ -405,17 +427,6 @@ w_config_adjust_directory(cfg); #endif - /* init syslog (as root) if needed, before daemonize, otherwise - * a fork error could not be printed since daemonize closed stderr.*/ - if(cfg->use_syslog) { - log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); - } - /* if using a logfile, we cannot open it because the logfile would - * be created with the wrong permissions, we cannot chown it because - * we cannot chown system logfiles, so we do not open at all. - * So, using a logfile, the user does not see errors unless -d is - * given to unbound on the commandline. */ - /* read ssl keys while superuser and outside chroot */ #ifdef HAVE_SSL if(!(daemon->rc = daemon_remote_create(cfg))) @@ -424,20 +435,50 @@ if(!(daemon->listen_sslctx = listen_sslctx_create( cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) fatal_exit("could not set up listen SSL_CTX"); + if(cfg->tls_ciphers && cfg->tls_ciphers[0]) { + if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) { + fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers); + } + } +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) { + if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) { + fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites); + } + } +#endif + if(cfg->tls_session_ticket_keys.first && + cfg->tls_session_ticket_keys.first->str[0] != 0) { + if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) { + fatal_exit("could not set session ticket SSL_CTX"); + } + } } - if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, NULL))) + if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, + cfg->tls_cert_bundle, cfg->tls_win_cert))) fatal_exit("could not set up connect SSL_CTX"); #endif + /* init syslog (as root) if needed, before daemonize, otherwise + * a fork error could not be printed since daemonize closed stderr.*/ + if(cfg->use_syslog) { + log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); + } + /* if using a logfile, we cannot open it because the logfile would + * be created with the wrong permissions, we cannot chown it because + * we cannot chown system logfiles, so we do not open at all. + * So, using a logfile, the user does not see errors unless -d is + * given to unbound on the commandline. */ + #ifdef HAVE_KILL /* true if pidfile is inside chrootdir, or nochroot */ - pidinchroot = !(cfg->chrootdir && cfg->chrootdir[0]) || + pidinchroot = need_pidfile && (!(cfg->chrootdir && cfg->chrootdir[0]) || (cfg->chrootdir && cfg->chrootdir[0] && strncmp(cfg->pidfile, cfg->chrootdir, - strlen(cfg->chrootdir))==0); + strlen(cfg->chrootdir))==0)); /* check old pid file before forking */ - if(cfg->pidfile && cfg->pidfile[0]) { + if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) { /* calculate position of pidfile */ if(cfg->pidfile[0] == '/') daemon->pidfile = strdup(cfg->pidfile); @@ -456,7 +497,7 @@ /* write new pidfile (while still root, so can be outside chroot) */ #ifdef HAVE_KILL - if(cfg->pidfile && cfg->pidfile[0]) { + if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) { writepid(daemon->pidfile, getpid()); if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 && pidinchroot) { @@ -471,6 +512,7 @@ } #else (void)daemon; + (void)need_pidfile; #endif /* HAVE_KILL */ /* Set user context */ @@ -586,9 +628,10 @@ * @param cmdline_verbose: verbosity resulting from commandline -v. * These increase verbosity as specified in the config file. * @param debug_mode: if set, do not daemonize. + * @param need_pidfile: if false, no pidfile is checked or created. */ static void -run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode) +run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile) { struct config_file* cfg = NULL; struct daemon* daemon = NULL; @@ -606,8 +649,10 @@ fatal_exit("Could not alloc config defaults"); if(!config_read(cfg, cfgfile, daemon->chroot)) { if(errno != ENOENT) - fatal_exit("Could not read config file: %s", - cfgfile); + fatal_exit("Could not read config file: %s." + " Maybe try unbound -dd, it stays on " + "the commandline to see more errors, " + "or unbound-checkconf", cfgfile); log_warn("Continuing with default config settings"); } apply_settings(daemon, cfg, cmdline_verbose, debug_mode); @@ -618,7 +663,7 @@ if(!daemon_open_shared_ports(daemon)) fatal_exit("could not open ports"); if(!done_setup) { - perform_setup(daemon, cfg, debug_mode, &cfgfile); + perform_setup(daemon, cfg, debug_mode, &cfgfile, need_pidfile); done_setup = 1; } else { /* reopen log after HUP to facilitate log rotation */ @@ -665,21 +710,21 @@ int c; const char* cfgfile = CONFIGFILE; const char* winopt = NULL; + const char* log_ident_default; int cmdline_verbose = 0; int debug_mode = 0; + int need_pidfile = 1; + #ifdef UB_ON_WINDOWS int cmdline_cfg = 0; #endif -#ifdef HAVE_SBRK - /* take debug snapshot of heap */ - unbound_start_brk = sbrk(0); -#endif - log_init(NULL, 0, NULL); - log_ident_set(strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]); + log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]; + log_ident_set_default(log_ident_default); + log_ident_set(log_ident_default); /* parse the options */ - while( (c=getopt(argc, argv, "c:dhvw:")) != -1) { + while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) { switch(c) { case 'c': cfgfile = optarg; @@ -691,6 +736,9 @@ cmdline_verbose++; verbosity++; break; + case 'p': + need_pidfile = 0; + break; case 'd': debug_mode++; break; @@ -697,6 +745,9 @@ case 'w': winopt = optarg; break; + case 'V': + print_build_options(); + return 0; case '?': case 'h': default: @@ -705,7 +756,7 @@ } } argc -= optind; - argv += optind; + /* argv += optind; not using further arguments */ if(winopt) { #ifdef UB_ON_WINDOWS @@ -721,7 +772,12 @@ return 1; } - run_daemon(cfgfile, cmdline_verbose, debug_mode); + run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile); log_init(NULL, 0, NULL); /* close logfile */ +#ifndef unbound_testbound + if(log_get_lock()) { + lock_basic_destroy((lock_basic_type*)log_get_lock()); + } +#endif return 0; } --- contrib/unbound/daemon/worker.c.orig +++ contrib/unbound/daemon/worker.c @@ -58,20 +58,27 @@ #include "services/cache/rrset.h" #include "services/cache/infra.h" #include "services/cache/dns.h" +#include "services/authzone.h" #include "services/mesh.h" #include "services/localzone.h" +#include "services/rpz.h" #include "util/data/msgparse.h" #include "util/data/msgencode.h" #include "util/data/dname.h" #include "util/fptr_wlist.h" #include "util/tube.h" +#include "util/edns.h" #include "iterator/iter_fwd.h" #include "iterator/iter_hints.h" #include "validator/autotrust.h" #include "validator/val_anchor.h" +#include "respip/respip.h" #include "libunbound/context.h" #include "libunbound/libworker.h" #include "sldns/sbuffer.h" +#include "sldns/wire2str.h" +#include "util/shm_side/shm_main.h" +#include "dnscrypt/dnscrypt.h" #ifdef HAVE_SYS_TYPES_H # include @@ -101,51 +108,6 @@ */ #define PREFETCH_EXPIRY_ADD 60 -#ifdef UNBOUND_ALLOC_STATS -/** measure memory leakage */ -static void -debug_memleak(size_t accounted, size_t heap, - size_t total_alloc, size_t total_free) -{ - static int init = 0; - static size_t base_heap, base_accounted, base_alloc, base_free; - size_t base_af, cur_af, grow_af, grow_acc; - if(!init) { - init = 1; - base_heap = heap; - base_accounted = accounted; - base_alloc = total_alloc; - base_free = total_free; - } - base_af = base_alloc - base_free; - cur_af = total_alloc - total_free; - grow_af = cur_af - base_af; - grow_acc = accounted - base_accounted; - log_info("Leakage: %d leaked. growth: %u use, %u acc, %u heap", - (int)(grow_af - grow_acc), (unsigned)grow_af, - (unsigned)grow_acc, (unsigned)(heap - base_heap)); -} - -/** give debug heap size indication */ -static void -debug_total_mem(size_t calctotal) -{ -#ifdef HAVE_SBRK - extern void* unbound_start_brk; - extern size_t unbound_mem_alloc, unbound_mem_freed; - void* cur = sbrk(0); - int total = cur-unbound_start_brk; - log_info("Total heap memory estimate: %u total-alloc: %u " - "total-free: %u", (unsigned)total, - (unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed); - debug_memleak(calctotal, (size_t)total, - unbound_mem_alloc, unbound_mem_freed); -#else - (void)calctotal; -#endif /* HAVE_SBRK */ -} -#endif /* UNBOUND_ALLOC_STATS */ - /** Report on memory usage by this thread and global */ static void worker_mem_report(struct worker* ATTR_UNUSED(worker), @@ -152,10 +114,15 @@ struct serviced_query* ATTR_UNUSED(cur_serv)) { #ifdef UNBOUND_ALLOC_STATS + /* measure memory leakage */ + extern size_t unbound_mem_alloc, unbound_mem_freed; /* debug func in validator module */ size_t total, front, back, mesh, msg, rrset, infra, ac, superac; size_t me, iter, val, anch; int i; +#ifdef CLIENT_SUBNET + size_t subnet = 0; +#endif /* CLIENT_SUBNET */ if(verbosity < VERB_ALGO) return; front = listen_get_mem(worker->front); @@ -175,6 +142,12 @@ if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0) val += (*worker->env.mesh->mods.mod[i]->get_mem) (&worker->env, i); +#ifdef CLIENT_SUBNET + else if(strcmp(worker->env.mesh->mods.mod[i]->name, + "subnet")==0) + subnet += (*worker->env.mesh->mods.mod[i]->get_mem) + (&worker->env, i); +#endif /* CLIENT_SUBNET */ else iter += (*worker->env.mesh->mods.mod[i]->get_mem) (&worker->env, i); } @@ -192,7 +165,18 @@ me += serviced_get_mem(cur_serv); } total = front+back+mesh+msg+rrset+infra+iter+val+ac+superac+me; +#ifdef CLIENT_SUBNET + total += subnet; log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u " + "rrset=%u infra=%u iter=%u val=%u subnet=%u anchors=%u " + "alloccache=%u globalalloccache=%u me=%u", + (unsigned)total, (unsigned)front, (unsigned)back, + (unsigned)mesh, (unsigned)msg, (unsigned)rrset, (unsigned)infra, + (unsigned)iter, (unsigned)val, + (unsigned)subnet, (unsigned)anch, (unsigned)ac, + (unsigned)superac, (unsigned)me); +#else /* no CLIENT_SUBNET */ + log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u " "rrset=%u infra=%u iter=%u val=%u anchors=%u " "alloccache=%u globalalloccache=%u me=%u", (unsigned)total, (unsigned)front, (unsigned)back, @@ -199,9 +183,15 @@ (unsigned)mesh, (unsigned)msg, (unsigned)rrset, (unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch, (unsigned)ac, (unsigned)superac, (unsigned)me); - debug_total_mem(total); +#endif /* CLIENT_SUBNET */ + log_info("Total heap memory estimate: %u total-alloc: %u " + "total-free: %u", (unsigned)total, + (unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed); #else /* no UNBOUND_ALLOC_STATS */ size_t val = 0; +#ifdef CLIENT_SUBNET + size_t subnet = 0; +#endif /* CLIENT_SUBNET */ int i; if(verbosity < VERB_QUERY) return; @@ -211,12 +201,27 @@ if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0) val += (*worker->env.mesh->mods.mod[i]->get_mem) (&worker->env, i); +#ifdef CLIENT_SUBNET + else if(strcmp(worker->env.mesh->mods.mod[i]->name, + "subnet")==0) + subnet += (*worker->env.mesh->mods.mod[i]->get_mem) + (&worker->env, i); +#endif /* CLIENT_SUBNET */ } +#ifdef CLIENT_SUBNET + verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u " + "subnet=%u", + (unsigned)slabhash_get_mem(worker->env.msg_cache), + (unsigned)slabhash_get_mem(&worker->env.rrset_cache->table), + (unsigned)infra_get_mem(worker->env.infra_cache), + (unsigned)val, (unsigned)subnet); +#else /* no CLIENT_SUBNET */ verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u", (unsigned)slabhash_get_mem(worker->env.msg_cache), (unsigned)slabhash_get_mem(&worker->env.rrset_cache->table), (unsigned)infra_get_mem(worker->env.infra_cache), (unsigned)val); +#endif /* CLIENT_SUBNET */ #endif /* UNBOUND_ALLOC_STATS */ } @@ -339,7 +344,8 @@ verbose(VERB_QUERY, "request bad, has TC bit on"); return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } - if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) { + if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY && + LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY) { verbose(VERB_QUERY, "request unknown opcode %d", LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt))); return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL); @@ -349,7 +355,9 @@ LDNS_QDCOUNT(sldns_buffer_begin(pkt))); return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); } - if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) { + if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 && + (LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 1 || + LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) { verbose(VERB_QUERY, "request wrong nr an=%d", LDNS_ANCOUNT(sldns_buffer_begin(pkt))); return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR); @@ -471,6 +479,7 @@ * Then check if it needs validation, if so, this routine fails, * so that iterator can prime and validator can verify rrsets. */ + struct edns_data edns_bak; uint16_t udpsize = edns->udp_size; int secure = 0; time_t timenow = *worker->env.now; @@ -485,6 +494,10 @@ if(!dp) { /* no delegation, need to reprime */ return 0; } + /* In case we have a local alias, copy it into the delegation message. + * Shallow copy should be fine, as we'll be done with msg in this + * function. */ + msg->qinfo.local_alias = qinfo->local_alias; if(must_validate) { switch(check_delegation_secure(msg->rep)) { case sec_status_unchecked: @@ -492,13 +505,15 @@ * let validator do that */ return 0; case sec_status_bogus: + case sec_status_secure_sentinel_fail: /* some rrsets are bogus, reply servfail */ edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->ext_rcode = 0; edns->bits &= EDNS_DO; - if(!edns_opt_inplace_reply(edns, worker->scratchpad)) - return 0; + if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, + msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) + return 0; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, &msg->qinfo, id, flags, edns); if(worker->stats.extended) { @@ -522,16 +537,23 @@ } } /* return this delegation from the cache */ + edns_bak = *edns; edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->ext_rcode = 0; edns->bits &= EDNS_DO; - if(!edns_opt_inplace_reply(edns, worker->scratchpad)) - return 0; + if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep, + (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) + return 0; msg->rep->flags |= BIT_QR|BIT_RA; - if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags, + if(!apply_edns_options(edns, &edns_bak, worker->env.cfg, + repinfo->c, worker->scratchpad) || + !reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags, repinfo->c->buffer, 0, 1, worker->scratchpad, udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) { + if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL, + LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) + edns->opt_list = NULL; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, &msg->qinfo, id, flags, edns); } @@ -542,53 +564,130 @@ return 1; } -/** answer query from the cache */ +/** Apply, if applicable, a response IP action to a cached answer. + * If the answer is rewritten as a result of an action, '*encode_repp' will + * point to the reply info containing the modified answer. '*encode_repp' will + * be intact otherwise. + * It returns 1 on success, 0 otherwise. */ static int +apply_respip_action(struct worker* worker, const struct query_info* qinfo, + struct respip_client_info* cinfo, struct reply_info* rep, + struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset, + struct reply_info** encode_repp, struct auth_zones* az) +{ + struct respip_action_info actinfo = {0}; + actinfo.action = respip_none; + + if(qinfo->qtype != LDNS_RR_TYPE_A && + qinfo->qtype != LDNS_RR_TYPE_AAAA && + qinfo->qtype != LDNS_RR_TYPE_ANY) + return 1; + + if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo, + alias_rrset, 0, worker->scratchpad, az)) + return 0; + + /* xxx_deny actions mean dropping the reply, unless the original reply + * was redirected to response-ip data. */ + if((actinfo.action == respip_deny || + actinfo.action == respip_inform_deny) && + *encode_repp == rep) + *encode_repp = NULL; + + /* If address info is returned, it means the action should be an + * 'inform' variant and the information should be logged. */ + if(actinfo.addrinfo) { + respip_inform_print(&actinfo, qinfo->qname, + qinfo->qtype, qinfo->qclass, qinfo->local_alias, + repinfo); + + if(worker->stats.extended && actinfo.rpz_used) { + if(actinfo.rpz_disabled) + worker->stats.rpz_action[RPZ_DISABLED_ACTION]++; + if(actinfo.rpz_cname_override) + worker->stats.rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; + else + worker->stats.rpz_action[ + respip_action_to_rpz_action(actinfo.action)]++; + } + } + + return 1; +} + +/** answer query from the cache. + * Normally, the answer message will be built in repinfo->c->buffer; if the + * answer is supposed to be suppressed or the answer is supposed to be an + * incomplete CNAME chain, the buffer is explicitly cleared to signal the + * caller as such. In the latter case *partial_rep will point to the incomplete + * reply, and this function is (possibly) supposed to be called again with that + * *partial_rep value to complete the chain. In addition, if the query should + * be completely dropped, '*need_drop' will be set to 1. */ +static int answer_from_cache(struct worker* worker, struct query_info* qinfo, - struct reply_info* rep, uint16_t id, uint16_t flags, + struct respip_client_info* cinfo, int* need_drop, int* is_expired_answer, + int* is_secure_answer, struct ub_packed_rrset_key** alias_rrset, + struct reply_info** partial_repp, + struct reply_info* rep, uint16_t id, uint16_t flags, struct comm_reply* repinfo, struct edns_data* edns) { + struct edns_data edns_bak; time_t timenow = *worker->env.now; uint16_t udpsize = edns->udp_size; - int secure; + struct reply_info* encode_rep = rep; + struct reply_info* partial_rep = *partial_repp; int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd) && worker->env.need_to_validate; - /* see if it is possible */ + *partial_repp = NULL; /* avoid accidental further pass */ + + /* Check TTL */ if(rep->ttl < timenow) { - /* the rrsets may have been updated in the meantime. - * we will refetch the message format from the - * authoritative server - */ - return 0; + /* Check if we need to serve expired now */ + if(worker->env.cfg->serve_expired && + !worker->env.cfg->serve_expired_client_timeout) { + if(worker->env.cfg->serve_expired_ttl && + rep->serve_expired_ttl < timenow) + return 0; + if(!rrset_array_lock(rep->ref, rep->rrset_count, 0)) + return 0; + *is_expired_answer = 1; + } else { + /* the rrsets may have been updated in the meantime. + * we will refetch the message format from the + * authoritative server + */ + return 0; + } + } else { + if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow)) + return 0; } - if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow)) - return 0; /* locked and ids and ttls are OK. */ + /* check CNAME chain (if any) */ - if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type == - htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type == + if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type == + htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type == htons(LDNS_RR_TYPE_DNAME))) { if(!reply_check_cname_chain(qinfo, rep)) { /* cname chain invalid, redo iterator steps */ verbose(VERB_ALGO, "Cache reply: cname chain broken"); - bail_out: - rrset_array_unlock_touch(worker->env.rrset_cache, - worker->scratchpad, rep->ref, rep->rrset_count); - return 0; + goto bail_out; } } /* check security status of the cached answer */ - if( rep->security == sec_status_bogus && must_validate) { + if(must_validate && (rep->security == sec_status_bogus || + rep->security == sec_status_secure_sentinel_fail)) { /* BAD cached */ edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->ext_rcode = 0; edns->bits &= EDNS_DO; - if(!edns_opt_inplace_reply(edns, worker->scratchpad)) - return 0; - error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, + if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep, + LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) + goto bail_out; + error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, id, flags, edns); - rrset_array_unlock_touch(worker->env.rrset_cache, + rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad, rep->ref, rep->rrset_count); if(worker->stats.extended) { worker->stats.ans_bogus ++; @@ -595,32 +694,67 @@ worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++; } return 1; - } else if( rep->security == sec_status_unchecked && must_validate) { + } else if(rep->security == sec_status_unchecked && must_validate) { verbose(VERB_ALGO, "Cache reply: unchecked entry needs " "validation"); goto bail_out; /* need to validate cache entry first */ } else if(rep->security == sec_status_secure) { - if(reply_all_rrsets_secure(rep)) - secure = 1; - else { + if(reply_all_rrsets_secure(rep)) { + *is_secure_answer = 1; + } else { if(must_validate) { verbose(VERB_ALGO, "Cache reply: secure entry" " changed status"); goto bail_out; /* rrset changed, re-verify */ } - secure = 0; + *is_secure_answer = 0; } - } else secure = 0; + } else *is_secure_answer = 0; + edns_bak = *edns; edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->ext_rcode = 0; edns->bits &= EDNS_DO; - if(!edns_opt_inplace_reply(edns, worker->scratchpad)) - return 0; - if(!reply_info_answer_encode(qinfo, rep, id, flags, + if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep, + (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) + goto bail_out; + *alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */ + if((worker->daemon->use_response_ip || worker->daemon->use_rpz) && + !partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep, + repinfo, alias_rrset, + &encode_rep, worker->env.auth_zones)) { + goto bail_out; + } else if(partial_rep && + !respip_merge_cname(partial_rep, qinfo, rep, cinfo, + must_validate, &encode_rep, worker->scratchpad, + worker->env.auth_zones)) { + goto bail_out; + } + if(encode_rep != rep) { + /* if rewritten, it can't be considered "secure" */ + *is_secure_answer = 0; + } + if(!encode_rep || *alias_rrset) { + if(!encode_rep) + *need_drop = 1; + else { + /* If a partial CNAME chain is found, we first need to + * make a copy of the reply in the scratchpad so we + * can release the locks and lookup the cache again. */ + *partial_repp = reply_info_copy(encode_rep, NULL, + worker->scratchpad); + if(!*partial_repp) + goto bail_out; + } + } else if(!apply_edns_options(edns, &edns_bak, worker->env.cfg, + repinfo->c, worker->scratchpad) || + !reply_info_answer_encode(qinfo, encode_rep, id, flags, repinfo->c->buffer, timenow, 1, worker->scratchpad, - udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) { + udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) { + if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL, + LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) + edns->opt_list = NULL; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, id, flags, edns); } @@ -628,22 +762,30 @@ * is bad while holding locks. */ rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad, rep->ref, rep->rrset_count); - if(worker->stats.extended) { - if(secure) worker->stats.ans_secure++; - server_stats_insrcode(&worker->stats, repinfo->c->buffer); - } /* go and return this buffer to the client */ return 1; + +bail_out: + rrset_array_unlock_touch(worker->env.rrset_cache, + worker->scratchpad, rep->ref, rep->rrset_count); + return 0; } -/** Reply to client and perform prefetch to keep cache up to date */ +/** Reply to client and perform prefetch to keep cache up to date. */ static void reply_and_prefetch(struct worker* worker, struct query_info* qinfo, - uint16_t flags, struct comm_reply* repinfo, time_t leeway) + uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply) { /* first send answer to client to keep its latency * as small as a cachereply */ - comm_point_send_reply(repinfo); + if(!noreply) { + if(repinfo->c->tcp_req_info) { + sldns_buffer_copy( + repinfo->c->tcp_req_info->spool_buffer, + repinfo->c->buffer); + } + comm_point_send_reply(repinfo); + } server_stats_prefetch(&worker->stats, worker); /* create the prefetch in the mesh as a normal lookup without @@ -658,17 +800,19 @@ * Fill CH class answer into buffer. Keeps query. * @param pkt: buffer * @param str: string to put into text record (<255). + * array of strings, every string becomes a text record. + * @param num: number of strings in array. * @param edns: edns reply information. * @param worker: worker with scratch region. + * @param repinfo: reply information for a communication point. */ static void -chaos_replystr(sldns_buffer* pkt, const char* str, struct edns_data* edns, - struct worker* worker) +chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns, + struct worker* worker, struct comm_reply* repinfo) { - size_t len = strlen(str); + int i; unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt)); unsigned int cd = LDNS_CD_WIRE(sldns_buffer_begin(pkt)); - if(len>255) len=255; /* cap size of TXT record */ sldns_buffer_clear(pkt); sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */ sldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA)); @@ -675,39 +819,113 @@ if(rd) LDNS_RD_SET(sldns_buffer_begin(pkt)); if(cd) LDNS_CD_SET(sldns_buffer_begin(pkt)); sldns_buffer_write_u16(pkt, 1); /* qdcount */ - sldns_buffer_write_u16(pkt, 1); /* ancount */ + sldns_buffer_write_u16(pkt, (uint16_t)num); /* ancount */ sldns_buffer_write_u16(pkt, 0); /* nscount */ sldns_buffer_write_u16(pkt, 0); /* arcount */ (void)query_dname_len(pkt); /* skip qname */ sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */ sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */ - sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */ - sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT); - sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH); - sldns_buffer_write_u32(pkt, 0); /* TTL */ - sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len); - sldns_buffer_write_u8(pkt, len); - sldns_buffer_write(pkt, str, len); + for(i=0; i255) len=255; /* cap size of TXT record */ + sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */ + sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT); + sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH); + sldns_buffer_write_u32(pkt, 0); /* TTL */ + sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len); + sldns_buffer_write_u8(pkt, len); + sldns_buffer_write(pkt, str[i], len); + } sldns_buffer_flip(pkt); edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->bits &= EDNS_DO; - if(!edns_opt_inplace_reply(edns, worker->scratchpad)) - edns->opt_list = NULL; - attach_edns_record(pkt, edns); + if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL, + LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad)) + edns->opt_list = NULL; + if(sldns_buffer_capacity(pkt) >= + sldns_buffer_limit(pkt)+calc_edns_field_size(edns)) + attach_edns_record(pkt, edns); } +/** Reply with one string */ +static void +chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns, + struct worker* worker, struct comm_reply* repinfo) +{ + chaos_replystr(pkt, (char**)&str, 1, edns, worker, repinfo); +} + /** + * Create CH class trustanchor answer. + * @param pkt: buffer + * @param edns: edns reply information. + * @param w: worker with scratch region. + * @param repinfo: reply information for a communication point. + */ +static void +chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w, + struct comm_reply* repinfo) +{ +#define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */ +#define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */ + char* str_array[TA_RESPONSE_MAX_TXT]; + uint16_t tags[TA_RESPONSE_MAX_TAGS]; + int num = 0; + struct trust_anchor* ta; + + if(!w->env.need_to_validate) { + /* no validator module, reply no trustanchors */ + chaos_replystr(pkt, NULL, 0, edns, w, repinfo); + return; + } + + /* fill the string with contents */ + lock_basic_lock(&w->env.anchors->lock); + RBTREE_FOR(ta, struct trust_anchor*, w->env.anchors->tree) { + char* str; + size_t i, numtag, str_len = 255; + if(num == TA_RESPONSE_MAX_TXT) continue; + str = (char*)regional_alloc(w->scratchpad, str_len); + if(!str) continue; + lock_basic_lock(&ta->lock); + numtag = anchor_list_keytags(ta, tags, TA_RESPONSE_MAX_TAGS); + if(numtag == 0) { + /* empty, insecure point */ + lock_basic_unlock(&ta->lock); + continue; + } + str_array[num] = str; + num++; + + /* spool name of anchor */ + (void)sldns_wire2str_dname_buf(ta->name, ta->namelen, str, str_len); + str_len -= strlen(str); str += strlen(str); + /* spool tags */ + for(i=0; ilock); + } + lock_basic_unlock(&w->env.anchors->lock); + + chaos_replystr(pkt, str_array, num, edns, w, repinfo); + regional_free_all(w->scratchpad); +} + +/** * Answer CH class queries. * @param w: worker * @param qinfo: query info. Pointer into packet buffer. * @param edns: edns info from query. + * @param repinfo: reply information for a communication point. * @param pkt: packet buffer. * @return: true if a reply is to be sent. */ static int -answer_chaos(struct worker* w, struct query_info* qinfo, - struct edns_data* edns, sldns_buffer* pkt) +answer_chaos(struct worker* w, struct query_info* qinfo, + struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* pkt) { struct config_file* cfg = w->env.cfg; if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT) @@ -723,13 +941,13 @@ char buf[MAXHOSTNAMELEN+1]; if (gethostname(buf, MAXHOSTNAMELEN) == 0) { buf[MAXHOSTNAMELEN] = 0; - chaos_replystr(pkt, buf, edns, w); + chaos_replyonestr(pkt, buf, edns, w, repinfo); } else { log_err("gethostname: %s", strerror(errno)); - chaos_replystr(pkt, "no hostname", edns, w); + chaos_replyonestr(pkt, "no hostname", edns, w, repinfo); } } - else chaos_replystr(pkt, cfg->identity, edns, w); + else chaos_replyonestr(pkt, cfg->identity, edns, w, repinfo); return 1; } if(query_dname_compare(qinfo->qname, @@ -740,13 +958,82 @@ if(cfg->hide_version) return 0; if(cfg->version==NULL || cfg->version[0]==0) - chaos_replystr(pkt, PACKAGE_STRING, edns, w); - else chaos_replystr(pkt, cfg->version, edns, w); + chaos_replyonestr(pkt, PACKAGE_STRING, edns, w, repinfo); + else chaos_replyonestr(pkt, cfg->version, edns, w, repinfo); return 1; } + if(query_dname_compare(qinfo->qname, + (uint8_t*)"\013trustanchor\007unbound") == 0) + { + if(cfg->hide_trustanchor) + return 0; + chaos_trustanchor(pkt, edns, w, repinfo); + return 1; + } + return 0; } +/** + * Answer notify queries. These are notifies for authoritative zones, + * the reply is an ack that the notify has been received. We need to check + * access permission here. + * @param w: worker + * @param qinfo: query info. Pointer into packet buffer. + * @param edns: edns info from query. + * @param repinfo: reply info with source address. + * @param pkt: packet buffer. + */ +static void +answer_notify(struct worker* w, struct query_info* qinfo, + struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo) +{ + int refused = 0; + int rcode = LDNS_RCODE_NOERROR; + uint32_t serial = 0; + int has_serial; + if(!w->env.auth_zones) return; + has_serial = auth_zone_parse_notify_serial(pkt, &serial); + if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname, + qinfo->qname_len, qinfo->qclass, &repinfo->addr, + repinfo->addrlen, has_serial, serial, &refused)) { + rcode = LDNS_RCODE_NOERROR; + } else { + if(refused) + rcode = LDNS_RCODE_REFUSED; + else rcode = LDNS_RCODE_SERVFAIL; + } + + if(verbosity >= VERB_DETAIL) { + char buf[380]; + char zname[255+1]; + char sr[25]; + dname_str(qinfo->qname, zname); + sr[0]=0; + if(has_serial) + snprintf(sr, sizeof(sr), "serial %u ", + (unsigned)serial); + if(rcode == LDNS_RCODE_REFUSED) + snprintf(buf, sizeof(buf), + "refused NOTIFY %sfor %s from", sr, zname); + else if(rcode == LDNS_RCODE_SERVFAIL) + snprintf(buf, sizeof(buf), + "servfail for NOTIFY %sfor %s from", sr, zname); + else snprintf(buf, sizeof(buf), + "received NOTIFY %sfor %s from", sr, zname); + log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen); + } + edns->edns_version = EDNS_ADVERTISED_VERSION; + edns->udp_size = EDNS_ADVERTISED_SIZE; + edns->ext_rcode = 0; + edns->bits &= EDNS_DO; + edns->opt_list = NULL; + error_encode(pkt, rcode, qinfo, + *(uint16_t*)(void *)sldns_buffer_begin(pkt), + sldns_buffer_read_u16_at(pkt, 2), edns); + LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY); +} + static int deny_refuse(struct comm_point* c, enum acl_access acl, enum acl_access deny, enum acl_access refuse, @@ -801,7 +1088,7 @@ { struct worker* worker = (struct worker*)arg; int ret; - hashvalue_t h; + hashvalue_type h; struct lruhash_entry* e; struct query_info qinfo; struct edns_data edns; @@ -808,12 +1095,68 @@ enum acl_access acl; struct acl_addr* acladdr; int rc = 0; + int need_drop = 0; + int is_expired_answer = 0; + int is_secure_answer = 0; + /* We might have to chase a CNAME chain internally, in which case + * we'll have up to two replies and combine them to build a complete + * answer. These variables control this case. */ + struct ub_packed_rrset_key* alias_rrset = NULL; + struct reply_info* partial_rep = NULL; + struct query_info* lookup_qinfo = &qinfo; + struct query_info qinfo_tmp; /* placeholder for lookup_qinfo */ + struct respip_client_info* cinfo = NULL, cinfo_tmp; + memset(&qinfo, 0, sizeof(qinfo)); - if(error != NETEVENT_NOERROR) { + if(error != NETEVENT_NOERROR || !repinfo) { /* some bad tcp query DNS formats give these error calls */ verbose(VERB_ALGO, "handle request called with err=%d", error); return 0; } +#ifdef USE_DNSCRYPT + repinfo->max_udp_size = worker->daemon->cfg->max_udp_size; + if(!dnsc_handle_curved_request(worker->daemon->dnscenv, repinfo)) { + worker->stats.num_query_dnscrypt_crypted_malformed++; + return 0; + } + if(c->dnscrypt && !repinfo->is_dnscrypted) { + char buf[LDNS_MAX_DOMAINLEN+1]; + /* Check if this is unencrypted and asking for certs */ + if(worker_check_request(c->buffer, worker) != 0) { + verbose(VERB_ALGO, + "dnscrypt: worker check request: bad query."); + log_addr(VERB_CLIENT,"from",&repinfo->addr, + repinfo->addrlen); + comm_point_drop_reply(repinfo); + return 0; + } + if(!query_info_parse(&qinfo, c->buffer)) { + verbose(VERB_ALGO, + "dnscrypt: worker parse request: formerror."); + log_addr(VERB_CLIENT, "from", &repinfo->addr, + repinfo->addrlen); + comm_point_drop_reply(repinfo); + return 0; + } + dname_str(qinfo.qname, buf); + if(!(qinfo.qtype == LDNS_RR_TYPE_TXT && + strcasecmp(buf, + worker->daemon->dnscenv->provider_name) == 0)) { + verbose(VERB_ALGO, + "dnscrypt: not TXT \"%s\". Received: %s \"%s\"", + worker->daemon->dnscenv->provider_name, + sldns_rr_descript(qinfo.qtype)->_name, + buf); + comm_point_drop_reply(repinfo); + worker->stats.num_query_dnscrypt_cleartext++; + return 0; + } + worker->stats.num_query_dnscrypt_cert++; + sldns_buffer_rewind(c->buffer); + } else if(c->dnscrypt && repinfo->is_dnscrypted) { + worker->stats.num_query_dnscrypt_crypted++; + } +#endif #ifdef USE_DNSTAP if(worker->dtenv.log_client_query_messages) dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type, @@ -839,11 +1182,34 @@ comm_point_drop_reply(repinfo); return 0; } + worker->stats.num_queries++; + + /* check if this query should be dropped based on source ip rate limiting */ + if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo, + *worker->env.now, c->buffer)) { + /* See if we are passed through with slip factor */ + if(worker->env.cfg->ip_ratelimit_factor != 0 && + ub_random_max(worker->env.rnd, + worker->env.cfg->ip_ratelimit_factor) == 0) { + + char addrbuf[128]; + addr_to_str(&repinfo->addr, repinfo->addrlen, + addrbuf, sizeof(addrbuf)); + verbose(VERB_QUERY, "ip_ratelimit allowed through for ip address %s because of slip in ip_ratelimit_factor", + addrbuf); + } else { + worker->stats.num_queries_ip_ratelimited++; + comm_point_drop_reply(repinfo); + return 0; + } + } + /* see if query is in the cache */ if(!query_info_parse(&qinfo, c->buffer)) { verbose(VERB_ALGO, "worker parse request: formerror."); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + memset(&qinfo, 0, sizeof(qinfo)); /* zero qinfo.qname */ if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) { comm_point_drop_reply(repinfo); return 0; @@ -858,7 +1224,7 @@ if(worker->env.cfg->log_queries) { char ip[128]; addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); - log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass); + log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass); } if(qinfo.qtype == LDNS_RR_TYPE_AXFR || qinfo.qtype == LDNS_RR_TYPE_IXFR) { @@ -874,6 +1240,28 @@ } goto send_reply; } + if(qinfo.qtype == LDNS_RR_TYPE_OPT || + qinfo.qtype == LDNS_RR_TYPE_TSIG || + qinfo.qtype == LDNS_RR_TYPE_TKEY || + qinfo.qtype == LDNS_RR_TYPE_MAILA || + qinfo.qtype == LDNS_RR_TYPE_MAILB || + (qinfo.qtype >= 128 && qinfo.qtype <= 248)) { + verbose(VERB_ALGO, "worker request: formerror for meta-type."); + log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) { + comm_point_drop_reply(repinfo); + return 0; + } + sldns_buffer_rewind(c->buffer); + LDNS_QR_SET(sldns_buffer_begin(c->buffer)); + LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), + LDNS_RCODE_FORMERR); + if(worker->stats.extended) { + worker->stats.qtype[qinfo.qtype]++; + server_stats_insrcode(&worker->stats, c->buffer); + } + goto send_reply; + } if((ret=parse_edns_from_pkt(c->buffer, &edns, worker->scratchpad)) != 0) { struct edns_data reply_edns; verbose(VERB_ALGO, "worker parse edns: formerror."); @@ -889,28 +1277,53 @@ server_stats_insrcode(&worker->stats, c->buffer); goto send_reply; } - if(edns.edns_present && edns.edns_version != 0) { - edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4); - edns.edns_version = EDNS_ADVERTISED_VERSION; - edns.udp_size = EDNS_ADVERTISED_SIZE; - edns.bits &= EDNS_DO; - edns.opt_list = NULL; - verbose(VERB_ALGO, "query with bad edns version."); - log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); - error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo, - *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), - sldns_buffer_read_u16_at(c->buffer, 2), NULL); - attach_edns_record(c->buffer, &edns); - regional_free_all(worker->scratchpad); - goto send_reply; + if(edns.edns_present) { + struct edns_option* edns_opt; + if(edns.edns_version != 0) { + edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4); + edns.edns_version = EDNS_ADVERTISED_VERSION; + edns.udp_size = EDNS_ADVERTISED_SIZE; + edns.bits &= EDNS_DO; + edns.opt_list = NULL; + verbose(VERB_ALGO, "query with bad edns version."); + log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), NULL); + if(sldns_buffer_capacity(c->buffer) >= + sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns)) + attach_edns_record(c->buffer, &edns); + regional_free_all(worker->scratchpad); + goto send_reply; + } + if(edns.udp_size < NORMAL_UDP_SIZE && + worker->daemon->cfg->harden_short_bufsize) { + verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored", + (int)edns.udp_size); + log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + edns.udp_size = NORMAL_UDP_SIZE; + } + if(c->type != comm_udp) { + edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE); + if(edns_opt && edns_opt->opt_len > 0) { + edns.ext_rcode = 0; + edns.edns_version = EDNS_ADVERTISED_VERSION; + edns.udp_size = EDNS_ADVERTISED_SIZE; + edns.bits &= EDNS_DO; + edns.opt_list = NULL; + verbose(VERB_ALGO, "query with bad edns keepalive."); + log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); + error_encode(c->buffer, LDNS_RCODE_FORMERR, &qinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), NULL); + if(sldns_buffer_capacity(c->buffer) >= + sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns)) + attach_edns_record(c->buffer, &edns); + regional_free_all(worker->scratchpad); + goto send_reply; + } + } } - if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE && - worker->daemon->cfg->harden_short_bufsize) { - verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored", - (int)edns.udp_size); - log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); - edns.udp_size = NORMAL_UDP_SIZE; - } if(edns.udp_size > worker->daemon->cfg->max_udp_size && c->type == comm_udp) { verbose(VERB_QUERY, @@ -939,17 +1352,23 @@ if(c->type != comm_udp) edns.udp_size = 65535; /* max size for TCP replies */ if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo, - &edns, c->buffer)) { + &edns, repinfo, c->buffer)) { server_stats_insrcode(&worker->stats, c->buffer); regional_free_all(worker->scratchpad); goto send_reply; } - if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns, - c->buffer, worker->scratchpad, repinfo, - acladdr->taglist, acladdr->taglen, acladdr->tag_actions, + if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) == + LDNS_PACKET_NOTIFY) { + answer_notify(worker, &qinfo, &edns, c->buffer, repinfo); + regional_free_all(worker->scratchpad); + goto send_reply; + } + if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo, + &edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist, + acladdr->taglen, acladdr->tag_actions, acladdr->tag_actions_size, acladdr->tag_datas, acladdr->tag_datas_size, worker->daemon->cfg->tagname, - worker->daemon->cfg->num_tags)) { + worker->daemon->cfg->num_tags, acladdr->view)) { regional_free_all(worker->scratchpad); if(sldns_buffer_limit(c->buffer) == 0) { comm_point_drop_reply(repinfo); @@ -958,6 +1377,34 @@ server_stats_insrcode(&worker->stats, c->buffer); goto send_reply; } + if(worker->env.auth_zones && + rpz_apply_qname_trigger(worker->env.auth_zones, + &worker->env, &qinfo, &edns, c->buffer, worker->scratchpad, + repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) { + regional_free_all(worker->scratchpad); + if(sldns_buffer_limit(c->buffer) == 0) { + comm_point_drop_reply(repinfo); + return 0; + } + server_stats_insrcode(&worker->stats, c->buffer); + goto send_reply; + } + if(worker->env.auth_zones && + auth_zones_answer(worker->env.auth_zones, &worker->env, + &qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) { + regional_free_all(worker->scratchpad); + if(sldns_buffer_limit(c->buffer) == 0) { + comm_point_drop_reply(repinfo); + return 0; + } + /* set RA for everyone that can have recursion (based on + * access control list) */ + if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) && + acl != acl_deny_non_local && acl != acl_refuse_non_local) + LDNS_RA_SET(sldns_buffer_begin(c->buffer)); + server_stats_insrcode(&worker->stats, c->buffer); + goto send_reply; + } /* We've looked in our local zones. If the answer isn't there, we * might need to bail out based on ACLs now. */ @@ -970,16 +1417,19 @@ } /* If this request does not have the recursion bit set, verify + * ACLs allow the recursion bit to be treated as set. */ + if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) && + acl == acl_allow_setrd ) { + LDNS_RD_SET(sldns_buffer_begin(c->buffer)); + } + + /* If this request does not have the recursion bit set, verify * ACLs allow the snooping. */ if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) && acl != acl_allow_snoop ) { - sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE); - sldns_buffer_write_at(c->buffer, 4, - (uint8_t*)"\0\0\0\0\0\0\0\0", 8); - LDNS_QR_SET(sldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), - LDNS_RCODE_REFUSED); - sldns_buffer_flip(c->buffer); + error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), NULL); regional_free_all(worker->scratchpad); server_stats_insrcode(&worker->stats, c->buffer); log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from", @@ -986,44 +1436,127 @@ &repinfo->addr, repinfo->addrlen); goto send_reply; } - h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); - if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) { - /* answer from cache - we have acquired a readlock on it */ - if(answer_from_cache(worker, &qinfo, - (struct reply_info*)e->data, - *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), - sldns_buffer_read_u16_at(c->buffer, 2), repinfo, - &edns)) { - /* prefetch it if the prefetch TTL expired */ - if(worker->env.cfg->prefetch && *worker->env.now >= - ((struct reply_info*)e->data)->prefetch_ttl) { - time_t leeway = ((struct reply_info*)e-> - data)->ttl - *worker->env.now; - lock_rw_unlock(&e->lock); - reply_and_prefetch(worker, &qinfo, - sldns_buffer_read_u16_at(c->buffer, 2), - repinfo, leeway); - rc = 0; - regional_free_all(worker->scratchpad); - goto send_reply_rc; - } - lock_rw_unlock(&e->lock); + + /* If we've found a local alias, replace the qname with the alias + * target before resolving it. */ + if(qinfo.local_alias) { + struct ub_packed_rrset_key* rrset = qinfo.local_alias->rrset; + struct packed_rrset_data* d = rrset->entry.data; + + /* Sanity check: our current implementation only supports + * a single CNAME RRset as a local alias. */ + if(qinfo.local_alias->next || + rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) || + d->count != 1) { + log_err("assumption failure: unexpected local alias"); regional_free_all(worker->scratchpad); - goto send_reply; + return 0; /* drop it */ } - verbose(VERB_ALGO, "answer from the cache failed"); - lock_rw_unlock(&e->lock); + qinfo.qname = d->rr_data[0] + 2; + qinfo.qname_len = d->rr_len[0] - 2; } - if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) { - if(answer_norec_from_cache(worker, &qinfo, - *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), - sldns_buffer_read_u16_at(c->buffer, 2), repinfo, - &edns)) { - regional_free_all(worker->scratchpad); - goto send_reply; + + /* If we may apply IP-based actions to the answer, build the client + * information. As this can be expensive, skip it if there is + * absolutely no possibility of it. */ + if((worker->daemon->use_response_ip || worker->daemon->use_rpz) && + (qinfo.qtype == LDNS_RR_TYPE_A || + qinfo.qtype == LDNS_RR_TYPE_AAAA || + qinfo.qtype == LDNS_RR_TYPE_ANY)) { + cinfo_tmp.taglist = acladdr->taglist; + cinfo_tmp.taglen = acladdr->taglen; + cinfo_tmp.tag_actions = acladdr->tag_actions; + cinfo_tmp.tag_actions_size = acladdr->tag_actions_size; + cinfo_tmp.tag_datas = acladdr->tag_datas; + cinfo_tmp.tag_datas_size = acladdr->tag_datas_size; + cinfo_tmp.view = acladdr->view; + cinfo_tmp.respip_set = worker->daemon->respip_set; + cinfo = &cinfo_tmp; + } + +lookup_cache: + /* Lookup the cache. In case we chase an intermediate CNAME chain + * this is a two-pass operation, and lookup_qinfo is different for + * each pass. We should still pass the original qinfo to + * answer_from_cache(), however, since it's used to build the reply. */ + if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) { + is_expired_answer = 0; + is_secure_answer = 0; + h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); + if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) { + /* answer from cache - we have acquired a readlock on it */ + if(answer_from_cache(worker, &qinfo, + cinfo, &need_drop, &is_expired_answer, &is_secure_answer, + &alias_rrset, &partial_rep, (struct reply_info*)e->data, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, + &edns)) { + /* prefetch it if the prefetch TTL expired. + * Note that if there is more than one pass + * its qname must be that used for cache + * lookup. */ + if((worker->env.cfg->prefetch && *worker->env.now >= + ((struct reply_info*)e->data)->prefetch_ttl) || + (worker->env.cfg->serve_expired && + *worker->env.now >= ((struct reply_info*)e->data)->ttl)) { + + time_t leeway = ((struct reply_info*)e-> + data)->ttl - *worker->env.now; + if(((struct reply_info*)e->data)->ttl + < *worker->env.now) + leeway = 0; + lock_rw_unlock(&e->lock); + reply_and_prefetch(worker, lookup_qinfo, + sldns_buffer_read_u16_at(c->buffer, 2), + repinfo, leeway, + (partial_rep || need_drop)); + if(!partial_rep) { + rc = 0; + regional_free_all(worker->scratchpad); + goto send_reply_rc; + } + } else if(!partial_rep) { + lock_rw_unlock(&e->lock); + regional_free_all(worker->scratchpad); + goto send_reply; + } else { + /* Note that we've already released the + * lock if we're here after prefetch. */ + lock_rw_unlock(&e->lock); + } + /* We've found a partial reply ending with an + * alias. Replace the lookup qinfo for the + * alias target and lookup the cache again to + * (possibly) complete the reply. As we're + * passing the "base" reply, there will be no + * more alias chasing. */ + memset(&qinfo_tmp, 0, sizeof(qinfo_tmp)); + get_cname_target(alias_rrset, &qinfo_tmp.qname, + &qinfo_tmp.qname_len); + if(!qinfo_tmp.qname) { + log_err("unexpected: invalid answer alias"); + regional_free_all(worker->scratchpad); + return 0; /* drop query */ + } + qinfo_tmp.qtype = qinfo.qtype; + qinfo_tmp.qclass = qinfo.qclass; + lookup_qinfo = &qinfo_tmp; + goto lookup_cache; + } + verbose(VERB_ALGO, "answer from the cache failed"); + lock_rw_unlock(&e->lock); } - verbose(VERB_ALGO, "answer norec from cache -- " - "need to validate or not primed"); + if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) { + if(answer_norec_from_cache(worker, &qinfo, + *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), + sldns_buffer_read_u16_at(c->buffer, 2), repinfo, + &edns)) { + regional_free_all(worker->scratchpad); + goto send_reply; + } + verbose(VERB_ALGO, "answer norec from cache -- " + "need to validate or not primed"); + } } sldns_buffer_rewind(c->buffer); server_stats_querymiss(&worker->stats, worker); @@ -1037,7 +1570,7 @@ } /* grab a work request structure for this new request */ - mesh_new_client(worker->env.mesh, &qinfo, + mesh_new_client(worker->env.mesh, &qinfo, cinfo, sldns_buffer_read_u16_at(c->buffer, 2), &edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer)); regional_free_all(worker->scratchpad); @@ -1047,11 +1580,43 @@ send_reply: rc = 1; send_reply_rc: + if(need_drop) { + comm_point_drop_reply(repinfo); + return 0; + } + if(is_expired_answer) { + worker->stats.ans_expired++; + } + if(worker->stats.extended) { + if(is_secure_answer) worker->stats.ans_secure++; + server_stats_insrcode(&worker->stats, repinfo->c->buffer); + } #ifdef USE_DNSTAP if(worker->dtenv.log_client_response_messages) dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, c->type, c->buffer); #endif + if(worker->env.cfg->log_replies) + { + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + if(qinfo.local_alias && qinfo.local_alias->rrset && + qinfo.local_alias->rrset->rk.dname) { + /* log original qname, before the local alias was + * used to resolve that CNAME to something else */ + qinfo.qname = qinfo.local_alias->rrset->rk.dname; + log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen, + tv, 1, c->buffer); + } else { + log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen, + tv, 1, c->buffer); + } + } +#ifdef USE_DNSCRYPT + if(!dnsc_handle_uncurved_request(repinfo)) { + return 0; + } +#endif return rc; } @@ -1107,6 +1672,10 @@ server_stats_log(&worker->stats, worker, worker->thread_num); mesh_stats(worker->env.mesh, "mesh has"); worker_mem_report(worker, NULL); + /* SHM is enabled, process data to SHM */ + if (worker->daemon->cfg->shm_enable) { + shm_main_run(worker); + } if(!worker->daemon->cfg->stat_cumulative) { worker_stats_clear(worker); } @@ -1148,11 +1717,7 @@ return NULL; } /* create random state here to avoid locking trouble in RAND_bytes */ - seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ - (((unsigned int)worker->thread_num)<<17); - /* shift thread_num so it does not match out pid bits */ - if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) { - seed = 0; + if(!(worker->rndstate = ub_initstate(daemon->rand))) { log_err("could not init random numbers."); tube_delete(worker->cmd); free(worker->ports); @@ -1159,7 +1724,7 @@ free(worker); return NULL; } - seed = 0; + explicit_bzero(&seed, sizeof(seed)); #ifdef USE_DNSTAP if(daemon->cfg->dnstap) { log_assert(daemon->dtenv != NULL); @@ -1227,9 +1792,13 @@ worker->comsig = NULL; } worker->front = listen_create(worker->base, ports, - cfg->msg_buffer_size, (int)cfg->incoming_num_tcp, - worker->daemon->listen_sslctx, dtenv, worker_handle_request, - worker); + cfg->msg_buffer_size, (int)cfg->incoming_num_tcp, + cfg->do_tcp_keepalive + ? cfg->tcp_keepalive_timeout + : cfg->tcp_idle_timeout, + worker->daemon->tcl, + worker->daemon->listen_sslctx, + dtenv, worker_handle_request, worker); if(!worker->front) { log_err("could not create listening sockets"); worker_delete(worker); @@ -1243,7 +1812,8 @@ cfg->use_caps_bits_for_id, worker->ports, worker->numports, cfg->unwanted_threshold, cfg->outgoing_tcp_mss, &worker_alloc_cleanup, worker, - cfg->do_udp, worker->daemon->connect_sslctx, cfg->delay_close, + cfg->do_udp || cfg->udp_upstream_without_downstream, + worker->daemon->connect_sslctx, cfg->delay_close, dtenv); if(!worker->back) { log_err("could not create outgoing sockets"); @@ -1278,16 +1848,31 @@ alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker); worker->env = *worker->daemon->env; comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv); - if(worker->thread_num == 0) - log_set_time(worker->env.now); worker->env.worker = worker; + worker->env.worker_base = worker->base; worker->env.send_query = &worker_send_query; worker->env.alloc = &worker->alloc; + worker->env.outnet = worker->back; worker->env.rnd = worker->rndstate; - worker->env.scratch = worker->scratchpad; + /* If case prefetch is triggered, the corresponding mesh will clear + * the scratchpad for the module env in the middle of request handling. + * It would be prone to a use-after-free kind of bug, so we avoid + * sharing it with worker's own scratchpad at the cost of having + * one more pad per worker. */ + worker->env.scratch = regional_create_custom(cfg->msg_buffer_size); + if(!worker->env.scratch) { + log_err("malloc failure"); + worker_delete(worker); + return 0; + } worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env); + /* Pass on daemon variables that we would need in the mesh area */ + worker->env.mesh->use_response_ip = worker->daemon->use_response_ip; + worker->env.mesh->use_rpz = worker->daemon->use_rpz; + worker->env.detach_subs = &mesh_detach_subs; worker->env.attach_sub = &mesh_attach_sub; + worker->env.add_sub = &mesh_add_sub; worker->env.kill_sub = &mesh_state_delete; worker->env.detect_cycle = &mesh_detect_cycle; worker->env.scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size); @@ -1321,6 +1906,14 @@ comm_timer_set(worker->env.probe_timer, &tv); } } + /* zone transfer tasks, setup once per process, if any */ + if(worker->env.auth_zones +#ifndef THREADS_DISABLED + && worker->thread_num == 0 +#endif + ) { + auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env); + } if(!worker->env.mesh || !worker->env.scratch_buffer) { worker_delete(worker); return 0; @@ -1364,7 +1957,6 @@ comm_timer_delete(worker->env.probe_timer); free(worker->ports); if(worker->thread_num == 0) { - log_set_time(NULL); #ifdef UB_ON_WINDOWS wsvc_desetup_worker(worker); #endif /* UB_ON_WINDOWS */ @@ -1372,16 +1964,16 @@ comm_base_delete(worker->base); ub_randfree(worker->rndstate); alloc_clear(&worker->alloc); + regional_destroy(worker->env.scratch); regional_destroy(worker->scratchpad); free(worker); } struct outbound_entry* -worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, - uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, - int nocaps, struct edns_option* opt_list, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, - size_t zonelen, struct module_qstate* q) +worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec, + int want_dnssec, int nocaps, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream, + char* tls_auth_name, struct module_qstate* q) { struct worker* worker = q->env->worker; struct outbound_entry* e = (struct outbound_entry*)regional_alloc( @@ -1389,11 +1981,10 @@ if(!e) return NULL; e->qstate = q; - e->qsent = outnet_serviced_query(worker->back, qname, - qnamelen, qtype, qclass, flags, dnssec, want_dnssec, nocaps, - q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, opt_list, - addr, addrlen, zone, zonelen, worker_handle_service_reply, e, - worker->back->udp_buff); + e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec, + want_dnssec, nocaps, q->env->cfg->tcp_upstream, + ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q, + worker_handle_service_reply, e, worker->back->udp_buff, q->env); if(!e->qsent) { return NULL; } @@ -1433,14 +2024,14 @@ } /* --- fake callbacks for fptr_wlist to work --- */ -struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname), - size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype), - uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags), - int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), - int ATTR_UNUSED(nocaps), struct edns_option* ATTR_UNUSED(opt_list), - struct sockaddr_storage* ATTR_UNUSED(addr), - socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), - size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q)) +struct outbound_entry* libworker_send_query( + struct query_info* ATTR_UNUSED(qinfo), + uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), + int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), + struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), + uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), + int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), + struct module_qstate* ATTR_UNUSED(q)) { log_assert(0); return 0; @@ -1470,22 +2061,22 @@ } void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), - char* ATTR_UNUSED(why_bogus)) + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) { log_assert(0); } void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), - char* ATTR_UNUSED(why_bogus)) + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) { log_assert(0); } void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), - sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), - char* ATTR_UNUSED(why_bogus)) + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) { log_assert(0); } @@ -1498,13 +2089,13 @@ int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2)) { - log_assert(0); - return 0; + log_assert(0); + return 0; } int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) { - log_assert(0); - return 0; + log_assert(0); + return 0; } --- contrib/unbound/daemon/worker.h.orig +++ contrib/unbound/daemon/worker.h @@ -61,6 +61,7 @@ struct regional; struct tube; struct daemon_remote; +struct query_info; /** worker commands */ enum worker_commands { @@ -84,7 +85,7 @@ /** global shared daemon structure */ struct daemon* daemon; /** thread id */ - ub_thread_t thr_id; + ub_thread_type thr_id; /** pipe, for commands for this worker */ struct tube* cmd; /** the event base this worker works with */ @@ -115,7 +116,7 @@ /** allocation cache for this thread */ struct alloc_cache alloc; /** per thread statistics */ - struct server_stats stats; + struct ub_server_stats stats; /** thread scratch regional */ struct regional* scratchpad; --- contrib/unbound/dns64/dns64.c.orig +++ contrib/unbound/dns64/dns64.c @@ -48,6 +48,9 @@ #include "util/fptr_wlist.h" #include "util/net_help.h" #include "util/regional.h" +#include "util/storage/dnstree.h" +#include "util/data/dname.h" +#include "sldns/str2wire.h" /****************************************************************************** * * @@ -67,12 +70,9 @@ #define MAX_PTR_QNAME_IPV4 30 /** - * Per-query module-specific state. This is usually a dynamically-allocated - * structure, but in our case we only need to store one variable describing the - * state the query is in. So we repurpose the minfo pointer by storing an - * integer in there. + * State of DNS64 processing for a query. */ -enum dns64_qstate { +enum dns64_state { DNS64_INTERNAL_QUERY, /**< Internally-generated query, no DNS64 processing. */ DNS64_NEW_QUERY, /**< Query for which we're the first module in @@ -81,6 +81,19 @@ for which this sub-query is finished. */ }; +/** + * Per-query module-specific state. For the DNS64 module. + */ +struct dns64_qstate { + /** State of the DNS64 module. */ + enum dns64_state state; + /** If the dns64 module started with no_cache bool set in the qstate, + * a message to tell it to not modify the cache contents, then this + * is true. The dns64 module is then free to modify that flag for + * its own purposes. + * Otherwise, it is false, the dns64 module was not told to no_cache */ + int started_no_cache_store; +}; /****************************************************************************** * * @@ -111,6 +124,11 @@ * This is the CIDR length of the prefix. It needs to be between 0 and 96. */ int prefix_net; + + /** + * Tree of names for which AAAA is ignored. always synthesize from A. + */ + rbtree_type ignore_aaaa; }; @@ -173,16 +191,19 @@ * * \param ipv6 IPv6 address represented as a 128-bit array in big-endian * order. + * \param ipv6_len length of the ipv6 byte array. * \param offset Index of the MSB of the IPv4 address embedded in the IPv6 * address. */ static uint32_t -extract_ipv4(const uint8_t ipv6[16], const int offset) +extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset) { - uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8)) - | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8)) - | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8)) - | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8)); + uint32_t ipv4; + log_assert(ipv6_len == 16); (void)ipv6_len; + ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8)) + | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8)) + | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8)) + | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8)); if (offset/8+4 < 16) ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8); return ipv4; @@ -196,22 +217,26 @@ * \param ipv4 IPv4 address represented as an unsigned 32-bit number. * \param ptr The result will be written here. Must be large enough, be * careful! + * \param nm_len length of the ptr buffer. * * \return The number of characters written. */ static size_t -ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4]) +ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len) { static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa"; int i; char* c = ptr; + log_assert(nm_len == MAX_PTR_QNAME_IPV4); for (i = 0; i < 4; ++i) { *c = uitoa((unsigned int)(ipv4 % 256), c + 1); c += *c + 1; + log_assert(c < ptr+nm_len); ipv4 /= 256; } + log_assert(c + sizeof(IPV4_PTR_SUFFIX) <= ptr+nm_len); memmove(c, IPV4_PTR_SUFFIX, sizeof(IPV4_PTR_SUFFIX)); return c + sizeof(IPV4_PTR_SUFFIX) - ptr; @@ -223,13 +248,15 @@ * * \param ptr The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa") * \param ipv6 The result will be written here, in network byte order. + * \param ipv6_len length of the ipv6 byte array. * * \return 1 on success, 0 on failure. */ static int -ptr_to_ipv6(const char* ptr, uint8_t ipv6[16]) +ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len) { int i; + log_assert(ipv6_len == 16); (void)ipv6_len; for (i = 0; i < 64; i++) { int x; @@ -257,14 +284,20 @@ * Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix. * * \param prefix_addr DNS64 prefix address. + * \param prefix_addr_len length of the prefix_addr buffer. * \param prefix_net CIDR length of the DNS64 prefix. Must be between 0 and 96. * \param a IPv4 address. + * \param a_len length of the a buffer. * \param aaaa IPv6 address. The result will be written here. + * \param aaaa_len length of the aaaa buffer. */ static void -synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net, - const uint8_t a[4], uint8_t aaaa[16]) +synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len, + int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[], + size_t aaaa_len) { + log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16); + (void)prefix_addr_len; (void)a_len; (void)aaaa_len; memcpy(aaaa, prefix_addr, 16); aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8); aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8); @@ -285,6 +318,40 @@ ******************************************************************************/ /** + * insert ignore_aaaa element into the tree + * @param dns64_env: module env. + * @param str: string with domain name. + * @return false on failure. + */ +static int +dns64_insert_ignore_aaaa(struct dns64_env* dns64_env, char* str) +{ + /* parse and insert element */ + struct name_tree_node* node; + node = (struct name_tree_node*)calloc(1, sizeof(*node)); + if(!node) { + log_err("out of memory"); + return 0; + } + node->name = sldns_str2wire_dname(str, &node->len); + if(!node->name) { + free(node); + log_err("cannot parse dns64-ignore-aaaa: %s", str); + return 0; + } + node->labs = dname_count_labels(node->name); + node->dclass = LDNS_RR_CLASS_IN; + if(!name_tree_insert(&dns64_env->ignore_aaaa, node, + node->name, node->len, node->labs, node->dclass)) { + /* ignore duplicate element */ + free(node->name); + free(node); + return 1; + } + return 1; +} + +/** * This function applies the configuration found in the parsed configuration * file \a cfg to this instance of the dns64 module. Currently only the DNS64 * prefix (a.k.a. Pref64) is configurable. @@ -295,6 +362,7 @@ static int dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg) { + struct config_strlist* s; verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix); if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix : DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr, @@ -311,6 +379,11 @@ cfg->dns64_prefix); return 0; } + for(s = cfg->dns64_ignore_aaaa; s; s = s->next) { + if(!dns64_insert_ignore_aaaa(dns64_env, s->str)) + return 0; + } + name_tree_init_parents(&dns64_env->ignore_aaaa); return 1; } @@ -329,7 +402,8 @@ log_err("malloc failure"); return 0; } - env->modinfo[id] = (void*)dns64_env; + env->modinfo[id] = (void*)dns64_env; + name_tree_init(&dns64_env->ignore_aaaa); if (!dns64_apply_cfg(dns64_env, env->cfg)) { log_err("dns64: could not apply configuration settings."); return 0; @@ -337,6 +411,16 @@ return 1; } +/** free ignore AAAA elements */ +static void +free_ignore_aaaa_node(rbnode_type* node, void* ATTR_UNUSED(arg)) +{ + struct name_tree_node* n = (struct name_tree_node*)node; + if(!n) return; + free(n->name); + free(n); +} + /** * Deinitializes this instance of the dns64 module. * @@ -346,8 +430,14 @@ void dns64_deinit(struct module_env* env, int id) { + struct dns64_env* dns64_env; if (!env) return; + dns64_env = (struct dns64_env*)env->modinfo[id]; + if(dns64_env) { + traverse_postorder(&dns64_env->ignore_aaaa, free_ignore_aaaa_node, + NULL); + } free(env->modinfo[id]); env->modinfo[id] = NULL; } @@ -372,7 +462,8 @@ /* Convert the PTR query string to an IPv6 address. */ memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; - if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr)) + if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr, + sizeof(sin6.sin6_addr.s6_addr))) return module_wait_module; /* Let other module handle this. */ /* @@ -395,7 +486,8 @@ if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4))) return module_error; qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr, - dns64_env->prefix_net), (char*)qinfo.qname); + sizeof(sin6.sin6_addr.s6_addr), dns64_env->prefix_net), + (char*)qinfo.qname, MAX_PTR_QNAME_IPV4); /* Create the new sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); @@ -405,37 +497,12 @@ if (subq) { subq->curmod = id; subq->ext_state[id] = module_state_initial; - subq->minfo[id] = NULL; + subq->minfo[id] = NULL; } return module_wait_subquery; } -/** allocate (special) rrset keys, return 0 on error */ -static int -repinfo_alloc_rrset_keys(struct reply_info* rep, - struct regional* region) -{ - size_t i; - for(i=0; irrset_count; i++) { - if(region) { - rep->rrsets[i] = (struct ub_packed_rrset_key*) - regional_alloc(region, - sizeof(struct ub_packed_rrset_key)); - if(rep->rrsets[i]) { - memset(rep->rrsets[i], 0, - sizeof(struct ub_packed_rrset_key)); - rep->rrsets[i]->entry.key = rep->rrsets[i]; - } - } - else return 0;/* rep->rrsets[i] = alloc_special_obtain(alloc);*/ - if(!rep->rrsets[i]) - return 0; - rep->rrsets[i]->entry.data = NULL; - } - return 1; -} - static enum module_ext_state generate_type_A_query(struct module_qstate* qstate, int id) { @@ -466,6 +533,25 @@ } /** + * See if query name is in the always synth config. + * The ignore-aaaa list has names for which the AAAA for the domain is + * ignored and the A is always used to create the answer. + * @param qstate: query state. + * @param id: module id. + * @return true if the name is covered by ignore-aaaa. + */ +static int +dns64_always_synth_for_qname(struct module_qstate* qstate, int id) +{ + struct dns64_env* dns64_env = (struct dns64_env*)qstate->env->modinfo[id]; + int labs = dname_count_labels(qstate->qinfo.qname); + struct name_tree_node* node = name_tree_lookup(&dns64_env->ignore_aaaa, + qstate->qinfo.qname, qstate->qinfo.qname_len, labs, + qstate->qinfo.qclass); + return (node != NULL); +} + +/** * Handles the "pass" event for a query. This event is received when a new query * is received by this module. The query may have been generated internally by * another module, in which case we don't want to do any special processing @@ -481,7 +567,8 @@ static enum module_ext_state handle_event_pass(struct module_qstate* qstate, int id) { - if ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY + struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id]; + if (iq && iq->state == DNS64_NEW_QUERY && qstate->qinfo.qtype == LDNS_RR_TYPE_PTR && qstate->qinfo.qname_len == 74 && !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa")) @@ -489,12 +576,20 @@ return handle_ipv6_ptr(qstate, id); if (qstate->env->cfg->dns64_synthall && - (uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY + iq && iq->state == DNS64_NEW_QUERY && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) return generate_type_A_query(qstate, id); + if(dns64_always_synth_for_qname(qstate, id) && + iq && iq->state == DNS64_NEW_QUERY + && !(qstate->query_flags & BIT_CD) + && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) { + verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway"); + return generate_type_A_query(qstate, id); + } + /* We are finished when our sub-query is finished. */ - if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED) + if (iq && iq->state == DNS64_SUBQUERY_FINISHED) return module_finished; /* Otherwise, pass request to next module. */ @@ -515,6 +610,7 @@ static enum module_ext_state handle_event_moddone(struct module_qstate* qstate, int id) { + struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id]; /* * In many cases we have nothing special to do. From most to least common: * @@ -526,17 +622,36 @@ * synthesize in (sec 5.1.2 of RFC6147). * - A successful AAAA query with an answer. */ - if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY - || qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA - || (qstate->query_flags & BIT_CD) - || (qstate->return_msg && + if((!iq || iq->state != DNS64_INTERNAL_QUERY) + && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA + && !(qstate->query_flags & BIT_CD) + && !(qstate->return_msg && qstate->return_msg->rep && reply_find_answer_rrset(&qstate->qinfo, qstate->return_msg->rep))) - return module_finished; + /* not internal, type AAAA, not CD, and no answer RRset, + * So, this is a AAAA noerror/nodata answer */ + return generate_type_A_query(qstate, id); - /* So, this is a AAAA noerror/nodata answer */ - return generate_type_A_query(qstate, id); + if((!iq || iq->state != DNS64_INTERNAL_QUERY) + && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA + && !(qstate->query_flags & BIT_CD) + && dns64_always_synth_for_qname(qstate, id)) { + /* if it is not internal, AAAA, not CD and listed domain, + * generate from A record and ignore AAAA */ + verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway"); + return generate_type_A_query(qstate, id); + } + + /* Store the response in cache. */ + if ( (!iq || !iq->started_no_cache_store) && + qstate->return_msg && qstate->return_msg->rep && + !dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep, + 0, 0, 0, NULL, qstate->query_flags)) + log_err("out of memory"); + + /* do nothing */ + return module_finished; } /** @@ -555,6 +670,7 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound) { + struct dns64_qstate* iq; (void)outbound; verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s", id, strextstate(qstate->ext_state[id]), @@ -564,7 +680,13 @@ switch(event) { case module_event_new: /* Tag this query as being new and fall through. */ - qstate->minfo[id] = (void*)DNS64_NEW_QUERY; + iq = (struct dns64_qstate*)regional_alloc( + qstate->region, sizeof(*iq)); + qstate->minfo[id] = iq; + iq->state = DNS64_NEW_QUERY; + iq->started_no_cache_store = qstate->no_cache_store; + qstate->no_cache_store = 1; + /* fallthrough */ case module_event_pass: qstate->ext_state[id] = handle_event_pass(qstate, id); break; @@ -575,6 +697,11 @@ qstate->ext_state[id] = module_finished; break; } + if(qstate->ext_state[id] == module_finished) { + iq = (struct dns64_qstate*)qstate->minfo[id]; + if(iq && iq->state != DNS64_INTERNAL_QUERY) + qstate->no_cache_store = iq->started_no_cache_store; + } } static void @@ -630,8 +757,10 @@ dd->rr_data[i][1] = 16; synthesize_aaaa( ((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr, + sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr), dns64_env->prefix_net, &fd->rr_data[i][2], - &dd->rr_data[i][2] ); + fd->rr_len[i]-2, &dd->rr_data[i][2], + dd->rr_len[i]-2); dd->rr_ttl[i] = fd->rr_ttl[i]; } @@ -701,13 +830,14 @@ * Build the actual reply. */ cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount, - rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets, - rep->ar_numrrsets, rep->rrset_count, rep->security); + rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl, + rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets, + rep->rrset_count, rep->security); if(!cp) return; /* allocate ub_key structures special or not */ - if(!repinfo_alloc_rrset_keys(cp, super->region)) { + if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) { return; } @@ -729,6 +859,12 @@ rrset_cache_remove(super->env->rrset_cache, dk->rk.dname, dk->rk.dname_len, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN, 0); + /* Delete negative AAAA in msg cache for CNAMEs, + * stored by the iterator module */ + if(i != 0) /* if not the first RR */ + msg_cache_remove(super->env, dk->rk.dname, + dk->rk.dname_len, LDNS_RR_TYPE_AAAA, + LDNS_RR_CLASS_IN, 0); } else { dk->entry.hash = fk->entry.hash; dk->rk.dname = (uint8_t*)regional_alloc_init(super->region, @@ -780,9 +916,10 @@ * initial query's domain name. */ answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep); - log_assert(answer); - answer->rk.dname = super->qinfo.qname; - answer->rk.dname_len = super->qinfo.qname_len; + if(answer) { + answer->rk.dname = super->qinfo.qname; + answer->rk.dname_len = super->qinfo.qname_len; + } } /** @@ -798,6 +935,7 @@ dns64_inform_super(struct module_qstate* qstate, int id, struct module_qstate* super) { + struct dns64_qstate* super_dq = (struct dns64_qstate*)super->minfo[id]; log_query_info(VERB_ALGO, "dns64: inform_super, sub is", &qstate->qinfo); log_query_info(VERB_ALGO, "super is", &super->qinfo); @@ -806,16 +944,32 @@ * Signal that the sub-query is finished, no matter whether we are * successful or not. This lets the state machine terminate. */ - super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED; + if(!super_dq) { + super_dq = (struct dns64_qstate*)regional_alloc(super->region, + sizeof(*super_dq)); + if(!super_dq) { + log_err("out of memory"); + super->return_rcode = LDNS_RCODE_SERVFAIL; + super->return_msg = NULL; + return; + } + super->minfo[id] = super_dq; + memset(super_dq, 0, sizeof(*super_dq)); + super_dq->started_no_cache_store = super->no_cache_store; + } + super_dq->state = DNS64_SUBQUERY_FINISHED; /* If there is no successful answer, we're done. */ if (qstate->return_rcode != LDNS_RCODE_NOERROR || !qstate->return_msg - || !qstate->return_msg->rep - || !reply_find_answer_rrset(&qstate->qinfo, - qstate->return_msg->rep)) + || !qstate->return_msg->rep) { return; + } + /* Use return code from A query in response to client. */ + if (super->return_rcode != LDNS_RCODE_NOERROR) + super->return_rcode = qstate->return_rcode; + /* Generate a response suitable for the original query. */ if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) { dns64_adjust_a(id, super, qstate); @@ -825,8 +979,9 @@ } /* Store the generated response in cache. */ - if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, - 0, 0, 0, NULL, super->query_flags)) + if ( (!super_dq || !super_dq->started_no_cache_store) && + !dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, + 0, 0, 0, NULL, super->query_flags)) log_err("out of memory"); } --- contrib/unbound/dnscrypt/cert.h.orig +++ contrib/unbound/dnscrypt/cert.h @@ -0,0 +1,32 @@ +#ifndef UNBOUND_DNSCRYPT_CERT_H +#define UNBOUND_DNSCRYPT_CERT_H + +/** + * \file + * certificate type for dnscrypt for use in other header files + */ + +#include +#define CERT_MAGIC_CERT "DNSC" +#define CERT_MAJOR_VERSION 1 +#define CERT_MINOR_VERSION 0 +#define CERT_OLD_MAGIC_HEADER "7PYqwfzt" + +#define CERT_FILE_EXPIRE_DAYS 365 + +struct SignedCert { + uint8_t magic_cert[4]; + uint8_t version_major[2]; + uint8_t version_minor[2]; + + // Signed Content + uint8_t signed_content[64]; + uint8_t server_publickey[crypto_box_PUBLICKEYBYTES]; + uint8_t magic_query[8]; + uint8_t serial[4]; + uint8_t ts_begin[4]; + uint8_t ts_end[4]; +}; + + +#endif --- contrib/unbound/dnscrypt/dnscrypt.c.orig +++ contrib/unbound/dnscrypt/dnscrypt.c @@ -0,0 +1,1108 @@ + +#include "config.h" +#include +#include +#ifdef HAVE_TIME_H +#include +#endif +#include +#include +#include +#include "sldns/sbuffer.h" +#include "util/config_file.h" +#include "util/net_help.h" +#include "util/netevent.h" +#include "util/log.h" +#include "util/storage/slabhash.h" +#include "util/storage/lookup3.h" + +#include "dnscrypt/cert.h" +#include "dnscrypt/dnscrypt.h" +#include "dnscrypt/dnscrypt_config.h" + +#include + + +/** + * \file + * dnscrypt functions for encrypting DNS packets. + */ + +#define DNSCRYPT_QUERY_BOX_OFFSET \ + (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + \ + crypto_box_HALF_NONCEBYTES) + +// 8 bytes: magic header (CERT_MAGIC_HEADER) +// 12 bytes: the client's nonce +// 12 bytes: server nonce extension +// 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) + +#define DNSCRYPT_REPLY_BOX_OFFSET \ + (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES + \ + crypto_box_HALF_NONCEBYTES) + + +/** + * Shared secret cache key length. + * secret key. + * 1 byte: ES_VERSION[1] + * 32 bytes: client crypto_box_PUBLICKEYBYTES + * 32 bytes: server crypto_box_SECRETKEYBYTES + */ +#define DNSCRYPT_SHARED_SECRET_KEY_LENGTH \ + (1 + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES) + + +struct shared_secret_cache_key { + /** the hash table key */ + uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH]; + /** the hash table entry, data is uint8_t pointer of size crypto_box_BEFORENMBYTES which contains the shared secret. */ + struct lruhash_entry entry; +}; + + +struct nonce_cache_key { + /** the nonce used by the client */ + uint8_t nonce[crypto_box_HALF_NONCEBYTES]; + /** the client_magic used by the client, this is associated to 1 cert only */ + uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN]; + /** the client public key */ + uint8_t client_publickey[crypto_box_PUBLICKEYBYTES]; + /** the hash table entry, data is uint8_t */ + struct lruhash_entry entry; +}; + +/** + * Generate a key suitable to find shared secret in slabhash. + * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH + * \param[in] esversion: The es version least significant byte. + * \param[in] pk: The public key of the client. uint8_t pointer of size + * crypto_box_PUBLICKEYBYTES. + * \param[in] sk: The secret key of the server matching the magic query number. + * uint8_t pointer of size crypto_box_SECRETKEYBYTES. + * \return the hash of the key. + */ +static uint32_t +dnsc_shared_secrets_cache_key(uint8_t* key, + uint8_t esversion, + uint8_t* pk, + uint8_t* sk) +{ + key[0] = esversion; + memcpy(key + 1, pk, crypto_box_PUBLICKEYBYTES); + memcpy(key + 1 + crypto_box_PUBLICKEYBYTES, sk, crypto_box_SECRETKEYBYTES); + return hashlittle(key, DNSCRYPT_SHARED_SECRET_KEY_LENGTH, 0); +} + +/** + * Inserts a shared secret into the shared_secrets_cache slabhash. + * The shared secret is copied so the caller can use it freely without caring + * about the cache entry being evicted or not. + * \param[in] cache: the slabhash in which to look for the key. + * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH + * which contains the key of the shared secret. + * \param[in] hash: the hash of the key. + * \param[in] nmkey: a uint8_t pointer of size crypto_box_BEFORENMBYTES which + * contains the shared secret. + */ +static void +dnsc_shared_secret_cache_insert(struct slabhash *cache, + uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH], + uint32_t hash, + uint8_t nmkey[crypto_box_BEFORENMBYTES]) +{ + struct shared_secret_cache_key* k = + (struct shared_secret_cache_key*)calloc(1, sizeof(*k)); + uint8_t* d = malloc(crypto_box_BEFORENMBYTES); + if(!k || !d) { + free(k); + free(d); + return; + } + memcpy(d, nmkey, crypto_box_BEFORENMBYTES); + lock_rw_init(&k->entry.lock); + memcpy(k->key, key, DNSCRYPT_SHARED_SECRET_KEY_LENGTH); + k->entry.hash = hash; + k->entry.key = k; + k->entry.data = d; + slabhash_insert(cache, + hash, &k->entry, + d, + NULL); +} + +/** + * Lookup a record in shared_secrets_cache. + * \param[in] cache: a pointer to shared_secrets_cache slabhash. + * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH + * containing the key to look for. + * \param[in] hash: a hash of the key. + * \return a pointer to the locked cache entry or NULL on failure. + */ +static struct lruhash_entry* +dnsc_shared_secrets_lookup(struct slabhash* cache, + uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH], + uint32_t hash) +{ + return slabhash_lookup(cache, hash, key, 0); +} + +/** + * Generate a key hash suitable to find a nonce in slabhash. + * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES + * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN + * \param[in] pk: The public key of the client. uint8_t pointer of size + * crypto_box_PUBLICKEYBYTES. + * \return the hash of the key. + */ +static uint32_t +dnsc_nonce_cache_key_hash(const uint8_t nonce[crypto_box_HALF_NONCEBYTES], + const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN], + const uint8_t pk[crypto_box_PUBLICKEYBYTES]) +{ + uint32_t h = 0; + h = hashlittle(nonce, crypto_box_HALF_NONCEBYTES, h); + h = hashlittle(magic_query, DNSCRYPT_MAGIC_HEADER_LEN, h); + return hashlittle(pk, crypto_box_PUBLICKEYBYTES, h); +} + +/** + * Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash. + * \param[in] cache: the slabhash in which to look for the key. + * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES + * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN + * \param[in] pk: The public key of the client. uint8_t pointer of size + * crypto_box_PUBLICKEYBYTES. + * \param[in] hash: the hash of the key. + */ +static void +dnsc_nonce_cache_insert(struct slabhash *cache, + const uint8_t nonce[crypto_box_HALF_NONCEBYTES], + const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN], + const uint8_t pk[crypto_box_PUBLICKEYBYTES], + uint32_t hash) +{ + struct nonce_cache_key* k = + (struct nonce_cache_key*)calloc(1, sizeof(*k)); + if(!k) { + free(k); + return; + } + lock_rw_init(&k->entry.lock); + memcpy(k->nonce, nonce, crypto_box_HALF_NONCEBYTES); + memcpy(k->magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN); + memcpy(k->client_publickey, pk, crypto_box_PUBLICKEYBYTES); + k->entry.hash = hash; + k->entry.key = k; + k->entry.data = NULL; + slabhash_insert(cache, + hash, &k->entry, + NULL, + NULL); +} + +/** + * Lookup a record in nonces_cache. + * \param[in] cache: the slabhash in which to look for the key. + * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES + * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN + * \param[in] pk: The public key of the client. uint8_t pointer of size + * crypto_box_PUBLICKEYBYTES. + * \param[in] hash: the hash of the key. + * \return a pointer to the locked cache entry or NULL on failure. + */ +static struct lruhash_entry* +dnsc_nonces_lookup(struct slabhash* cache, + const uint8_t nonce[crypto_box_HALF_NONCEBYTES], + const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN], + const uint8_t pk[crypto_box_PUBLICKEYBYTES], + uint32_t hash) +{ + struct nonce_cache_key k; + memset(&k, 0, sizeof(k)); + k.entry.hash = hash; + memcpy(k.nonce, nonce, crypto_box_HALF_NONCEBYTES); + memcpy(k.magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN); + memcpy(k.client_publickey, pk, crypto_box_PUBLICKEYBYTES); + + return slabhash_lookup(cache, hash, &k, 0); +} + +/** + * Decrypt a query using the dnsccert that was found using dnsc_find_cert. + * The client nonce will be extracted from the encrypted query and stored in + * client_nonce, a shared secret will be computed and stored in nmkey and the + * buffer will be decrypted inplace. + * \param[in] env the dnscrypt environment. + * \param[in] cert the cert that matches this encrypted query. + * \param[in] client_nonce where the client nonce will be stored. + * \param[in] nmkey where the shared secret key will be written. + * \param[in] buffer the encrypted buffer. + * \return 0 on success. + */ +static int +dnscrypt_server_uncurve(struct dnsc_env* env, + const dnsccert *cert, + uint8_t client_nonce[crypto_box_HALF_NONCEBYTES], + uint8_t nmkey[crypto_box_BEFORENMBYTES], + struct sldns_buffer* buffer) +{ + size_t len = sldns_buffer_limit(buffer); + uint8_t *const buf = sldns_buffer_begin(buffer); + uint8_t nonce[crypto_box_NONCEBYTES]; + struct dnscrypt_query_header *query_header; + // shared secret cache + uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH]; + struct lruhash_entry* entry; + uint32_t hash; + + uint32_t nonce_hash; + + if (len <= DNSCRYPT_QUERY_HEADER_SIZE) { + return -1; + } + + query_header = (struct dnscrypt_query_header *)buf; + + /* Detect replay attacks */ + nonce_hash = dnsc_nonce_cache_key_hash( + query_header->nonce, + cert->magic_query, + query_header->publickey); + + lock_basic_lock(&env->nonces_cache_lock); + entry = dnsc_nonces_lookup( + env->nonces_cache, + query_header->nonce, + cert->magic_query, + query_header->publickey, + nonce_hash); + + if(entry) { + lock_rw_unlock(&entry->lock); + env->num_query_dnscrypt_replay++; + lock_basic_unlock(&env->nonces_cache_lock); + return -1; + } + + dnsc_nonce_cache_insert( + env->nonces_cache, + query_header->nonce, + cert->magic_query, + query_header->publickey, + nonce_hash); + lock_basic_unlock(&env->nonces_cache_lock); + + /* Find existing shared secret */ + hash = dnsc_shared_secrets_cache_key(key, + cert->es_version[1], + query_header->publickey, + cert->keypair->crypt_secretkey); + entry = dnsc_shared_secrets_lookup(env->shared_secrets_cache, + key, + hash); + + if(!entry) { + lock_basic_lock(&env->shared_secrets_cache_lock); + env->num_query_dnscrypt_secret_missed_cache++; + lock_basic_unlock(&env->shared_secrets_cache_lock); + if(cert->es_version[1] == 2) { +#ifdef USE_DNSCRYPT_XCHACHA20 + if (crypto_box_curve25519xchacha20poly1305_beforenm( + nmkey, query_header->publickey, + cert->keypair->crypt_secretkey) != 0) { + return -1; + } +#else + return -1; +#endif + } else { + if (crypto_box_beforenm(nmkey, + query_header->publickey, + cert->keypair->crypt_secretkey) != 0) { + return -1; + } + } + // Cache the shared secret we just computed. + dnsc_shared_secret_cache_insert(env->shared_secrets_cache, + key, + hash, + nmkey); + } else { + /* copy shared secret and unlock entry */ + memcpy(nmkey, entry->data, crypto_box_BEFORENMBYTES); + lock_rw_unlock(&entry->lock); + } + + memcpy(nonce, query_header->nonce, crypto_box_HALF_NONCEBYTES); + memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES); + + if(cert->es_version[1] == 2) { +#ifdef USE_DNSCRYPT_XCHACHA20 + if (crypto_box_curve25519xchacha20poly1305_open_easy_afternm + (buf, + buf + DNSCRYPT_QUERY_BOX_OFFSET, + len - DNSCRYPT_QUERY_BOX_OFFSET, nonce, + nmkey) != 0) { + return -1; + } +#else + return -1; +#endif + } else { + if (crypto_box_open_easy_afternm + (buf, + buf + DNSCRYPT_QUERY_BOX_OFFSET, + len - DNSCRYPT_QUERY_BOX_OFFSET, nonce, + nmkey) != 0) { + return -1; + } + } + + len -= DNSCRYPT_QUERY_HEADER_SIZE; + + while (*sldns_buffer_at(buffer, --len) == 0) + ; + + if (*sldns_buffer_at(buffer, len) != 0x80) { + return -1; + } + + memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES); + + sldns_buffer_set_position(buffer, 0); + sldns_buffer_set_limit(buffer, len); + + return 0; +} + + +/** + * Add random padding to a buffer, according to a client nonce. + * The length has to depend on the query in order to avoid reply attacks. + * + * @param buf a buffer + * @param len the initial size of the buffer + * @param max_len the maximum size + * @param nonce a nonce, made of the client nonce repeated twice + * @param secretkey + * @return the new size, after padding + */ +size_t +dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len, + const uint8_t *nonce, const uint8_t *secretkey) +{ + uint8_t *buf_padding_area = buf + len; + size_t padded_len; + uint32_t rnd; + + // no padding + if (max_len < len + DNSCRYPT_MIN_PAD_LEN) + return len; + + assert(nonce[crypto_box_HALF_NONCEBYTES] == nonce[0]); + + crypto_stream((unsigned char *)&rnd, (unsigned long long)sizeof(rnd), nonce, + secretkey); + padded_len = + len + DNSCRYPT_MIN_PAD_LEN + rnd % (max_len - len - + DNSCRYPT_MIN_PAD_LEN + 1); + padded_len += DNSCRYPT_BLOCK_SIZE - padded_len % DNSCRYPT_BLOCK_SIZE; + if (padded_len > max_len) + padded_len = max_len; + + memset(buf_padding_area, 0, padded_len - len); + *buf_padding_area = 0x80; + + return padded_len; +} + +uint64_t +dnscrypt_hrtime(void) +{ + struct timeval tv; + uint64_t ts = (uint64_t)0U; + int ret; + + ret = gettimeofday(&tv, NULL); + if (ret == 0) { + ts = (uint64_t)tv.tv_sec * 1000000U + (uint64_t)tv.tv_usec; + } else { + log_err("gettimeofday: %s", strerror(errno)); + } + return ts; +} + +/** + * Add the server nonce part to once. + * The nonce is made half of client nonce and the seconf half of the server + * nonce, both of them of size crypto_box_HALF_NONCEBYTES. + * \param[in] nonce: a uint8_t* of size crypto_box_NONCEBYTES + */ +static void +add_server_nonce(uint8_t *nonce) +{ + randombytes_buf(nonce + crypto_box_HALF_NONCEBYTES, 8/*tsn*/+4/*suffix*/); +} + +/** + * Encrypt a reply using the dnsccert that was used with the query. + * The client nonce will be extracted from the encrypted query and stored in + * The buffer will be encrypted inplace. + * \param[in] cert the dnsccert that matches this encrypted query. + * \param[in] client_nonce client nonce used during the query + * \param[in] nmkey shared secret key used during the query. + * \param[in] buffer the buffer where to encrypt the reply. + * \param[in] udp if whether or not it is a UDP query. + * \param[in] max_udp_size configured max udp size. + * \return 0 on success. + */ +static int +dnscrypt_server_curve(const dnsccert *cert, + uint8_t client_nonce[crypto_box_HALF_NONCEBYTES], + uint8_t nmkey[crypto_box_BEFORENMBYTES], + struct sldns_buffer* buffer, + uint8_t udp, + size_t max_udp_size) +{ + size_t dns_reply_len = sldns_buffer_limit(buffer); + size_t max_len = dns_reply_len + DNSCRYPT_MAX_PADDING \ + + DNSCRYPT_REPLY_HEADER_SIZE; + size_t max_reply_size = max_udp_size - 20U - 8U; + uint8_t nonce[crypto_box_NONCEBYTES]; + uint8_t *boxed; + uint8_t *const buf = sldns_buffer_begin(buffer); + size_t len = sldns_buffer_limit(buffer); + + if(udp){ + if (max_len > max_reply_size) + max_len = max_reply_size; + } + + + memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES); + memcpy(nonce + crypto_box_HALF_NONCEBYTES, client_nonce, + crypto_box_HALF_NONCEBYTES); + + boxed = buf + DNSCRYPT_REPLY_BOX_OFFSET; + memmove(boxed + crypto_box_MACBYTES, buf, len); + len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len, + max_len - DNSCRYPT_REPLY_HEADER_SIZE, nonce, + cert->keypair->crypt_secretkey); + sldns_buffer_set_at(buffer, + DNSCRYPT_REPLY_BOX_OFFSET - crypto_box_BOXZEROBYTES, + 0, crypto_box_ZEROBYTES); + + // add server nonce extension + add_server_nonce(nonce); + + if(cert->es_version[1] == 2) { +#ifdef USE_DNSCRYPT_XCHACHA20 + if (crypto_box_curve25519xchacha20poly1305_easy_afternm + (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) { + return -1; + } +#else + return -1; +#endif + } else { + if (crypto_box_easy_afternm + (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) { + return -1; + } + } + + sldns_buffer_write_at(buffer, + 0, + DNSCRYPT_MAGIC_RESPONSE, + DNSCRYPT_MAGIC_HEADER_LEN); + sldns_buffer_write_at(buffer, + DNSCRYPT_MAGIC_HEADER_LEN, + nonce, + crypto_box_NONCEBYTES); + sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE); + return 0; +} + +/** + * Read the content of fname into buf. + * \param[in] fname name of the file to read. + * \param[in] buf the buffer in which to read the content of the file. + * \param[in] count number of bytes to read. + * \return 0 on success. + */ +static int +dnsc_read_from_file(char *fname, char *buf, size_t count) +{ + int fd; + fd = open(fname, O_RDONLY); + if (fd == -1) { + return -1; + } + if (read(fd, buf, count) != (ssize_t)count) { + close(fd); + return -2; + } + close(fd); + return 0; +} + +/** + * Given an absolute path on the original root, returns the absolute path + * within the chroot. If chroot is disabled, the path is not modified. + * No char * is malloced so there is no need to free this. + * \param[in] cfg the configuration. + * \param[in] path the path from the original root. + * \return the path from inside the chroot. + */ +static char * +dnsc_chroot_path(struct config_file *cfg, char *path) +{ + char *nm; + nm = path; + if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm, + cfg->chrootdir, strlen(cfg->chrootdir)) == 0) + nm += strlen(cfg->chrootdir); + return nm; +} + +/** + * Parse certificates files provided by the configuration and load them into + * dnsc_env. + * \param[in] env the dnsc_env structure to load the certs into. + * \param[in] cfg the configuration. + * \return the number of certificates loaded. + */ +static int +dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg) +{ + struct config_strlist *head, *head2; + size_t signed_cert_id; + size_t rotated_cert_id; + char *nm; + + env->signed_certs_count = 0U; + env->rotated_certs_count = 0U; + for (head = cfg->dnscrypt_provider_cert; head; head = head->next) { + env->signed_certs_count++; + } + for (head = cfg->dnscrypt_provider_cert_rotated; head; head = head->next) { + env->rotated_certs_count++; + } + env->signed_certs = sodium_allocarray(env->signed_certs_count, + sizeof *env->signed_certs); + + env->rotated_certs = sodium_allocarray(env->rotated_certs_count, + sizeof env->signed_certs); + signed_cert_id = 0U; + rotated_cert_id = 0U; + for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) { + nm = dnsc_chroot_path(cfg, head->str); + if(dnsc_read_from_file( + nm, + (char *)(env->signed_certs + signed_cert_id), + sizeof(struct SignedCert)) != 0) { + fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno)); + } + for(head2 = cfg->dnscrypt_provider_cert_rotated; head2; head2 = head2->next) { + if(strcmp(head->str, head2->str) == 0) { + *(env->rotated_certs + rotated_cert_id) = env->signed_certs + signed_cert_id; + rotated_cert_id++; + verbose(VERB_OPS, "Cert %s is rotated and will not be distributed via DNS", head->str); + break; + } + } + verbose(VERB_OPS, "Loaded cert %s", head->str); + } + return signed_cert_id; +} + +/** + * Helper function to convert a binary key into a printable fingerprint. + * \param[in] fingerprint the buffer in which to write the printable key. + * \param[in] key the key to convert. + */ +void +dnsc_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key) +{ + const size_t fingerprint_size = 80U; + size_t fingerprint_pos = (size_t) 0U; + size_t key_pos = (size_t) 0U; + + for (;;) { + assert(fingerprint_size > fingerprint_pos); + snprintf(&fingerprint[fingerprint_pos], + fingerprint_size - fingerprint_pos, "%02X%02X", + key[key_pos], key[key_pos + 1U]); + key_pos += 2U; + if (key_pos >= crypto_box_PUBLICKEYBYTES) { + break; + } + fingerprint[fingerprint_pos + 4U] = ':'; + fingerprint_pos += 5U; + } +} + +/** + * Find the cert matching a DNSCrypt query. + * \param[in] dnscenv The DNSCrypt environment, which contains the list of certs + * supported by the server. + * \param[in] buffer The encrypted DNS query. + * \return a dnsccert * if we found a cert matching the magic_number of the + * query, NULL otherwise. + */ +static const dnsccert * +dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer) +{ + const dnsccert *certs = dnscenv->certs; + struct dnscrypt_query_header *dnscrypt_header; + size_t i; + + if (sldns_buffer_limit(buffer) < DNSCRYPT_QUERY_HEADER_SIZE) { + return NULL; + } + dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer); + for (i = 0U; i < dnscenv->signed_certs_count; i++) { + if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query, + DNSCRYPT_MAGIC_HEADER_LEN) == 0) { + return &certs[i]; + } + } + return NULL; +} + +/** + * Insert local-zone and local-data into configuration. + * In order to be able to serve certs over TXT, we can reuse the local-zone and + * local-data config option. The zone and qname are infered from the + * provider_name and the content of the TXT record from the certificate content. + * returns the number of certificate TXT record that were loaded. + * < 0 in case of error. + */ +static int +dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg) +{ + size_t i, j; + // Insert 'local-zone: "2.dnscrypt-cert.example.com" deny' + if(!cfg_str2list_insert(&cfg->local_zones, + strdup(dnscenv->provider_name), + strdup("deny"))) { + log_err("Could not load dnscrypt local-zone: %s deny", + dnscenv->provider_name); + return -1; + } + + // Add local data entry of type: + // 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......" + for(i=0; isigned_certs_count; i++) { + const char *ttl_class_type = " 86400 IN TXT \""; + int rotated_cert = 0; + uint32_t serial; + uint16_t rrlen; + char* rr; + struct SignedCert *cert = dnscenv->signed_certs + i; + // Check if the certificate is being rotated and should not be published + for(j=0; jrotated_certs_count; j++){ + if(cert == dnscenv->rotated_certs[j]) { + rotated_cert = 1; + break; + } + } + memcpy(&serial, cert->serial, sizeof serial); + serial = htonl(serial); + if(rotated_cert) { + verbose(VERB_OPS, + "DNSCrypt: not adding cert with serial #%" + PRIu32 + " to local-data as it is rotated", + serial + ); + continue; + } + if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) { + /* guard against integer overflow in rrlen calculation */ + verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial); + continue; + } + rrlen = strlen(dnscenv->provider_name) + + strlen(ttl_class_type) + + 4 * sizeof(struct SignedCert) + // worst case scenario + 1 + // trailing double quote + 1; + rr = malloc(rrlen); + if(!rr) { + log_err("Could not allocate memory"); + return -2; + } + snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name); + for(j=0; jlocal_data, strdup(rr)); + free(rr); + } + return dnscenv->signed_certs_count; +} + +static const char * +key_get_es_version(uint8_t version[2]) +{ + struct es_version { + uint8_t es_version[2]; + const char *name; + }; + + const int num_versions = 2; + struct es_version es_versions[] = { + {{0x00, 0x01}, "X25519-XSalsa20Poly1305"}, + {{0x00, 0x02}, "X25519-XChacha20Poly1305"}, + }; + int i; + for(i=0; i < num_versions; i++){ + if(es_versions[i].es_version[0] == version[0] && + es_versions[i].es_version[1] == version[1]){ + return es_versions[i].name; + } + } + return NULL; +} + + +/** + * Parse the secret key files from `dnscrypt-secret-key` config and populates + * a list of dnsccert with es_version, magic number and secret/public keys + * supported by dnscrypt listener. + * \param[in] env The dnsc_env structure which will hold the keypairs. + * \param[in] cfg The config with the secret key file paths. + */ +static int +dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg) +{ + struct config_strlist *head; + size_t cert_id, keypair_id; + size_t c; + char *nm; + + env->keypairs_count = 0U; + for (head = cfg->dnscrypt_secret_key; head; head = head->next) { + env->keypairs_count++; + } + + env->keypairs = sodium_allocarray(env->keypairs_count, + sizeof *env->keypairs); + env->certs = sodium_allocarray(env->signed_certs_count, + sizeof *env->certs); + + cert_id = 0U; + keypair_id = 0U; + for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) { + char fingerprint[80]; + int found_cert = 0; + KeyPair *current_keypair = &env->keypairs[keypair_id]; + nm = dnsc_chroot_path(cfg, head->str); + if(dnsc_read_from_file( + nm, + (char *)(current_keypair->crypt_secretkey), + crypto_box_SECRETKEYBYTES) != 0) { + fatal_exit("dnsc_parse_keys: failed to load %s: %s", head->str, strerror(errno)); + } + verbose(VERB_OPS, "Loaded key %s", head->str); + if (crypto_scalarmult_base(current_keypair->crypt_publickey, + current_keypair->crypt_secretkey) != 0) { + fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str); + } + dnsc_key_to_fingerprint(fingerprint, current_keypair->crypt_publickey); + verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint); + // find the cert matching this key + for(c = 0; c < env->signed_certs_count; c++) { + if(memcmp(current_keypair->crypt_publickey, + env->signed_certs[c].server_publickey, + crypto_box_PUBLICKEYBYTES) == 0) { + dnsccert *current_cert = &env->certs[cert_id++]; + found_cert = 1; + current_cert->keypair = current_keypair; + memcpy(current_cert->magic_query, + env->signed_certs[c].magic_query, + sizeof env->signed_certs[c].magic_query); + memcpy(current_cert->es_version, + env->signed_certs[c].version_major, + sizeof env->signed_certs[c].version_major + ); + dnsc_key_to_fingerprint(fingerprint, + current_cert->keypair->crypt_publickey); + verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", + head->str, fingerprint); + verbose(VERB_OPS, "Using %s", + key_get_es_version(current_cert->es_version)); +#ifndef USE_DNSCRYPT_XCHACHA20 + if (current_cert->es_version[1] == 0x02) { + fatal_exit("Certificate for XChacha20 but libsodium does not support it."); + } +#endif + + } + } + if (!found_cert) { + fatal_exit("dnsc_parse_keys: could not match certificate for key " + "%s. Unable to determine ES version.", + head->str); + } + } + return cert_id; +} + +static void +sodium_misuse_handler(void) +{ + fatal_exit( + "dnscrypt: libsodium could not be initialized, this typically" + " happens when no good source of entropy is found. If you run" + " unbound in a chroot, make sure /dev/urandom is available. See" + " https://www.unbound.net/documentation/unbound.conf.html"); +} + + +/** + * ######################################################### + * ############# Publicly accessible functions ############# + * ######################################################### + */ + +int +dnsc_handle_curved_request(struct dnsc_env* dnscenv, + struct comm_reply* repinfo) +{ + struct comm_point* c = repinfo->c; + + repinfo->is_dnscrypted = 0; + if( !c->dnscrypt ) { + return 1; + } + // Attempt to decrypt the query. If it is not crypted, we may still need + // to serve the certificate. + verbose(VERB_ALGO, "handle request called on DNSCrypt socket"); + if ((repinfo->dnsc_cert = dnsc_find_cert(dnscenv, c->buffer)) != NULL) { + if(dnscrypt_server_uncurve(dnscenv, + repinfo->dnsc_cert, + repinfo->client_nonce, + repinfo->nmkey, + c->buffer) != 0){ + verbose(VERB_ALGO, "dnscrypt: Failed to uncurve"); + comm_point_drop_reply(repinfo); + return 0; + } + repinfo->is_dnscrypted = 1; + sldns_buffer_rewind(c->buffer); + } + return 1; +} + +int +dnsc_handle_uncurved_request(struct comm_reply *repinfo) +{ + if(!repinfo->c->dnscrypt) { + return 1; + } + sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer); + if(!repinfo->is_dnscrypted) { + return 1; + } + if(dnscrypt_server_curve(repinfo->dnsc_cert, + repinfo->client_nonce, + repinfo->nmkey, + repinfo->c->dnscrypt_buffer, + repinfo->c->type == comm_udp, + repinfo->max_udp_size) != 0){ + verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer"); + comm_point_drop_reply(repinfo); + return 0; + } + return 1; +} + +struct dnsc_env * +dnsc_create(void) +{ + struct dnsc_env *env; +#ifdef SODIUM_MISUSE_HANDLER + sodium_set_misuse_handler(sodium_misuse_handler); +#endif + if (sodium_init() == -1) { + fatal_exit("dnsc_create: could not initialize libsodium."); + } + env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env)); + lock_basic_init(&env->shared_secrets_cache_lock); + lock_protect(&env->shared_secrets_cache_lock, + &env->num_query_dnscrypt_secret_missed_cache, + sizeof(env->num_query_dnscrypt_secret_missed_cache)); + lock_basic_init(&env->nonces_cache_lock); + lock_protect(&env->nonces_cache_lock, + &env->nonces_cache, + sizeof(env->nonces_cache)); + lock_protect(&env->nonces_cache_lock, + &env->num_query_dnscrypt_replay, + sizeof(env->num_query_dnscrypt_replay)); + + return env; +} + +int +dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg) +{ + if(dnsc_parse_certs(env, cfg) <= 0) { + fatal_exit("dnsc_apply_cfg: no cert file loaded"); + } + if(dnsc_parse_keys(env, cfg) <= 0) { + fatal_exit("dnsc_apply_cfg: no key file loaded"); + } + randombytes_buf(env->hash_key, sizeof env->hash_key); + env->provider_name = cfg->dnscrypt_provider; + + if(dnsc_load_local_data(env, cfg) <= 0) { + fatal_exit("dnsc_apply_cfg: could not load local data"); + } + lock_basic_lock(&env->shared_secrets_cache_lock); + env->shared_secrets_cache = slabhash_create( + cfg->dnscrypt_shared_secret_cache_slabs, + HASH_DEFAULT_STARTARRAY, + cfg->dnscrypt_shared_secret_cache_size, + dnsc_shared_secrets_sizefunc, + dnsc_shared_secrets_compfunc, + dnsc_shared_secrets_delkeyfunc, + dnsc_shared_secrets_deldatafunc, + NULL + ); + lock_basic_unlock(&env->shared_secrets_cache_lock); + if(!env->shared_secrets_cache){ + fatal_exit("dnsc_apply_cfg: could not create shared secrets cache."); + } + lock_basic_lock(&env->nonces_cache_lock); + env->nonces_cache = slabhash_create( + cfg->dnscrypt_nonce_cache_slabs, + HASH_DEFAULT_STARTARRAY, + cfg->dnscrypt_nonce_cache_size, + dnsc_nonces_sizefunc, + dnsc_nonces_compfunc, + dnsc_nonces_delkeyfunc, + dnsc_nonces_deldatafunc, + NULL + ); + lock_basic_unlock(&env->nonces_cache_lock); + return 0; +} + +void +dnsc_delete(struct dnsc_env *env) +{ + if(!env) { + return; + } + verbose(VERB_OPS, "DNSCrypt: Freeing environment."); + sodium_free(env->signed_certs); + sodium_free(env->rotated_certs); + sodium_free(env->certs); + sodium_free(env->keypairs); + lock_basic_destroy(&env->shared_secrets_cache_lock); + lock_basic_destroy(&env->nonces_cache_lock); + slabhash_delete(env->shared_secrets_cache); + slabhash_delete(env->nonces_cache); + free(env); +} + +/** + * ######################################################### + * ############# Shared secrets cache functions ############ + * ######################################################### + */ + +size_t +dnsc_shared_secrets_sizefunc(void *k, void* ATTR_UNUSED(d)) +{ + struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k; + size_t key_size = sizeof(struct shared_secret_cache_key) + + lock_get_mem(&ssk->entry.lock); + size_t data_size = crypto_box_BEFORENMBYTES; + (void)ssk; /* otherwise ssk is unused if no threading, or fixed locksize */ + return key_size + data_size; +} + +int +dnsc_shared_secrets_compfunc(void *m1, void *m2) +{ + return sodium_memcmp(m1, m2, DNSCRYPT_SHARED_SECRET_KEY_LENGTH); +} + +void +dnsc_shared_secrets_delkeyfunc(void *k, void* ATTR_UNUSED(arg)) +{ + struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k; + lock_rw_destroy(&ssk->entry.lock); + free(ssk); +} + +void +dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UNUSED(arg)) +{ + uint8_t* data = (uint8_t*)d; + free(data); +} + +/** + * ######################################################### + * ############### Nonces cache functions ################## + * ######################################################### + */ + +size_t +dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d)) +{ + struct nonce_cache_key* nk = (struct nonce_cache_key*)k; + size_t key_size = sizeof(struct nonce_cache_key) + + lock_get_mem(&nk->entry.lock); + (void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */ + return key_size; +} + +int +dnsc_nonces_compfunc(void *m1, void *m2) +{ + struct nonce_cache_key *k1 = m1, *k2 = m2; + return + sodium_memcmp( + k1->nonce, + k2->nonce, + crypto_box_HALF_NONCEBYTES) != 0 || + sodium_memcmp( + k1->magic_query, + k2->magic_query, + DNSCRYPT_MAGIC_HEADER_LEN) != 0 || + sodium_memcmp( + k1->client_publickey, k2->client_publickey, + crypto_box_PUBLICKEYBYTES) != 0; +} + +void +dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg)) +{ + struct nonce_cache_key* nk = (struct nonce_cache_key*)k; + lock_rw_destroy(&nk->entry.lock); + free(nk); +} + +void +dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg)) +{ + return; +} --- contrib/unbound/dnscrypt/dnscrypt.h.orig +++ contrib/unbound/dnscrypt/dnscrypt.h @@ -0,0 +1,175 @@ +#ifndef UNBOUND_DNSCRYPT_H +#define UNBOUND_DNSCRYPT_H + +/** + * \file + * dnscrypt functions for encrypting DNS packets. + */ + +#include "dnscrypt/dnscrypt_config.h" +#ifdef USE_DNSCRYPT + +#define DNSCRYPT_MAGIC_HEADER_LEN 8U +#define DNSCRYPT_MAGIC_RESPONSE "r6fnvWj8" + +#ifndef DNSCRYPT_MAX_PADDING +# define DNSCRYPT_MAX_PADDING 256U +#endif +#ifndef DNSCRYPT_BLOCK_SIZE +# define DNSCRYPT_BLOCK_SIZE 64U +#endif +#ifndef DNSCRYPT_MIN_PAD_LEN +# define DNSCRYPT_MIN_PAD_LEN 8U +#endif + +#define crypto_box_HALF_NONCEBYTES (crypto_box_NONCEBYTES / 2U) + +#include "config.h" +#include "dnscrypt/cert.h" +#include "util/locks.h" + +#define DNSCRYPT_QUERY_HEADER_SIZE \ + (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + crypto_box_MACBYTES) +#define DNSCRYPT_RESPONSE_HEADER_SIZE \ + (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_NONCEBYTES + crypto_box_MACBYTES) + +#define DNSCRYPT_REPLY_HEADER_SIZE \ + (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES * 2 + crypto_box_MACBYTES) + +struct sldns_buffer; +struct config_file; +struct comm_reply; +struct slabhash; + +typedef struct KeyPair_ { + uint8_t crypt_publickey[crypto_box_PUBLICKEYBYTES]; + uint8_t crypt_secretkey[crypto_box_SECRETKEYBYTES]; +} KeyPair; + +typedef struct cert_ { + uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN]; + uint8_t es_version[2]; + KeyPair *keypair; +} dnsccert; + +struct dnsc_env { + struct SignedCert *signed_certs; + struct SignedCert **rotated_certs; + dnsccert *certs; + size_t signed_certs_count; + size_t rotated_certs_count; + uint8_t provider_publickey[crypto_sign_ed25519_PUBLICKEYBYTES]; + uint8_t provider_secretkey[crypto_sign_ed25519_SECRETKEYBYTES]; + KeyPair *keypairs; + size_t keypairs_count; + uint64_t nonce_ts_last; + unsigned char hash_key[crypto_shorthash_KEYBYTES]; + char * provider_name; + + /** Caches */ + struct slabhash *shared_secrets_cache; + /** lock on shared secret cache counters */ + lock_basic_type shared_secrets_cache_lock; + /** number of misses from shared_secrets_cache */ + size_t num_query_dnscrypt_secret_missed_cache; + + /** slabhash keeping track of nonce/cient pk/server sk pairs. */ + struct slabhash *nonces_cache; + /** lock on nonces_cache, used to avoid race condition in updating the hash */ + lock_basic_type nonces_cache_lock; + /** number of replayed queries */ + size_t num_query_dnscrypt_replay; +}; + +struct dnscrypt_query_header { + uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN]; + uint8_t publickey[crypto_box_PUBLICKEYBYTES]; + uint8_t nonce[crypto_box_HALF_NONCEBYTES]; + uint8_t mac[crypto_box_MACBYTES]; +}; + +/** + * Initialize DNSCrypt environment. + * Initialize sodium library and allocate the dnsc_env structure. + * \return an uninitialized struct dnsc_env. + */ +struct dnsc_env * dnsc_create(void); + +/** + * Apply configuration. + * Read certificates and secret keys from configuration. Initialize hashkey and + * provider name as well as loading cert TXT records. + * In case of issue applying configuration, this function fatals. + * \param[in] env the struct dnsc_env to populate. + * \param[in] cfg the config_file struct with dnscrypt options. + * \return 0 on success. + */ +int dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg); + +/** + * Delete DNSCrypt environment + * + */ +void dnsc_delete(struct dnsc_env *env); + +/** + * handle a crypted dnscrypt request. + * Determine wether or not a query is coming over the dnscrypt listener and + * attempt to uncurve it or detect if it is a certificate query. + * return 0 in case of failure. + */ +int dnsc_handle_curved_request(struct dnsc_env* dnscenv, + struct comm_reply* repinfo); +/** + * handle an unencrypted dnscrypt request. + * Determine wether or not a query is going over the dnscrypt channel and + * attempt to curve it unless it was not crypted like when it is a + * certificate query. + * \return 0 in case of failure. + */ + +int dnsc_handle_uncurved_request(struct comm_reply *repinfo); + +/** + * Computes the size of the shared secret cache entry. + */ +size_t dnsc_shared_secrets_sizefunc(void *k, void *d); + +/** + * Compares two shared secret cache keys. + */ +int dnsc_shared_secrets_compfunc(void *m1, void *m2); + +/** + * Function to delete a shared secret cache key. + */ +void dnsc_shared_secrets_delkeyfunc(void *k, void* arg); + +/** + * Function to delete a share secret cache value. + */ +void dnsc_shared_secrets_deldatafunc(void* d, void* arg); + +/** + * Computes the size of the nonce cache entry. + */ +size_t dnsc_nonces_sizefunc(void *k, void *d); + +/** + * Compares two nonce cache keys. + */ +int dnsc_nonces_compfunc(void *m1, void *m2); + +/** + * Function to delete a nonce cache key. + */ +void dnsc_nonces_delkeyfunc(void *k, void* arg); + +/** + * Function to delete a nonce cache value. + */ +void dnsc_nonces_deldatafunc(void* d, void* arg); + + +#endif /* USE_DNSCRYPT */ +#endif --- contrib/unbound/dnscrypt/dnscrypt.m4.orig +++ contrib/unbound/dnscrypt/dnscrypt.m4 @@ -0,0 +1,44 @@ +# dnscrypt.m4 + +# dnsc_DNSCRYPT([action-if-true], [action-if-false]) +# -------------------------------------------------------------------------- +# Check for required dnscrypt libraries and add dnscrypt configure args. +AC_DEFUN([dnsc_DNSCRYPT], +[ + AC_ARG_ENABLE([dnscrypt], + AS_HELP_STRING([--enable-dnscrypt], + [Enable dnscrypt support (requires libsodium)]), + [opt_dnscrypt=$enableval], [opt_dnscrypt=no]) + + if test "x$opt_dnscrypt" != "xno"; then + AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path], + [Path where libsodium is installed, for dnscrypt]), [ + CFLAGS="$CFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + ]) + AC_SEARCH_LIBS([sodium_init], [sodium], [], + AC_MSG_ERROR([The sodium library was not found. Please install sodium!])) + AC_SEARCH_LIBS([crypto_box_curve25519xchacha20poly1305_beforenm], [sodium], + [ + AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [1]) + AC_DEFINE( + [USE_DNSCRYPT_XCHACHA20], [1], + [Define to 1 to enable dnscrypt with xchacha20 support]) + ], + [ + AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0]) + ]) + AC_SEARCH_LIBS([sodium_set_misuse_handler], [sodium], + [ + AC_DEFINE( + [SODIUM_MISUSE_HANDLER], [1], + [Define to 1 if libsodium supports sodium_set_misuse_handler]) + ], + [ + ]) + $1 + else + AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0]) + $2 + fi +]) --- contrib/unbound/dnscrypt/dnscrypt_config.h.orig +++ contrib/unbound/dnscrypt/dnscrypt_config.h @@ -0,0 +1,17 @@ +#ifndef UNBOUND_DNSCRYPT_CONFIG_H +#define UNBOUND_DNSCRYPT_CONFIG_H + +/* + * Process this file (dnscrypt_config.h.in) with AC_CONFIG_FILES to generate + * dnscrypt_config.h. + * + * This file exists so that USE_DNSCRYPT can be used without including config.h. + */ + +#if 0 /* ENABLE_DNSCRYPT */ +# ifndef USE_DNSCRYPT +# define USE_DNSCRYPT 1 +# endif +#endif + +#endif /* UNBOUND_DNSCRYPT_CONFIG_H */ --- contrib/unbound/dnscrypt/dnscrypt_config.h.in.orig +++ contrib/unbound/dnscrypt/dnscrypt_config.h.in @@ -0,0 +1,17 @@ +#ifndef UNBOUND_DNSCRYPT_CONFIG_H +#define UNBOUND_DNSCRYPT_CONFIG_H + +/* + * Process this file (dnscrypt_config.h.in) with AC_CONFIG_FILES to generate + * dnscrypt_config.h. + * + * This file exists so that USE_DNSCRYPT can be used without including config.h. + */ + +#if @ENABLE_DNSCRYPT@ /* ENABLE_DNSCRYPT */ +# ifndef USE_DNSCRYPT +# define USE_DNSCRYPT 1 +# endif +#endif + +#endif /* UNBOUND_DNSCRYPT_CONFIG_H */ --- contrib/unbound/dnstap/dnstap.c.orig +++ contrib/unbound/dnstap/dnstap.c @@ -39,6 +39,10 @@ #include "config.h" #include #include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#include #include "sldns/sbuffer.h" #include "util/config_file.h" #include "util/net_help.h" @@ -118,10 +122,24 @@ } } +/* check that the socket file can be opened and exists, print error if not */ +static void +check_socket_file(const char* socket_path) +{ + struct stat statbuf; + memset(&statbuf, 0, sizeof(statbuf)); + if(stat(socket_path, &statbuf) < 0) { + log_warn("could not open dnstap-socket-path: %s, %s", + socket_path, strerror(errno)); + } +} + struct dt_env * dt_create(const char *socket_path, unsigned num_workers) { +#ifdef UNBOUND_DEBUG fstrm_res res; +#endif struct dt_env *env; struct fstrm_iothr_options *fopt; struct fstrm_unix_writer_options *fuwopt; @@ -132,6 +150,7 @@ socket_path); log_assert(socket_path != NULL); log_assert(num_workers > 0); + check_socket_file(socket_path); env = (struct dt_env *) calloc(1, sizeof(struct dt_env)); if (!env) @@ -138,7 +157,12 @@ return NULL; fwopt = fstrm_writer_options_init(); - res = fstrm_writer_options_add_content_type(fwopt, +#ifdef UNBOUND_DEBUG + res = +#else + (void) +#endif + fstrm_writer_options_add_content_type(fwopt, DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1); log_assert(res == fstrm_res_success); --- contrib/unbound/dnstap/dnstap.proto.orig +++ contrib/unbound/dnstap/dnstap.proto @@ -13,6 +13,7 @@ // with this file. If not, see: // // . +syntax = "proto2"; package dnstap; --- contrib/unbound/doc/Changelog.orig +++ contrib/unbound/doc/Changelog @@ -1,3 +1,2695 @@ +20 February 2020: Wouter + - Updated contrib/unbound_smf23.tar.gz with Solaris SMF service for + Unbound from Yuri Voinov. + +17 February 2020: Ralph + - Add respip to supported module-config options in unbound-checkconf. + +17 February 2020: George + - Remove unused variable. + +17 February 2020: Wouter + - contrib/drop2rpz: perl script that converts the Spamhaus DROP-List + in RPZ-Format, contributed by Andreas Schulze. + +14 February 2020: Wouter + - Fix spelling in unbound.conf.5.in. + - Stop unbound-checkconf from insisting that auth-zone and rpz + zonefiles have to exist. They can not exist, and download later. + +13 February 2020: Wouter + - tag for 1.10.0rc1 release. + +12 February 2020: Wouter + - Fix with libnettle make test with dsa disabled. + - Fix contrib/fastrpz.patch to apply cleanly. Fix for serve-stale + fixes, but it does not compile, conflicts with new rpz code. + - Fix to clean memory leak of respip_addr.lock when ip_tree deleted. + - Fix compile warning when threads disabled. + - updated version number to 1.10.0. + +10 February 2020: George + - Document 'ub_result.was_ratelimited' in libunbound. + - Fix use after free on log-identity after a reload; Fixes #163. + +6 February 2020: George + - Fix num_reply_states and num_detached_states counting with + serve_expired_callback. + - Cleaner code in mesh_serve_expired_lookup. + - Document in unbound.conf manpage that configuration clauses can be + repeated in the configuration file. + +6 February 2020: Wouter + - Fix num_reply_addr counting in mesh and tcp drop due to size + after serve_stale commit. + - Fix to create and destroy rpz_lock in auth_zones structure. + - Fix to lock zone before adding rpz qname trigger. + - Fix to lock and release once in mesh_serve_expired_lookup. + - Fix to put braces around empty if body when threading is disabled. + +5 February 2020: George + - Added serve-stale functionality as described in + draft-ietf-dnsop-serve-stale-10. `serve-expired-*` options can be used + to configure the behavior. + - Updated cachedb to honor `serve-expired-ttl`; Fixes #107. + - Renamed statistic `num.zero_ttl` to `num.expired` as expired replies + come with a configurable TTL value (`serve-expired-reply-ttl`). + - Fixed stats when replying with cached, cname-aliased records. + - Added missing default values for redis cachedb backend. + +3 February 2020: Ralph + - Add assertion to please static analyzer + +31 January 2020: Wouter + - Fix fclose on error in TLS session ticket code. + +30 January 2020: Ralph + - Fix memory leak in error condition remote.c + - Fix double free in error condition view.c + - Fix memory leak in do_auth_zone_transfer on success + - Merge RPZ support into master. Only QNAME and Response IP triggers are + supported. + - Stop working on socket when socket() call returns an error. + - Check malloc return values in TLS session ticket code + +30 January 2020: Wouter + - Fix subnet tests for disabled DSA algorithm by default. + - Update contrib/fastrpz.patch for clean diff with current code. + - Merge PR#151: Fixes for systemd units, by Maryse47, Edmonds + and Frzk. Updates the unbound.service systemd file and adds + a portable systemd service file. + - updated .gitignore for added contrib file. + - Add build rule for ipset to Makefile + - Add getentropy_freebsd.o to Makefile dependencies. + +29 January 2020: Ralph + - Merge PR#156 from Alexander Berkes; Added unbound-control + view_local_datas_remove command. + +29 January 2020: Wouter + - Fix #157: undefined reference to `htobe64'. + +28 January 2020: Ralph + - Merge PR#147; change rfc reference for reserved top level dns names. + +28 January 2020: Wouter + - iana portlist updated. + - Fix to silence the tls handshake errors for broken pipe and reset + by peer, unless verbosity is set to 2 or higher. + +27 January 2020: Ralph + - Merge PR#154; Allow use of libbsd functions with configure option + --with-libbsd. By Robert Edmonds and Steven Chamberlain. + - Merge PR#148; Add some TLS stats to unbound_munin_. By Fredrik Pettai. + +27 January 2020: Wouter + - Merge PR#155 from Robert Edmonds: contrib/libunbound.pc.in: Fixes + to Libs/Requires for crypto library dependencies. + - Fix #153: Disable validation for DSA algorithms. RFC 8624 + compliance. + +23 January 2020: Wouter + - Merge PR#150 from Frzk: Systemd unit without chroot. It add + contrib/unbound_nochroot.service.in, a systemd file for use with + chroot: "", see comments in the file, it uses systemd protections + instead. + +14 January 2020: Wouter + - Removed the dnscrypt_queries and dnscrypt_queries_chacha tests, + because dnscrypt-proxy (2.0.36) does not support the test setup + any more, and also the config file format does not seem to have + the appropriate keys to recreate that setup. + - Fix crash after reload where a stats lookup could reference old key + cache and neg cache structures. + - Fix for memory leak when edns subnet config options are read when + compiled without edns subnet support. + - Fix auth zone support for NSEC3 records without salt. + +10 January 2020: Wouter + - Fix the relationship between serve-expired and prefetch options, + patch from Saksham Manchanda from Secure64. + - Fix unreachable code in ssl set options code. + +8 January 2020: Ralph + - Fix #138: stop binding pidfile inside chroot dir in systemd service + file. + +8 January 2020: Wouter + - Fix 'make test' to work for --disable-sha1 configure option. + - Fix out-of-bounds null-byte write in sldns_bget_token_par while + parsing type WKS, reported by Luis Merino from X41 D-Sec. + - Updated sldns_bget_token_par fix for also space for the zero + delimiter after the character. And update for more spare space. + +6 January 2020: George + - Downgrade compat/getentropy_solaris.c to version 1.4 from OpenBSD. + The dl_iterate_phdr() function introduced in newer versions raises + compilation errors on solaris 10. + - Changes to compat/getentropy_solaris.c for, + ifdef stdint.h inclusion for older systems. + ifdef sha2.h inclusion for older systems. + +6 January 2020: Wouter + - Merge #135 from Florian Obser: Use passed in neg and key cache + if non-NULL. + - Fix #140: Document slave not downloading new zonefile upon update. + +16 December 2019: George + - Update mailing list URL. + +12 December 2019: Ralph + - Master is 1.9.7 in development. + - Fix typo to let serve-expired-ttl work with ub_ctx_set_option(), by + Florian Obser + +10 December 2019: Wouter + - Fix to make auth zone IXFR to fallback to AXFR if a single + response RR is received over TCP with the SOA in it. + +6 December 2019: Wouter + - Fix ipsecmod compile. + - Fix Makefile.in for ipset module compile, from Adi Prasaja. + - release-1.9.6 tag, which became the 1.9.6 release + +5 December 2019: Wouter + - unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1 + replacements for unbound-fuzzme.c that gets created after applying + the contrib/unbound-fuzzme.patch. They are contributed by + Eric Sesterhenn from X41 D-Sec. + - tag for 1.9.6rc1. + +4 December 2019: Wouter + - Fix lock type for memory purify log lock deletion. + - Fix testbound for alloccheck runs, memory purify and lock checks. + - update contrib/fastrpz.patch to apply more cleanly. + - Fix Make Test Fails when Configured With --enable-alloc-nonregional, + reported by X41 D-Sec. + +3 December 2019: Wouter + - Merge pull request #124 from rmetrich: Changed log lock + from 'quick' to 'basic' because this is an I/O lock. + - Fix text around serial arithmatic used for RRSIG times to refer + to correct RFC number. + - Fix Assert Causing DoS in synth_cname(), + reported by X41 D-Sec. + - Fix similar code in auth_zone synth cname to add the extra checks. + - Fix Assert Causing DoS in dname_pkt_copy(), + reported by X41 D-Sec. + - Fix OOB Read in sldns_wire2str_dname_scan(), + reported by X41 D-Sec. + - Fix Out of Bounds Write in sldns_str2wire_str_buf(), + reported by X41 D-Sec. + - Fix Out of Bounds Write in sldns_b64_pton(), + fixed by check in sldns_str2wire_int16_data_buf(), + reported by X41 D-Sec. + - Fix Insufficient Handling of Compressed Names in dname_pkt_copy(), + reported by X41 D-Sec. + - Fix Out of Bound Write Compressed Names in rdata_copy(), + reported by X41 D-Sec. + - Fix Hang in sldns_wire2str_pkt_scan(), + reported by X41 D-Sec. + This further lowers the max to 256. + - Fix snprintf() supports the n-specifier, + reported by X41 D-Sec. + - Fix Bad Indentation, in dnscrypt.c, + reported by X41 D-Sec. + - Fix Client NONCE Generation used for Server NONCE, + reported by X41 D-Sec. + - Fix compile error in dnscrypt. + - Fix _vfixed not Used, removed from sbuffer code, + reported by X41 D-Sec. + - Fix Hardcoded Constant, reported by X41 D-Sec. + - make depend + +2 December 2019: Wouter + - Merge pull request #122 from he32: In tcp_callback_writer(), + don't disable time-out when changing to read. + +22 November 2019: George + - Fix compiler warnings. + +22 November 2019: Wouter + - Fix dname loop maximum, reported by Eric Sesterhenn from X41 D-Sec. + - Add make distclean that removes everything configure produced, + and make maintainer-clean that removes bison and flex output. + +20 November 2019: Wouter + - Fix Out of Bounds Read in rrinternal_get_owner(), + reported by X41 D-Sec. + - Fix Race Condition in autr_tp_create(), + reported by X41 D-Sec. + - Fix Shared Memory World Writeable, + reported by X41 D-Sec. + - Adjust unbound-control to make stats_shm a read only operation. + - Fix Weak Entropy Used For Nettle, + reported by X41 D-Sec. + - Fix Randomness Error not Handled Properly, + reported by X41 D-Sec. + - Fix Out-of-Bounds Read in dname_valid(), + reported by X41 D-Sec. + - Fix Config Injection in create_unbound_ad_servers.sh, + reported by X41 D-Sec. + - Fix Local Memory Leak in cachedb_init(), + reported by X41 D-Sec. + - Fix Integer Underflow in Regional Allocator, + reported by X41 D-Sec. + - Upgrade compat/getentropy_linux.c to version 1.46 from OpenBSD. + - Synchronize compat/getentropy_win.c with version 1.5 from + OpenBSD, no changes but makes the file, comments, identical. + - Upgrade compat/getentropy_solaris.c to version 1.13 from OpenBSD. + - Upgrade compat/getentropy_osx.c to version 1.12 from OpenBSD. + - Changes to compat/getentropy files for, + no link to openssl if using nettle, and hence config.h for + HAVE_NETTLE variable. + compat definition of MAP_ANON, for older systems. + ifdef stdint.h inclusion for older systems. + ifdef sha2.h inclusion for older systems. + - Fixed Compat Code Diverging from Upstream, reported by X41 D-Sec. + - Fix compile with --enable-alloc-checks, reported by X41 D-Sec. + - Fix Terminating Quotes not Written, reported by X41 D-Sec. + - Fix Useless memset() in validator, reported by X41 D-Sec. + - Fix Unrequired Checks, reported by X41 D-Sec. + - Fix Enum Name not Used, reported by X41 D-Sec. + - Fix NULL Pointer Dereference via Control Port, + reported by X41 D-Sec. + - Fix Bad Randomness in Seed, reported by X41 D-Sec. + - Fix python examples/calc.py for eval, reported by X41 D-Sec. + - Fix comments for doxygen in dns64. + +19 November 2019: Wouter + - Fix CVE-2019-18934, shell execution in ipsecmod. + - 1.9.5 is 1.9.4 with bugfix, trunk is 1.9.6 in development. + - Fix authzone printout buffer length check. + - Fixes to please lint checks. + - Fix Integer Overflow in Regional Allocator, + reported by X41 D-Sec. + - Fix Unchecked NULL Pointer in dns64_inform_super() + and ipsecmod_new(), reported by X41 D-Sec. + - Fix Out-of-bounds Read in rr_comment_dnskey(), + reported by X41 D-Sec. + - Fix Integer Overflows in Size Calculations, + reported by X41 D-Sec. + - Fix Integer Overflow to Buffer Overflow in + sldns_str2wire_dname_buf_origin(), reported by X41 D-Sec. + - Fix Out of Bounds Read in sldns_str2wire_dname(), + reported by X41 D-Sec. + - Fix Out of Bounds Write in sldns_bget_token_par(), + reported by X41 D-Sec. + +18 November 2019: Wouter + - In unbound-host use separate variable for get_option to please + code checkers. + - update to bison output of 3.4.1 in code repository. + - Provide a prototype for compat malloc to remove compile warning. + - Portable grep usage for reuseport configure test. + - Check return type of HMAC_Init_ex for openssl 0.9.8. + - gitignore .source tempfile used for compatible make. + +13 November 2019: Wouter + - iana portlist updated. + - contrib/fastrpz.patch updated to apply for current code. + - fixes for splint cleanliness, long vs int in SSL set_mode. + +11 November 2019: Wouter + - Fix #109: check number of arguments for stdin-pipes in + unbound-control and fail if too many arguments. + - Merge #102 from jrtc27: Add getentropy emulation for FreeBSD. + +24 October 2019: Wouter + - Fix #99: Memory leak in ub_ctx (event_base will never be freed). + +23 October 2019: George + - Add new configure option `--enable-fully-static` to enable full static + build if requested; in relation to #91. + +23 October 2019: Wouter + - Merge #97: manpage: Add missing word on unbound.conf, + from Erethon. + +22 October 2019: Wouter + - drop-tld.diff: adds option drop-tld: yesno that drops 2 label + queries, to stop random floods. Apply with + patch -p1 < contrib/drop-tld.diff and compile. + From Saksham Manchanda (Secure64). Please note that we think this + will drop DNSKEY and DS lookups for tlds and hence break DNSSEC + lookups for downstream clients. + +7 October 2019: Wouter + - Add doxygen comments to unbound-anchor source address code, in #86. + +3 October 2019: Wouter + - Merge #90 from vcunat: fix build with nettle-3.5. + - Merge 1.9.4 release with fix for vulnerability CVE-2019-16866. + - Continue with development of 1.9.5. + - Merge #86 from psquarejho: Added -b source address option to + smallapp/unbound-anchor.c, from Lukas Wunner. + +26 September 2019: Wouter + - Merge #87 from hardfalcon: Fix contrib/unbound.service.in, + Drop CAP_KILL, use + prefix for ExecReload= instead. + +25 September 2019: Wouter + - The unbound.conf includes are sorted ascending, for include + statements with a '*' from glob. + +23 September 2019: Wouter + - Merge #85 for #84 from sam-lunt: Add kill capability to systemd + service file to fix that systemctl reload fails. + +20 September 2019: Wouter + - Merge #82 from hardfalcon: Downgrade CAP_NET_ADMIN to CAP_NET_RAW + in unbound.service. + - Merge #81 from Maryse47: Consistently use /dev/urandom instead + of /dev/random in scripts and docs. + - Merge #83 from Maryse47: contrib/unbound.service.in: do not fork + into the background. + +19 September 2019: Wouter + - Fix #78: Memory leak in outside_network.c. + - Merge pull request #76 from Maryse47: Improvements and fixes for + systemd unbound.service. + - oss-fuzz badge on README.md. + - Fix fix for #78 to also free service callback struct. + - Fix for oss-fuzz build warning. + - Fix wrong response ttl for prepended short CNAME ttls, this would + create a wrong zero_ttl response count with serve-expired enabled. + - Merge #80 from stasic: Improve wording in man page. + +11 September 2019: Wouter + - Use explicit bzero for wiping clear buffer of hash in cachedb, + reported by Eric Sesterhenn from X41 D-Sec. + +9 September 2019: Wouter + - Fix #72: configure --with-syslog-facility=LOCAL0-7 with default + LOG_DAEMON (as before) can set the syslog facility that the server + uses to log messages. + +4 September 2019: Wouter + - Fix #71: fix openssl error squelch commit compilation error. + +3 September 2019: Wouter + - squelch DNS over TLS errors 'ssl handshake failed crypto error' + on low verbosity, they show on verbosity 3 (query details), because + there is a high volume and the operator cannot do anything for the + remote failure. Specifically filters the high volume errors. + +2 September 2019: Wouter + - ipset module #28: log that an address is added, when verbosity high. + - ipset: refactor long routine into three smaller ones. + - updated Makefile dependencies. + +23 August 2019: Wouter + - Fix contrib/fastrpz.patch asprintf return value checks. + +22 August 2019: Wouter + - Fix that pkg-config is setup before --enable-systemd needs it. + - 1.9.3rc2 release candidate tag. And this became the 1.9.3 release. + Master is 1.9.4 in development. + +21 August 2019: Wouter + - Fix log_dns_msg to log irrespective of minimal responses config. + +19 August 2019: Ralph + - Document limitation of pidfile removal outside of chroot directory. + +16 August 2019: Wouter + - Fix unittest valgrind false positive uninitialised value report, + where if gcc 9.1.1 uses -O2 (but not -O1) then valgrind 3.15.0 + issues an uninitialised value for the token buffer at the str2wire.c + rrinternal_get_owner() strcmp with the '@' value. Rewritten to use + straight character comparisons removes the false positive. Also + valgrinds --expensive-definedness-checks=yes can stop this false + positive. + - Please doxygen's parser for "@" occurrence in doxygen comment. + - Fixup contrib/fastrpz.patch + - Remove warning about unknown cast-function-type warning pragma. + +15 August 2019: Wouter + - iana portlist updated. + - Fix autotrust temp file uniqueness windows compile. + - avoid warning about upcast on 32bit systems for autotrust. + - escape commandline contents for -V. + - Fix character buffer size in ub_ctx_hosts. + - 1.9.3rc1 release candidate tag. + - Option -V prints if TCP fastopen is available. + +14 August 2019: George + - Fix #59, when compiled with systemd support check that we can properly + communicate with systemd through the `NOTIFY_SOCKET`. + +14 August 2019: Wouter + - Generate configlexer with newer flex. + - Fix warning for unused variable for compilation without systemd. + +12 August 2019: George + - Introduce `-V` option to print the version number and build options. + Previously reported build options like linked libs and linked modules + are now moved from `-h` to `-V` as well for consistency. + - PACKAGE_BUGREPORT now also includes link to GitHub issues. + +1 August 2019: Wouter + - For #52 #53, second context does not close logfile override. + - Fix #52 #53, fix for example fail program. + - Fix to return after failed auth zone http chunk write. + - Fix to remove unused test for task_probe existance. + - Fix to timeval_add for remaining second in microseconds. + - Check repinfo in worker_handle_request, if null, drop it. + +29 July 2019: Wouter + - Add verbose log message when auth zone file is written, at level 4. + - Add hex print of trust anchor pointer to trust anchor file temp + name to make it unique, for libunbound created multiple contexts. + +23 July 2019: Wouter + - Fix question section mismatch in local zone redirect. + +19 July 2019: Wouter + - Fix #49: Set no renegotiation on the SSL context to stop client + session renegotiation. + +12 July 2019: Wouter + - Fix #48: Unbound returns additional records on NODATA response, + if minimal-responses is enabled, also the additional for negative + responses is removed. + +9 July 2019: Ralph + - Fix in respip addrtree selection. Absence of addr_tree_init_parents() + call made it impossible to go up the tree when the matching netmask is + too specific. + +5 July 2019: Ralph + - Fix for possible assertion failure when answering respip CNAME from + cache. + +25 June 2019: Wouter + - For #45, check that 127.0.0.1 and ::1 are not used in unbound.conf + when do-not-query-localhost is turned on, or at default on, + unbound-checkconf prints a warning if it is found in forward-addr or + stub-addr statements. + +24 June 2019: Wouter + - Fix memleak in unit test, reported from the clang 8.0 static analyzer. + +18 June 2019: Wouter + - PR #28: IPSet module, by Kevin Chou. Created a module to support + the ipset that could add the domain's ip to a list easily. + Needs libmnl, and --enable-ipset and config it, doc/README.ipset.md. + - Fix to omit RRSIGs from addition to the ipset. + - Fix to make unbound-control with ipset, remove unused variable, + use unsigned type because of comparison, and assign null instead + of compare with it. Remade lex and yacc output. + - make depend + - Added documentation to the ipset files (for doxygen output). + - Merge PR #6: Python module: support multiple instances + - Merge PR #5: Python module: define constant MODULE_RESTART_NEXT + - Merge PR #4: Python module: assign something useful to the + per-query data store 'qdata' + - Fix python dict reference and double free in config. + +17 June 2019: Wouter + - Master contains version 1.9.3 in development. + - Fix #39: In libunbound, leftover logfile is close()d unpredictably. + - Fix for #24: Fix abort due to scan of auth zone masters using old + address from previous scan. + +12 June 2019: Wouter + - Fix another spoolbuf storage code point, in prefetch. + - 1.9.2rc3 release candidate tag. Which became the 1.9.2 release + on 17 June 2019. + +11 June 2019: Wouter + - Fix that fixes the Fix that spoolbuf is not used to store tcp + pipelined response between mesh send and callback end, this fixes + error cases that did not use the correct spoolbuf. + - 1.9.2rc2 release candidate tag. + +6 June 2019: Wouter + - 1.9.2rc1 release candidate tag. + +4 June 2019: Wouter + - iana portlist updated. + +29 May 2019: Wouter + - Fix to guard _OPENBSD_SOURCE from redefinition. + +28 May 2019: Wouter + - Fix to define _OPENBSD_SOURCE to get reallocarray on NetBSD. + - gitignore config.h.in~. + +27 May 2019: Wouter + - Fix double file close in tcp pipelined response code. + +24 May 2019: Wouter + - Fix that spoolbuf is not used to store tcp pipelined response + between mesh send and callback end. + +20 May 2019: Wouter + - Note that so-reuseport at extreme load is better turned off, + otherwise queries are not distributed evenly, on Linux 4.4.x. + +16 May 2019: Wouter + - Fix #31: swig 4.0 and python module. + +13 May 2019: Wouter + - Squelch log messages from tcp send about connection reset by peer. + They can be enabled with verbosity at higher values for diagnosing + network connectivity issues. + - Attempt to fix malformed tcp response. + +9 May 2019: Wouter + - Revert fix for oss-fuzz, error is in that build script that + unconditionally includes .o files detected by configure, also + when the machine architecture uses different LIBOBJS files. + +8 May 2019: Wouter + - Attempt to fix build failure in oss-fuzz because of reallocarray. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14648. + Does not omit compile flags from commandline. + +7 May 2019: Wouter + - Fix edns-subnet locks, in error cases the lock was not unlocked. + - Fix doxygen output error on readme markdown vignettes. + +6 May 2019: Wouter + - Fix #29: Solaris 11.3 and missing symbols be64toh, htobe64. + - Fix #30: AddressSanitizer finding in lookup3.c. This sets the + hash function to use a slower but better auditable code that does + not read beyond array boundaries. This makes code better security + checkable, and is better for security. It is fixed to be slower, + but not read outside of the array. + +2 May 2019: Wouter + - contrib/fastrpz.patch updated for code changes, and with git diff. + - Fix .gitignore, add pythonmod and dnstap generated files. + And unit test generated files, and generated doc files. + +1 May 2019: Wouter + - Update makedist for git. + - Nicer travis output for clang analysis. + - PR #16: XoT support, AXFR over TLS, turn it on with + master: # in unbound.conf. This uses TLS to + download the AXFR (or IXFR). + +25 April 2019: Wouter + - Fix wrong query name in local zone redirect answers with a CNAME, + the copy of the local alias is in unpacked form. + +18 April 2019: Ralph + - Scrub RRs from answer section when reusing NXDOMAIN message for + subdomain answers. + - For harden-below-nxdomain: do not consider a name to be non-exitent + when message contains a CNAME record. + +18 April 2019: Wouter + - travis build file. + +16 April 2019: Wouter + - Better braces in if statement in TCP fastopen code. + - iana portlist updated. + +15 April 2019: Wouter + - Fix tls write event for read state change to re-call SSL_write and + not resume the TLS handshake. + +11 April 2019: George + - Update python documentation for init_standard(). + - Typos. + +11 April 2019: Wouter + - Fix that auth zone uses correct network type for sockets for + SOA serial probes. This fixes that probes fail because earlier + probe addresses are unreachable. + - Fix that auth zone fails over to next master for timeout in tcp. + - Squelch SSL read and write connection reset by peer and broken pipe + messages. Verbosity 2 and higher enables them. + +8 April 2019: Wouter + - Fix to use event_assign with libevent for thread-safety. + - verbose information about auth zone lookup process, also lookup + start, timeout and fail. + - Fix #17: Add python module example from Jan Janak, that is a + plugin for the Unbound DNS resolver to resolve DNS records in + multicast DNS [RFC 6762] via Avahi. The plugin communicates + with Avahi via DBus. The comment section at the beginning of + the file contains detailed documentation. + - Fix to wipe ssl ticket keys from memory with explicit_bzero, + if available. + +5 April 2019: Wouter + - Fix to reinit event structure for accepted TCP (and TLS) sockets. + +4 April 2019: Wouter + - Fix spelling error in log output for event method. + +3 April 2019: Wouter + - Move goto label in answer_from_cache to the end of the function + where it is more visible. + - Fix auth-zone NSEC3 response for wildcard nodata answers, + include the closest encloser in the answer. + +2 April 2019: Wouter + - Fix auth-zone NSEC3 response for empty nonterminals with exact + match nsec3 records. + - Fix for out of bounds integers, thanks to OSTIF audit. It is in + allocation debug code. + - Fix for auth zone nsec3 ent fix for wildcard nodata. + +25 March 2019: Wouter + - Fix that tls-session-ticket-keys: "" on its own in unbound.conf + disables the tls session ticker key calls into the OpenSSL API. + - Fix crash if tls-servic-pem not filled in when necessary. + +21 March 2019: Wouter + - Fix #4240: Fix whitespace cleanup in example.conf. + +19 March 2019: Wouter + - add type CAA to libpyunbound (accessing libunbound from python). + +18 March 2019: Wouter + - Add log message, at verbosity 4, that says the query is encrypted + with TLS, if that is enabled for the query. + - Fix #4239: set NOTIMPL when deny-any is enabled, for RFC8482. + +7 March 2019: Wouter + - Fix for #4233: guard use of NDEBUG, so that it can be passed in + CFLAGS into configure. + +5 March 2019: Wouter + - Tag release 1.9.1rc1. Which became 1.9.1 on 12 March 2019. Trunk + has 1.9.2 in development. + +1 March 2019: Wouter + - output forwarder log in ssl_req_order test. + +28 February 2019: Wouter + - Remove memory leak on pythonmod python2 script file init. + - Remove swig gcc8 python function cast warnings, they are ignored. + - Print correct module that failed when module-config is wrong. + +27 February 2019: Wouter + - Fix #4229: Unbound man pages lack information, about access-control + order and local zone tags, and elements in views. + - Fix #14: contrib/unbound.init: Fix wrong comparison judgment + before copying. + - Fix for python module on Windows, fix fopen. + +25 February 2019: Wouter + - Fix #4227: pair event del and add for libevent for tcp_req_info. + +21 February 2019: Wouter + - Fix the error for unknown module in module-config is understandable, + and explains it was not compiled in and where to see the list. + - In example.conf explain where to put cachedb module in module-config. + - In man page and example config explain that most modules have to + be listed at the start of module-config. + +20 February 2019: Wouter + - Fix pythonmod include and sockaddr_un ifdefs for compile on + Windows, and for libunbound. + +18 February 2019: Wouter + - Print query name with ip_ratelimit exceeded log lines. + - Spaces instead of tabs in that log message. + - Print query name and IP address when domain rate limit exceeded. + +14 February 2019: Wouter + - Fix capsforid canonical sort qsort callback. + +11 February 2019: Wouter + - Note default for module-config in man page. + - Fix recursion lame test for qname minimisation asked queries, + that were not present in the set of prepared answers. + - Fix #13: Remove left-over requirements on OpenSSL >= 1.1.0 for + cert name matching, from man page. + - make depend, with newer gcc, nicer layout. + +7 February 2019: Wouter + - Fix #4206: OpenSSL 1.0.2 hostname verification for FreeBSD 11.2. + - Fix that qname minimisation does not skip a label when missing + nameserver targets need to be fetched. + - Fix #4225: clients seem to erroneously receive no answer with + DNS-over-TLS and qname-minimisation. + +4 February 2019: Wouter + - Fix that log-replies prints the correct name for local-alias + names, for names that have a CNAME in local-data configuration. + It logs the original query name, not the target of the CNAME. + - Add local-zone type inform_redirect, which logs like type inform, + and redirects like type redirect. + - Perform canonical sort for 0x20 capsforid compare of replies, + this sorts rrsets in the authority and additional section before + comparison, so that out of order rrsets do not cause failure. + +31 January 2019: Wouter + - Set ub_ctx_set_tls call signature in ltrace config file for + libunbound in contrib/libunbound.so.conf. + - improve documentation for tls-service-key and forward-first. + - #10: fixed pkg-config operations, PKG_PROG_PKG_CONFIG moved out of + conditional section, fixes systemd builds, from Enrico Scholz. + - #9: For openssl 1.0.2 use the CRYPTO_THREADID locking callbacks, + still supports the set_id_callback previous API. And for 1.1.0 + no locking callbacks are needed. + - #8: Fix OpenSSL without ENGINE support compilation. + - Wipe TLS session key data from memory on exit. + +30 January 2019: Ralph + - Fix case in which query timeout can result in marking delegation + as edns_lame_known. + +29 January 2019: Wouter + - Fix spelling of tls-ciphers in example.conf.in. + - Fix #4224: auth_xfr_notify.rpl test broken due to typo + - Fix locking for libunbound context setup with broken port config. + +28 January 2019: Wouter + - ub_ctx_set_tls call for libunbound that enables DoT for the machines + set with ub_ctx_set_fwd. Patch from Florian Obser. + - Set build system for added call in the libunbound API. + - List example config for root zone copy locally hosted with auth-zone + as suggested from draft-ietf-dnsop-7706-bis-02. But with updated + B root address. + - set version to 1.9.0 for release. And this was released with the + spelling for tls-ciphers fix as 1.9.0 on Feb 5. Trunk has 1.9.1 in + development. + +25 January 2019: Wouter + - Fix that tcp for auth zone and outgoing does not remove and + then gets the ssl read again applied to the deleted commpoint. + - updated contrib/fastrpz.patch to cleanly diff. + - no lock when threads disabled in tcp request buffer count. + - remove compile warnings from libnettle compile. + - output of newer lex 2.6.1 and bison 3.0.5. + +24 January 2019: Wouter + - Newer aclocal and libtoolize used for generating configure scripts, + aclocal 1.16.1 and libtoolize 2.4.6. + - Fix unit test for python 3.7 new keyword 'async'. + - clang analysis fixes, assert arc4random buffer in init, + no check for already checked delegation pointer in iterator, + in testcode check for NULL packet matches, in perf do not copy + from NULL start list when growing capacity. Adjust host and file + only when present in test header read to please checker. In + testcode for unknown macro operand give zero result. Initialise the + passed argv array in test code. In test code add EDNS data + segment copy only when nonempty. + - Patch from Florian Obser fixes some compiler warnings: + include mini_event.h to have a prototype for mini_ev_cmp + include edns.h to have a prototype for apply_edns_options + sldns_wire2str_edns_keepalive_print is only called in the wire2str, + module declare it static to get rid of compiler warning: + no previous prototype for function + infra_find_ip_ratedata() is only called in the infra module, + declare it static to get rid of compiler warning: + no previous prototype for function + do not shadow local variable buf in authzone + auth_chunks_delete and az_nsec3_findnode are only called in the + authzone module, declare them static to get rid of compiler warning: + no previous prototype for function... + copy_rrset() is only called in the respip module, declare it + static to get rid of compiler warning: + no previous prototype for function 'copy_rrset' + no need for another variable "r"; gets rid of compiler warning: + declaration shadows a local variable in libunbound.c + no need for another variable "ns"; gets rid of compiler warning: + declaration shadows a local variable in iterator.c + - Moved includes and make depend. + +23 January 2019: Wouter + - Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites + options for unbound.conf. + - Fixes for the patch, and man page entry. + - Fix configure to detect SSL_CTX_set_ciphersuites, for better + library compatibility when compiling. + - Patch for TLS session resumption from Manabu Sonoda, + enable with tls-session-ticket-keys in unbound.conf. + - Fixes for patch (includes, declarations, warnings). Free at end + and keep config options in order read from file to keep the first + one as the first one. + - Fix for IXFR fallback to reset counter when IXFR does not timeout. + +22 January 2019: Wouter + - Fix space calculation for tcp req buffer size. + - Doc for stream-wait-size and unit test. + - unbound-control stats has mem.streamwait that counts TCP and TLS + waiting result buffers. + - Fix for #4219: secondaries not updated after serial change, unbound + falls back to AXFR after IXFR gives several timeout failures. + - Fix that auth zone after IXFR fallback tries the same master. + +21 January 2019: Wouter + - Fix tcp idle timeout test, for difference in the tcp reply code. + - Unit test for tcp request reorder and timeouts. + - Unit tests for ssl out of order processing. + - Fix that multiple dns fragments can be carried in one TLS frame. + - Add stream-wait-size: 4m config option to limit the maximum + memory used by waiting tcp and tls stream replies. This avoids + a denial of service where these replies use up all of the memory. + +17 January 2019: Wouter + - For caps-for-id fallback, use the whitelist to avoid timeout + starting a fallback sequence for it. + - increase mesh max activation count for capsforid long fetches. + +16 January 2019: Ralph + - Get ready for the DNS flag day: remove EDNS lame procedure, do not + re-query without EDNS after timeout. + +15 January 2019: Wouter + - In the out of order processing, reset byte count for (potential) + partial read. + - Review fixes in out of order processing. + +14 January 2019: Wouter + - streamtcp option -a send queries consecutively and prints answers + as they arrive. + - Fix for out of order processing administration quit cleanup. + - unit test for tcp out of order processing. + +11 January 2019: Wouter + - Initial commit for out-of-order processing for TCP and TLS. + +9 January 2019: Wouter + - Log query name for looping module errors. + +8 January 2019: Wouter + - Fix syntax in comment of local alias processing. + - Fix NSEC3 record that is returned in wildcard replies from + auth-zone zones with NSEC3 and wildcards. + +7 January 2019: Wouter + - On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN, + and server tcp fastopen is enabled at compile time. + - Document interaction between the tls-upstream option in the server + section and forward-tls-upstream option in the forward-zone sections. + - Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews, + the patch adds a program used for fuzzing. + +12 December 2018: Wouter + - Fix for crash in dns64 module if response is null. + +10 December 2018: Wouter + - Fix config parser memory leaks. + - ip-ratelimit-factor of 1 allows all traffic through, instead of the + previous blocking everything. + - Fix for FreeBSD port make with dnscrypt and dnstap enabled. + - Fix #4206: support openssl 1.0.2 for TLS hostname verification, + alongside the 1.1.0 and later support that is already there. + - Fixup openssl 1.0.2 compile + +6 December 2018: Wouter + - Fix dns64 allocation in wrong region for returned internal queries. + +3 December 2018: Wouter + - Fix icon, no ragged edges and nicer resolutions available, for eg. + Win 7 and Windows 10 display. + - cache-max-ttl also defines upperbound of initial TTL in response. + +30 November 2018: Wouter + - Patch for typo in unbound.conf man page. + - log-tag-queryreply: yes in unbound.conf tags the log-queries and + log-replies in the log file for easier log filter maintenance. + +29 November 2018: Wouter + - iana portlist updated. + - Fix chroot auth-zone fix to remove chroot prefix. + - tag for 1.8.2rc1, which became 1.8.2 on 4 dec 2018, with icon + updated. Trunk contains 1.8.3 in development. + Which became 1.8.3 on 11 december with only the dns64 fix of 6 dec. + Trunk then became 1.8.4 in development. + - Fix that unbound-checkconf does not complains if the config file + is not placed inside the chroot. + - Refuse to start with no ports. + - Remove clang analysis warnings. + +28 November 2018: Wouter + - Fix leak in chroot fix for auth-zone. + - Fix clang analysis for outside directory build test. + +27 November 2018: Wouter + - Fix DNS64 to not store intermediate results in cache, this avoids + other threads from picking up the wrong data. The module restores + the previous no_cache_store setting when the the module is finished. + - Fix #4208: 'stub-no-cache' and 'forward-no-cache' not work. + - New and better fix for Fix #4193: Fix that prefetch failure does + not overwrite valid cache entry with SERVFAIL. + - auth-zone give SERVFAIL when expired, fallback activates when + expired, and this is documented in the man page. + - stat count SERVFAIL downstream auth-zone queries for expired zones. + - Put new logos into windows installer. + - Fix windows compile for new rrset roundrobin fix. + - Update contrib fastrpz patch for latest release. + +26 November 2018: Wouter + - Fix to not set GLOB_NOSORT so the unbound.conf include: files are + sorted and in a predictable order. + - Fix #4193: Fix that prefetch failure does not overwrite valid cache + entry with SERVFAIL. + - Add unbound-control view_local_datas command, like local_datas. + - Fix that unbound-control can send file for view_local_datas. + +22 November 2018: Wouter + - With ./configure --with-pyunbound --with-pythonmodule + PYTHON_VERSION=3.6 or with 2.7 unbound can compile and unit tests + succeed for the python module. + - pythonmod logs the python error and traceback on failure. + - ignore debug python module for test in doxygen output. + - review fixes for python module. + - Fix #4209: Crash in libunbound when called from getdns. + - auth zone zonefiles can be in a chroot, the chroot directory + components are removed before use. + - Fix that empty zonefile means the zonefile is not set and not used. + - make depend. + +21 November 2018: Wouter + - Scrub NS records from NODATA responses as well. + +20 November 2018: Wouter + - Scrub NS records from NXDOMAIN responses to stop fragmentation + poisoning of the cache. + - Add patch from Jan Vcelak for pythonmod, + add sockaddr_storage getters, add support for query callbacks, + allow raw address access via comm_reply and update API documentation. + - Removed compile warnings in pythonmod sockaddr routines. + +19 November 2018: Wouter + - Support SO_REUSEPORT_LB in FreeBSD 12 with the so-reuseport: yes + option in unbound.conf. + +6 November 2018: Ralph + - Bugfix min-client-subnet-ipv6 + +25 October 2018: Ralph + - Add min-client-subnet-ipv6 and min-client-subnet-ipv4 options. + +25 October 2018: Wouter + - Fix #4191: NXDOMAIN vs SERVFAIL during dns64 PTR query. + - Fix #4190: Please create a "ANY" deny option, adds the option + deny-any: yes in unbound.conf. This responds with an empty message + to queries of type ANY. + - Fix #4141: More randomness to rrset-roundrobin. + - Fix #4132: Openness/closeness of RANGE intervals in rpl files. + - Fix #4126: RTT_band too low on VSAT links with 600+ms latency, + adds the option unknown-server-time-limit to unbound.conf that + can be increased to avoid the problem. + - remade makefile dependencies. + - Fix #4152: Logs shows wrong time when using log-time-ascii: yes. + +24 October 2018: Ralph + - Add markdel function to ECS slabhash. + - Limit ECS scope returned to client to the scope used for caching. + - Make lint like previous #4154 fix. + +22 October 2018: Wouter + - Fix #4192: unbound-control-setup generates keys not readable by + group. + - check that the dnstap socket file can be opened and exists, print + error if not. + - Fix #4154: make ECS_MAX_TREESIZE configurable, with + the max-ecs-tree-size-ipv4 and max-ecs-tree-size-ipv6 options. + +22 October 2018: Ralph + - Change fast-server-num default to 3. + +8 October 2018: Ralph + - Add fast-server-permil and fast-server-num options. + - Deprecate low-rtt and low-rtt-permil options. + +8 October 2018: Wouter + - Squelch log of failed to tcp initiate after TCP Fastopen failure. + +5 October 2018: Wouter + - Squelch EADDRNOTAVAIL errors when the interface goes away, + this omits 'can't assign requested address' errors unless + verbosity is set to a high value. + - Set default for so-reuseport to no for FreeBSD. It is enabled + by default for Linux and DragonFlyBSD. The setting can + be configured in unbound.conf to override the default. + - iana port update. + +2 October 2018: Wouter + - updated contrib/fastrpz.patch to apply for this version + - dnscrypt.c removed sizeof to get array bounds. + - Fix testlock code to set noreturn on error routine. + - Remove unused variable from contrib fastrpz/rpz.c and + remove unused diagnostic pragmas that themselves generate warnings + - clang analyze test is used only when assertions are enabled. + +1 October 2018: Wouter + - tag for release 1.8.1rc1. Became release 1.8.1 on 8 oct, with + fastrpz.patch fix included. Trunk has 1.8.2 in development. + +27 September 2018: Wouter + - Fix #4188: IPv6 forwarders without ipv6 result in SERVFAIL, fixes + qname minimisation with a forwarder when connectivity has issues + from rejecting responses. + +25 September 2018: Wouter + - Perform TLS SNI indication of the host that is being contacted + for DNS over TLS service. It sets the configured tls auth name. + This is useful for hosts that apart from the DNS over TLS services + also provide other (web) services. + - Fix #4149: Add SSL cleanup for tcp timeout. + +17 September 2018: Wouter + - Fix compile on Mac for unbound, provide explicit_bzero when libc + does not have it. + - Fix unbound for openssl in FIPS mode, it uses the digests with + the EVP call contexts. + - Fix that with harden-below-nxdomain and qname minisation enabled + some iterator states for nonresponsive domains can get into a + state where they waited for an empty list. + - Stop UDP to TCP failover after timeouts that causes the ping count + to be reset by the TCP time measurement (that exists for TLS), + because that causes the UDP part to not be measured as timeout. + - Fix #4156: Fix systemd service manager state change notification. + +13 September 2018: Wouter + - Fix seed for random backup code to use explicit zero when wiped. + - exit log routine is annotated as noreturn function. + - free memory leaks in config strlist and str2list insert functions. + - do not move unused argv variable after getopt. + - Remove unused if clause in testcode. + - in testcode, free async ids, initialise array, and check for null + pointer during test of the test. And use exit for return to note + irregular program stop. + - Free memory leak in config strlist append. + - make sure nsec3 comparison salt is initialized. + - unit test has clang analysis. + - remove unused variable assignment from iterator scrub routine. + - check for null in delegation point during iterator refetch + in forward zone. + - neater pointer cast in libunbound context quit routine. + - initialize statistics totals for printout. + - in authzone check that node exists before adding rrset. + - in unbound-anchor, use readwrite memory BIO. + - assertion in autotrust that packed rrset is formed correctly. + - Fix memory leak when message parse fails partway through copy. + - remove unused udpsize assignment in message encode. + - nicer bio free code in unbound-anchor. + - annotate exit functions with noreturn in unbound-control. + +11 September 2018: Wouter + - Fixed unused return value warnings in contrib/fastrpz.patch for + asprintf. + - Fix to squelch respip warning in unit test, it is printed at + higher verbosity settings. + - Fix spelling errors. + - Fix initialisation in remote.c + +10 September 2018: Wouter + - 1.8.1 in svn trunk. (changes from 4,5,.. sep apply). + - iana port update. + +5 September 2018: Wouter + - Fix spelling error in header, from getdns commit by Andreas Gelmini. + +4 September 2018: Ralph + - More explicitly mention the type of ratelimit when applying + ip-ratelimit. + +4 September 2018: Wouter + - Tag for 1.8.0rc1 release, became 1.8.0 release on 10 Sep 2018. + +31 August 2018: Wouter + - Disable minimal-responses in subnet unit tests. + +30 August 2018: Wouter + - Fix that a local-zone with a local-zone-type that is transparent + in a view with view-first, makes queries check for answers from the + local-zones defined outside of views. + +28 August 2018: Ralph + - Disable minimal-responses in ipsecmod unit tests. + - Added serve-expired-ttl and serve-expired-ttl-reset options. + +27 August 2018: Wouter + - Set defaults to yes for a number of options to increase speed and + resilience of the server. The so-reuseport, harden-below-nxdomain, + and minimal-responses options are enabled by default. They used + to be disabled by default, waiting to make sure they worked. They + are enabled by default now, and can be disabled explicitly by + setting them to "no" in the unbound.conf config file. The reuseport + and minimal options increases speed of the server, and should be + otherwise harmless. The harden-below-nxdomain option works well + together with the recently default enabled qname minimisation, this + causes more fetches to use information from the cache. + - next release is called 1.8.0. + - Fix lintflags for lint on FreeBSD. + +22 August 2018: George + - #4140: Expose repinfo (comm_reply) to the inplace_callbacks. This + gives access to reply information for the client's communication + point when the callback is called before the mesh state (modules). + Changes to C and Python's inplace_callback signatures were also + necessary. + +21 August 2018: Wouter + - log-local-actions: yes option for unbound.conf that logs all the + local zone actions, a patch from Saksham Manchanda (Secure64). + - #4146: num.query.subnet and num.query.subnet_cache counters. + - Fix only misc failure from log-servfail when val-log-level is not + enabled. + +17 August 2018: Ralph + - Fix classification for QTYPE=CNAME queries when QNAME minimisation is + enabled. + +17 August 2018: Wouter + - Set libunbound to increase current, because the libunbound change + to the event callback function signature. That needs programs, + that use it, to recompile against the new header definition. + - print servfail info to log as error. + - added more servfail printout statements, to the iterator. + - log-servfail: yes prints log lines that say why queries are + returning SERVFAIL to clients. + +16 August 2018: Wouter + - Fix warning on compile without threads. + - Fix contrib/fastrpz.patch. + +15 August 2018: Wouter + - Fix segfault in auth-zone read and reorder of RRSIGs. + +14 August 2018: Wouter + - Fix that printout of error for cycle targets is a verbosity 4 + printout and does not wrongly print it is a memory error. + - Upgraded crosscompile script to include libunbound DLL in the + zipfile. + +10 August 2018: Wouter + - Fix #4144: dns64 module caches wrong (negative) information. + +9 August 2018: Wouter + - unbound-checkconf checks if modules exist and prints if they are + not compiled in the name of the wrong module. + - document --enable-subnet in doc/README. + - Patch for stub-no-cache and forward-no-cache options that disable + caching for the contents of that stub or forward, for when you + want immediate changes visible, from Bjoern A. Zeeb. + +7 August 2018: Ralph + - Make capsforid fallback QNAME minimisation aware. + +7 August 2018: Wouter + - Fix #4142: unbound.service.in: improvements and fixes. + Add unit dependency ordering (based on systemd-resolved). + Add 'CAP_SYS_RESOURCE' to 'CapabilityBoundingSet' (fixes warnings + about missing privileges during startup). Add 'AF_INET6' to + 'RestrictAddressFamilies' (without it IPV6 can't work). From + Guido Shanahan. + - Patch to implement tcp-connection-limit from Jim Hague (Sinodun). + This limits the number of simultaneous TCP client connections + from a nominated netblock. + - make depend, yacc, lex, doc, headers. And log the limit exceeded + message only on high verbosity, so as to not spam the logs when + it is busy. + +6 August 2018: Wouter + - Fix for #4136: Fix to unconditionally call destroy in daemon.c. + +3 August 2018: George + - Expose if a query (or a subquery) was ratelimited (not src IP + ratelimiting) to libunbound under 'ub_result.was_ratelimited'. + This also introduces a change to 'ub_event_callback_type' in + libunbound/unbound-event.h. + - Tidy pylib tests. + +3 August 2018: Wouter + - Revert previous change for #4136: because it introduces build + problems. + - New fix for #4136: This one ignores lex without without + yylex_destroy. + +1 August 2018: Wouter + - Fix to remove systemd sockaddr function check, that is not + always present. Make socket activation more lenient. But not + different when socket activation is not used. + - iana port list update. + +31 July 2018: Wouter + - Patches from Jim Hague (Sinodun) for EDNS KeepAlive. + - Sort out test runs when the build directory isn't the project + root directory. + - Add config tcp-idle-timeout (default 30s). This applies to + client connections only; the timeout on TCP connections upstream + is unaffected. + - Error if EDNS Keepalive received over UDP. + - Add edns-tcp-keepalive and edns-tcp-keepalive timeout options + and implement option in client responses. + - Correct and expand manual page entries for keepalive and idle timeout. + - Implement progressive backoff of TCP idle/keepalive timeout. + - Fix 'make depend' to work when build dir is not project root. + - Add delay parameter to streamtcp, -d secs. + To be used when testing idle timeout. + - From Wouter: make depend, the dependencies in the patches did not + apply cleanly. Also remade yacc and lex. + - Fix mesh.c incompatible pointer pass. + - Please doxygen so it passes. + - Fix #4139: Fix unbound-host leaks memory on ANY. + +30 July 2018: Wouter + - Fix #4136: insufficiency from mismatch of FLEX capability between + released tarball and build host. + +27 July 2018: Wouter + - Fix man page, say that chroot is enabled by default. + +26 July 2018: Wouter + - Fix #4135: 64-bit Windows Installer Creates Entries Under The + Wrong Registry Key, reported by Brian White. + +23 July 2018: Wouter + - Fix use-systemd readiness signalling, only when use-systemd is yes + and not in signal handler. + +20 July 2018: Wouter + - Fix #4130: print text describing -dd and unbound-checkconf on + config file read error at startup, the errors may have been moved + away by the startup process. + - Fix #4131: for solaris, error YY_CURRENT_BUFFER undeclared. + +19 July 2018: Wouter + - Fix #4129 unbound-control error message with wrong cert permissions + is too cryptic. + +17 July 2018: Wouter + - Fix #4127 unbound -h does not list -p help. + - Print error if SSL name verification configured but not available + in the ssl library. + - Fix that ratelimit and ip-ratelimit are applied after reload of + changed config file. + - Resize ratelimit and ip-ratelimit caches if changed on reload. + +16 July 2018: Wouter + - Fix qname minimisation NXDOMAIN validation lookup failures causing + error_supers assertion fails. + - Squelch can't bind socket errors with Permission denied unless + verbosity is 4 or higher, for UDP outgoing sockets. + +12 July 2018: Wouter + - Fix to improve systemd socket activation code file descriptor + assignment. + - Fix for 4126 that the #define for UNKNOWN_SERVER_NICENESS can be more + easily changed to adjust default rtt assumptions. + +10 July 2018: Wouter + - Note in documentation that the cert name match code needs + OpenSSL 1.1.0 or later to be enabled. + +6 July 2018: Wouter + - Fix documentation ambiguity for tls-win-cert in tls-upstream and + forward-tls-upstream docs. + - iana port update. + - Note RFC8162 support. SMIMEA record type can be read in by the + zone record parser. + - Fix round robin for failed addresses with prefer-ip6: yes + +4 July 2018: Wouter + - Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will not pass + if DNSSEC is not enabled. New option -R allows fallback from + resolv.conf to direct queries. + +3 July 2018: Wouter + - Better documentation for unblock-lan-zones and insecure-lan-zones + config statements. + - Fix permission denied printed for auth zone probe random port nrs. + +2 July 2018: Wouter + - Fix checking for libhiredis printout in configure output. + - Fix typo on man page in ip-address description. + - Update libunbound/python/examples/dnssec_test.py example code to + also set the 20326 trust anchor for the root in the example code. + +29 June 2018: Wouter + - dns64-ignore-aaaa: config option to list domain names for which the + existing AAAA is ignored and dns64 processing is used on the A + record. + +28 June 2018: Wouter + - num.queries.tls counter for queries over TLS. + - log port number with err_addr logs. + +27 June 2018: Wouter + - #4109: Fix that package config depends on python unconditionally. + - Patch, do not export python from pkg-config, from Petr Menšík. + +26 June 2018: Wouter + - Partial fix for permission denied on IPv6 address on FreeBSD. + - Fix that auth-zone master reply with current SOA serial does not + stop scan of masters for an updated zone. + - Fix that auth-zone does not start the wait timer without checking + if the wait timer has already been started. + +21 June 2018: Wouter + - #4108: systemd reload hang fix. + - Fix usage printout for unbound-host, hostname has to be last + argument on BSDs and Windows. + +19 June 2018: Wouter + - Fix for unbound-control on Windows and set TCP socket parameters + more closely. + This fix is part of 1.7.3. + - Windows example service.conf edited with more windows specific + configuration. + - Fix windows unbound-control no cert bad file descriptor error. + This fix is part of 1.7.3. + +18 June 2018: Wouter + - Fix that control-use-cert: no works for 127.0.0.1 to disable certs. + This fix is part of 1.7.3rc2. + - Fix unbound-checkconf for control-use-cert. + This fix is part of 1.7.3. + +15 June 2018: Wouter + - tag for 1.7.3rc1. + - trunk has 1.7.4. + - unbound-control auth_zone_reload _zone_ option rereads the zonefile. + - unbound-control auth_zone_transfer _zone_ option starts the probe + sequence for a master to transfer the zone from and transfers when + a new zone version is available. + +14 June 2018: Wouter + - #4103: Fix that auth-zone does not insist on SOA record first in + file for url downloads. + - Fix that first control-interface determines if TLS is used. Warn + when IP address interfaces are used without TLS. + - Fix nettle compile. + +12 June 2018: Ralph + - Don't count CNAME response types received during qname minimisation as + query restart. + +12 June 2018: Wouter + - #4102 for NSD, but for Unbound. Named unix pipes do not use + certificate and key files, access can be restricted with file and + directory permissions. The option control-use-cert is no longer + used, and ignored if found in unbound.conf. + - Rename tls-additional-ports to tls-additional-port, because every + line adds one port. + - Fix buffer size warning in unit test. + - remade dependencies in the Makefile. + +6 June 2018: Wouter + - Patch to fix openwrt for mac os build darwin detection in configure. + +5 June 2018: Wouter + - Fix crash if ratelimit taken into use with unbound-control + instead of with unbound.conf. + +4 June 2018: Wouter + - Fix deadlock caused by incoming notify for auth-zone. + - tag for 1.7.2rc1, became 1.7.2 release on 11 June 2018, + trunk is 1.7.3 in development from this point. + - #4100: Fix stub reprime when it becomes useless. + +1 June 2018: Wouter + - Rename additional-tls-port to tls-additional-ports. + The older name is accepted for backwards compatibility. + +30 May 2018: Wouter + - Patch from Syzdek: Add ability to ignore RD bit and treat all + requests as if the RD bit is set. + +29 May 2018: Wouter + - in compat/arc4random call getentropy_urandom when getentropy fails + with ENOSYS. + - Fix that fallback for windows port. + +28 May 2018: Wouter + - Fix windows tcp and tls spin on events. + - Add routine from getdns to add windows cert store to the SSL_CTX. + - tls-win-cert option that adds the system certificate store for + authenticating DNS-over-TLS connections. It can be used instead + of the tls-cert-bundle option, or with it to add certificates. + +25 May 2018: Wouter + - For TCP and TLS connections that don't establish, perform address + update in infra cache, so future selections can exclude them. + - Fix that tcp sticky events are removed for closed fd on windows. + - Fix close events for tcp only. + +24 May 2018: Wouter + - Fix that libunbound can do DNS-over-TLS, when configured. + - Fix that windows unbound service can use DNS-over-TLS. + - unbound-host initializes ssl (for potential DNS-over-TLS usage + inside libunbound), when ssl upstream or a cert-bundle is configured. + +23 May 2018: Wouter + - Use accept4 to speed up incoming TCP (and TLS) connections, + available on Linux, FreeBSD and OpenBSD. + +17 May 2018: Ralph + - Qname minimisation default changed to yes. + +15 May 2018: Wouter + - Fix low-rtt-pct to low-rtt-permil, as it is parts in one thousand. + +11 May 2018: Wouter + - Fix contrib/libunbound.pc for libssl libcrypto references, + from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=226914 + +7 May 2018: Wouter + - Fix windows to not have sticky TLS events for TCP. + - Fix read of DNS over TLS length and data in one read call. + - Fix mesh state assertion failure due to callback removal. + +3 May 2018: Wouter + - Fix that configure --with-libhiredis also turns on cachedb. + - Fix gcc 8 buffer warning in testcode. + - Fix function type cast warning in libunbound context callback type. + +2 May 2018: Wouter + - Fix fail to reject dead peers in forward-zone, with ssl-upstream. + +1 May 2018: Wouter + - Fix that unbound-control reload frees the rrset keys and returns + the memory pages to the system. + +30 April 2018: Wouter + - Fix spelling error in man page and note defaults as no instead of + off. + +26 April 2018: Wouter + - Fix for crash in daemon_cleanup with dnstap during reload, + from Saksham Manchanda. + - Also that for dnscrypt. + - tag for 1.7.1rc1 release. Became 1.7.1 release on 3 May, trunk + is from here 1.7.2 in development. + +25 April 2018: Ralph + - Fix memory leak when caching wildcard records for aggressive NSEC use + +24 April 2018: Wouter + - Fix contrib/fastrpz.patch for this release. + - Fix auth https for libev. + +24 April 2018: Ralph + - Added root-key-sentinel support + +23 April 2018: Wouter + - makedist uses bz2 for expat code, instead of tar.gz. + - Fix #4092: libunbound: use-caps-for-id lacks colon in + config_set_option. + - auth zone http download stores exact copy of downloaded file, + including comments in the file. + - Fix sldns parse failure for CDS alternate delete syntax empty hex. + - Attempt for auth zone fix; add of callback in mesh gets from + callback does not skip callback of result. + - Fix cname classification with qname minimisation enabled. + - list_auth_zones unbound-control command. + +20 April 2018: Wouter + - man page documentation for dns-over-tls forward-addr '#' notation. + - removed free from failed parse case. + - Fix #4091: Fix that reload of auth-zone does not merge the zonefile + with the previous contents. + - Delete auth zone when removed from config. + +19 April 2018: Wouter + - Can set tls authentication with forward-addr: IP#tls.auth.name + And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem". + such as forward-addr: 9.9.9.9@853#dns.quad9.net or + 1.1.1.1@853#cloudflare-dns.com + - Fix #658: unbound using TLS in a forwarding configuration does not + verify the server's certificate (RFC 8310 support). + - For addr with #authname and no @port notation, the default is 853. + +18 April 2018: Wouter + - Fix auth-zone retry timer to be on schedule with retry timeout, + with backoff. Also time a refresh at the zone expiry. + +17 April 2018: Wouter + - auth zone notify work. + - allow-notify: config statement for auth-zones. + - unit test for allow-notify + +16 April 2018: Wouter + - Fix auth zone target lookup iterator. + - auth zone notify with prefix + - auth zone notify work. + +13 April 2018: Wouter + - Fix for max include depth for authzones. + - Fix memory free on fail for $INCLUDE in authzone. + - Fix that an internal error to look up the wrong rr type for + auth zone gets stopped, before trying to send there. + - auth zone notify work. + +10 April 2018: Ralph + - num.query.aggressive.NOERROR and num.query.aggressive.NXDOMAIN + statistics counters. + +10 April 2018: Wouter + - documentation for low-rtt and low-rtt-pct. + - auth zone notify work. + +9 April 2018: Wouter + - Fix that flush_zone sets prefetch ttl expired, so that with + serve-expired enabled it'll start prefetching those entries. + - num.query.authzone.up and num.query.authzone.down statistics counters. + - Fix downstream auth zone, only fallback when auth zone fails to + answer and fallback is enabled. + - Accept both option names with and without colon for get_option + and set_option. + - low-rtt and low-rtt-pct in unbound.conf enable the server selection + of fast servers for some percentage of the time. + +5 April 2018: Wouter + - Combine write of tcp length and tcp query for dns over tls. + - nitpick fixes in example.conf. + - Fix above stub queries for type NS and useless delegation point. + - Fix unbound-control over pipe with openssl 1.1.1, the TLSv1.3 + tls_choose_sigalg routine does not allow the ciphers for the pipe, + so use TLSv1.2. + - ED448 support. + +3 April 2018: Wouter + - Fix #4043: make test fails due to v6 presentation issue in macOS. + - Fix unable to resolve after new WLAN connection, due to auth-zone + failing with a forwarder set. Now, auth-zone is only used for + answers (not referrals) when a forwarder is set. + +29 March 2018: Ralph + - Check "result" in dup_all(), by Florian Obser. + +23 March 2018: Ralph + - Fix unbound-control get_option aggressive-nsec + +21 March 2018: Ralph + - Do not use cached NSEC records to generate negative answers for + domains under DNSSEC Negative Trust Anchors. + +19 March 2018: Wouter + - iana port update. + +16 March 2018: Wouter + - corrected a minor typo in the changelog. + - move htobe64/be64toh portability code to cachedb.c. + +15 March 2018: Wouter + - Add --with-libhiredis, unbound support for a new cachedb backend + that uses a Redis server as the storage. This implementation + depends on the hiredis client library (https://redislabs.com/lp/hiredis/). + And unbound should be built with both --enable-cachedb and + --with-libhiredis[=PATH] (where $PATH/include/hiredis/hiredis.h + should exist). Patch from Jinmei Tatuya (Infoblox). + - Fix #3817: core dump happens in libunbound delete, when queued + servfail hits deleted message queue. + - Create additional tls service interfaces by opening them on other + portnumbers and listing the portnumbers as additional-tls-port: nr. + +13 March 2018: Wouter + - Fix typo in documentation. + - Fix #3736: Fix 0 TTL domains stuck on SERVFAIL unless manually + flushed with serve-expired on. + +12 March 2018: Wouter + - Added documentation for aggressive-nsec: yes. + - tag 1.7.0rc3. That became the 1.7.0 release on 15 Mar, trunk + now has 1.7.1 in development. + - Fix #3727: Protocol name is TLS, options have been renamed but + documentation is not consistent. + - Check IXFR start serial. + +9 March 2018: Wouter + - Fix #3598: Fix swig build issue on rhel6 based system. + configure --disable-swig-version-check stops the swig version check. + +8 March 2018: Wouter + - tag 1.7.0rc2. + +7 March 2018: Wouter + - Fixed contrib/fastrpz.patch, even though this already applied + cleanly for me, now also for others. + - patch to log creates keytag queries, from A. Schulze. + - patch suggested by Debian lintian: allow to -> allow one to, from + A. Schulze. + - Attempt to remove warning about trailing whitespace. + +6 March 2018: Wouter + - Reverted fix for #3512, this may not be the best way forward; + although it could be changed at a later time, to stay similar to + other implementations. + - svn trunk contains 1.7.0, this is the number for the next release. + - Fix for windows compile. + - tag 1.7.0rc1. + +5 March 2018: Wouter + - Fix to check define of DSA for when openssl is without deprecated. + - iana port update. + - Fix #3582: Squelch address already in use log when reuseaddr option + causes same port to be used twice for tcp connections. + +27 February 2018: Wouter + - Fixup contrib/fastrpz.patch so that it applies. + - Fix compile without threads, and remove unused variable. + - Fix compile with staticexe and python module. + - Fix nettle compile. + +22 February 2018: Ralph + - Save wildcard RRset from answer with original owner for use in + aggressive NSEC. + +21 February 2018: Wouter + - Fix #3512: unbound incorrectly reports SERVFAIL for CAA query + when there is a CNAME loop. + - Fix validation for CNAME loops. When it detects a cname loop, + by finding the cname, cname in the existing list, it returns + the partial result with the validation result up to then. + - more robust cachedump rrset routine. + +19 February 2018: Wouter + - Fix #3505: Documentation for default local zones references + wrong RFC. + - Fix #3494: local-zone noview can be used to break out of the view + to the global local zone contents, for queries for that zone. + - Fix for more maintainable code in localzone. + +16 February 2018: Wouter + - Fixes for clang static analyzer, the missing ; in + edns-subnet/addrtree.c after the assert made clang analyzer + produce a failure to analyze it. + +13 February 2018: Ralph + - Aggressive NSEC tests + +13 February 2018: Wouter + - tls-cert-bundle option in unbound.conf enables TLS authentication. + - iana port update. + +12 February 2018: Wouter + - Unit test for auth zone https url download. + +12 February 2018: Ralph + - Added tests with wildcard expanded NSEC records (CVE-2017-15105 test) + - Processed aggressive NSEC code review remarks Wouter + +8 February 2018: Ralph + - Aggressive use of NSEC implementation. Use cached NSEC records to + generate NXDOMAIN, NODATA and positive wildcard answers. + +8 February 2018: Wouter + - iana port update. + - auth zone url config. + +5 February 2018: Wouter + - Fix #3451: dnstap not building when you have a separate build dir. + And removed protoc warning, set dnstap.proto syntax to proto2. + - auth-zone provides a way to configure RFC7706 from unbound.conf, + eg. with auth-zone: name: "." for-downstream: no for-upstream: yes + fallback-enabled: yes and masters or a zonefile with data. + +2 February 2018: Wouter + - Fix unfreed locks in log and arc4random at exit of unbound. + - unit test with valgrind + - Fix lock race condition in dns cache dname synthesis. + - lock subnet new item before insertion to please checklocks, + no modification of critical regions outside of lock region. + +1 February 2018: Wouter + - fix unaligned structure making a false positive in checklock + unitialised memory. + +29 January 2018: Ralph + - Use NSEC with longest ce to prove wildcard absence. + - Only use *.ce to prove wildcard absence, no longer names. + +25 January 2018: Wouter + - ltrace.conf file for libunbound in contrib. + +23 January 2018: Wouter + - Fix that unbound-checkconf -f flag works with auto-trust-anchor-file + for startup scripts to get the full pathname(s) of anchor file(s). + - Print fatal errors about remote control setup before log init, + so that it is printed to console. + +22 January 2018: Wouter + - Accept tls-upstream in unbound.conf, the ssl-upstream keyword is + also recognized and means the same. Also for tls-port, + tls-service-key, tls-service-pem, stub-tls-upstream and + forward-tls-upstream. + - Fix #3397: Fix that cachedb could return a partial CNAME chain. + - Fix #3397: Fix that when the cache contains an unsigned DNAME in + the middle of a cname chain, a result without the DNAME could + be returned. + +19 January 2018: Wouter + - tag 1.6.8 for release with CVE fix. + - trunk has 1.6.9 with fix and previous commits. + - patch for CVE-2017-15105: vulnerability in the processing of + wildcard synthesized NSEC records. + - iana port update. + - make depend: code dependencies updated in Makefile. + +4 January 2018: Ralph + - Copy query and correctly set flags on REFUSED answers when cache + snooping is not allowed. + +3 January 2018: Ralph + - Fix queries being leaked above stub when refetching glue. + +2 January 2017: Wouter + - Fix that DS queries with referral replies are answered straight + away, without a repeat query picking the DS from cache. + The correct reply should have been an answer, the reply is fixed + by the scrubber to have the answer in the answer section. + - Remove clang optimizer disable, + Fix that expiration date checks don't fail with clang -O2. + +15 December 2017: Wouter + - Fix timestamp failure because of clang optimizer failure, by + disabling -O2 when the compiler --version is clang. + - iana port update. + - Also disable -flto for clang, to make incep-expi signature check + work. + +12 December 2017: Ralph + - Fix qname-minimisation documentation (A QTYPE, not NS) + +12 December 2017: Wouter + - authzone work, transfer connect. + +7 December 2017: Ralph + - Check whether --with-libunbound-only is set when using --with-nettle + or --with-nss. + +4 December 2017: Wouter + - Fix link failure on OmniOS. + +1 December 2017: Wouter + - auth zone work. + +30 November 2017: Wouter + - Fix #3299 - forward CNAME daisy chain is not working + +14 November 2017: Wouter + - Fix #2882: Unbound behaviour changes (wrong) when domain-insecure is + set for stub zone. It no longer searches for DNSSEC information. + - auth xfer work on probe timer and lookup. + +13 November 2017: Wouter + - Fix #2801: Install libunbound.pc. + - Fix qname minimisation to send AAAA queries at zonecut like type A. + - reverted AAAA change. + +7 November 2017: Wouter + - Fix #2492: Documentation libunbound. + +3 November 2017: Wouter + - Fix #2362: TLS1.3/openssl-1.1.1 not working. + - Fix #2034 - Autoconf and -flto. + - Fix #2141 - for libsodium detect lack of entropy in chroot, print + a message and exit. + +2 November 2017: Wouter + - Fix #1913: ub_ctx_config is under circumstances thread-safe. + - make ip-transparent option work on OpenBSD. + +31 October 2017: Wouter + - Document that errno is left informative on libunbound config read + fail. + - lexer output. + - iana port update. + +25 October 2017: Ralph + - Fixed libunbound manual typo. + - Fix #1949: [dnscrypt] make provider name mismatch more obvious. + - Fix #2031: Double included headers + +24 October 2017: Ralph + - Update B root ipv4 address. + +19 October 2017: Wouter + - authzone work, probe timer setup. + +18 October 2017: Wouter + - lint for recent authzone commit. + +17 October 2017: Wouter + - Fix #1749: With harden-referral-path: performance drops, due to + circular dependency in NS and DS lookups. + - [dnscrypt] prevent dnscrypt-secret-key, dnscrypt-provider-cert + duplicates + - [dnscrypt] introduce dnscrypt-provider-cert-rotated option, + from Manu Bretelle. + This option allows handling multiple cert/key pairs while only + distributing some of them. + In order to reliably match a client magic with a given key without + strong assumption as to how those were generated, we need both key and + cert. Likewise, in order to know which ES version should be used. + On the other hand, when rotating a cert, it can be desirable to only + serve the new cert but still be able to handle clients that are still + using the old certs's public key. + The `dnscrypt-provider-cert-rotated` allow to instruct unbound to not + publish the cert as part of the DNS's provider_name's TXT answer. + - Better documentation for cache-max-negative-ttl. + - Work on local root zone code. + +10 October 2017: Wouter + - tag 1.6.7 + - trunk has version 1.6.8. + +6 October 2017: Wouter + - Fix spelling in unbound-control man page. + +5 October 2017: Wouter + - Fix trust-anchor-signaling works in libunbound. + - Fix some more crpls in testdata for different signaling default. + - tag 1.6.7rc1 + +5 October 2017: Ralph + - Set trust-anchor-signaling default to yes + - Use RCODE from A query on DNS64 synthesized answer. + +2 October 2017: Wouter + - Fix param unused warning for windows exportsymbol compile. + +25 September 2017: Ralph + - Fix #1450: Generate again patch contrib/aaaa-filter-iterator.patch + (by Danilo G. Baio). + +21 September 2017: Ralph + - Log name of looping module + +19 September 2017: Wouter + - use a cachedb answer even if it's "expired" when serve-expired is yes + (patch from Jinmei Tatuya). + - trigger refetching of the answer in that case (this will bypass + cachedb lookup) + - allow storing a 0-TTL answer from cachedb in the in-memory message + cache when serve-expired is yes + - Fix DNSCACHE_STORE_ZEROTTL to be bigger than 0xffff. + +18 September 2017: Ralph + - Fix #1400: allowing use of global cache on ECS-forwarding unless + always-forward. + +18 September 2017: Wouter + - tag 1.6.6 (is 1.6.6rc2) + - Fix that looping modules always stop the query, and don't pass + control. + - Fix #1435: Please allow UDP to be disabled separately upstream and + downstream. + - Fix #1440: [dnscrypt] client nonce cache. + +15 September 2017: Wouter + - Fix unbound-host to report error for DNSSEC state of failed lookups. + - Spelling fixes, from Josh Soref. + +13 September 2017: Wouter + - tag 1.6.6rc2, became 1.6.6 on 18 sep. trunk 1.6.7 in development. + +12 September 2017: Wouter + - Add dns64 for client-subnet in unbound-checkconf. + +4 September 2017: Ralph + - Fix #1412: QNAME minimisation strict mode not honored + - Fix #1434: Fix windows openssl 1.1.0 linking. + +4 September 2017: Wouter + - tag 1.6.6rc1 + - makedist fix for windows binaries, with openssl 1.1.0 windres fix, + and expat 2.2.4 install target fix. + +1 September 2017: Wouter + - Recommend 1472 buffer size in unbound.conf + +31 August 2017: Wouter + - Fix #1424: cachedb:testframe is not thread safe. + - For #1417: escape ; in dnscrypt tests. + - but reverted that, tests fails with that escape. + - Fix #1417: [dnscrypt] shared secret cache counters, and works when + dnscrypt is not enabled. And cache size configuration option. + - make depend + - Fix #1418: [ip ratelimit] initialize slabhash using + ip-ratelimit-slabs. + +30 August 2017: Wouter + - updated contrib/fastrpz.patch to apply with configparser changes. + - Fix 1416: qname-minimisation breaks TLSA lookups with CNAMEs. + +29 August 2017: Wouter + - Fix #1414: fix segfault on parse failure and log_replies. + - zero qinfo in handle_request, this zeroes local_alias and also the + qname member. + - new keys and certs for dnscrypt tests. + - fixup WKS test on buildhost without servicebyname. + +28 August 2017: Wouter + - Fix #1415: patch to free dnscrypt environment on reload. + - iana portlist update + - Fix #1415: [dnscrypt] shared secret cache, patch from + Manu Bretelle. + - Small fixes for the shared secret cache patch. + - Fix WKS records on kvm autobuild host, with default protobyname + entries for udp and tcp. + +23 August 2017: Wouter + - Fix #1407: Add ECS options check to unbound-checkconf. + - make depend + - Fix to reclaim tcp handler when it is closed due to dnscrypt buffer + allocation failure. + +22 August 2017: Wouter + - Fix install of trust anchor when two anchors are present, makes both + valid. Checks hash of DS but not signature of new key. This fixes + the root.key file if created when unbound is installed between + sep11 and oct11 2017. + - tag 1.6.5 with pointrelease 1.6.5 (1.6.4 plus 5011 fix). + - trunk version 1.6.6 in development. + - Fix issue on macOX 10.10 where TCP fast open is detected but not + implemented causing TCP to fail. The fix allows fallback to regular + TCP in this case and is also more robust for cases where connectx() + fails for some reason. + - Fix #1402: squelch invalid argument error for fd_set_block on windows. + +10 August 2017: Wouter + - Patch to show DNSCrypt status in help output, from Carsten + Strotmann. + +8 August 2017: Wouter + - Fix #1398: make cachedb secret configurable. + - Remove spaces from Makefile. + +7 August 2017: Wouter + - Fix #1397: Recursive DS lookups for AS112 zones names should recurse. + +3 August 2017: Ralph + - Remove unused iter_env member (ip6arpa_dname) + - Do not reset rrset.bogus stats when called using stats_noreset. + - Added stats for queries that have been ratelimited by domain + recursion. + - Do not add rrset_bogus and query ratelimiting stats per thread, these + module stats are global. + +3 August 2017: Wouter + - Fix #1394: mix of serve-expired and response-ip could cause a crash. + +24 July 2017: Wouter + - upgrade aclocal(pkg.m4 0.29.1), config.guess(2016-10-02), + config.sub(2016-09-05). + - annotate case statement fallthrough for gcc 7.1.1. + - flex output from flex 2.6.1. + - snprintf of thread number does not warn about truncated string. + - squelch TCP fast open error on FreeBSD when kernel has it disabled, + unless verbosity is high. + - remove warning from windows compile. + - Fix compile with libnettle + - Fix DSA configure switch (--disable dsa) for libnettle and libnss. + - Fix #1365: Add Ed25519 support using libnettle. + - iana portlist update + +17 July 2017: Wouter + - Fix #1350: make cachedb backend configurable (from JINMEI Tatuya). + - Fix #1349: allow suppression of pidfiles (from Daniel Kahn Gillmor). + With the -p option unbound does not create a pidfile. + +11 July 2017: Wouter + - Fix #1344: RFC6761-reserved domains: test. and invalid. + - Redirect all localhost names to localhost address for RFC6761. + +6 July 2017: Wouter + - Fix tests to use .tdir (from Manu Bretelle) instead of .tpkg. + - Fix svn hooks for tdir (selected if testcode/mini_tdir.sh exists).. + +4 July 2017: Wouter + - Fix 1332: Bump verbosity of failed chown'ing of the control socket. + +3 July 2017: Wouter + - Fix for unbound-checkconf, check ipsecmod-hook if ipsecmod is turned + on. + - Fix #1331: libunbound segfault in threaded mode when context is + deleted. + - Fix pythonmod link line option flag. + - Fix openssl 1.1.0 load of ssl error strings from ssl init. + +29 June 2017: Wouter + - Fix python example0 return module wait instead of error for pass. + - iana portlist update + - enhancement for hardened-tls for DNS over TLS. Removed duplicated + security settings. + +27 June 2017: Wouter + - Tag 1.6.4 is created with the 1.6.4rc2 contents. + - Trunk contains 1.6.5, with changes from 26, 27 june. + - Remove signed unsigned warning from authzone. + - Fix that infra cache host hash does not change after reconfig. + +26 June 2017: Wouter + - (for 1.6.5) + Better fixup of dnscrypt_cert_chacha test for different escapes. + - First fix for zero b64 and hex text zone format in sldns. + - unbound-control dump_infra prints port number for address if not 53. + +23 June 2017: Wouter + - (for 1.6.5): fixup of dnscrypt_cert_chacha test (from Manu Bretelle). + +22 June 2017: Wouter + - Tag 1.6.4rc2 + +22 June 2017: Ralph + - Added fastrpz patch to contrib + +21 June 2017: Wouter + - Fix #1316: heap read buffer overflow in parse_edns_options. + +20 June 2017: Wouter + - Fix warning in pythonmod under clang compiler. + - Tag 1.6.4rc1 + - Fix lintian typo. + +16 June 2017: Ralph + - Fix #1277: disable domain ratelimit by setting value to 0. + +16 June 2017: Wouter + - Fix #1301: memory leak in respip and tests. + - Free callback in edns-subnetmod on exit and restart. + - Fix memory leak in sldns_buffer_new_frm_data. + - Fix memory leak in dnscrypt config read. + - Fix dnscrypt chacha cert support ifdefs. + - Fix dnscrypt chacha cert unit test escapes in grep. + - Remove asynclook tests that cause test and purifier problems. + - Fix to unlock view in view test. + +15 June 2017: Wouter + - Fix stub zone queries leaking to the internet for + harden-referral-path ns checks. + - Fix query for refetch_glue of stub leaking to internet. + +13 June 2017: Wouter + - Fix #1279: Memory leak on reload when python module is enabled. + - Fix #1280: Unbound fails assert when response from authoritative + contains malformed qname. When 0x20 caps-for-id is enabled, when + assertions are not enabled the malformed qname is handled correctly. + - 1.6.3 tag created, with only #1280 fix, trunk is 1.6.4 development. + - More fixes in depth for buffer checks in 0x20 qname checks. + +12 June 2017: Wouter + - Fix #1278: Incomplete wildcard proof. + +8 June 2017: Ralph + - Added domain name based ECS whitelist. + +8 June 2017: Wouter + - Detect chacha for dnscrypt at configure time. + - dnscrypt unit tests with chacha. + +7 June 2017: Wouter + - Fix that unbound-control can set val_clean_additional and val_permissive_mode. + - Add dnscrypt XChaCha20 tests. + +6 June 2017: Wouter + - Add an explicit type cast for TCP FASTOPEN fix. + - renumbering B-Root's IPv6 address to 2001:500:200::b. + - Fix #1275: cached data in cachedb is never used. + - Fix #1276: [dnscrypt] add XChaCha20-Poly1305 cipher. + +1 June 2017: Ralph + - Fix #1274: automatically trim chroot path from dnscrypt key/cert paths + (from Manu Bretelle). + +1 June 2017: Wouter + - Fix fastopen EPIPE fallthrough to perform connect. + +31 May 2017: Ralph + - Also use global local-zones when there is a matching view that does + not have any local-zone specified. + +31 May 2017: Wouter + - Fix #1273: cachedb.c doesn't compile with -Wextra. + - If MSG_FASTOPEN gives EPIPE fallthrough to try normal tcp write. + +30 May 2017: Ralph + - Fix #1269: inconsistent use of built-in local zones with views. + - Add defaults for new local-zone trees added to views using + unbound-control. + +30 May 2017: Wouter + - Support for openssl EVP_DigestVerify. + - Support for the ED25519 algorithm with openssl (from openssl 1.1.1). + +29 May 2017: Wouter + - Fix assertion for low buffer size and big edns payload when worker + overrides udpsize. + +26 May 2017: Ralph + - Added redirect-bogus.patch to contrib directory. + +26 May 2017: Wouter + - Fix #1270: unitauth.c doesn't compile with higher warning level + and optimization + - exec_prefix is by default equal to prefix. + - printout localzone for duplicate local-zone warnings. + +24 May 2017: Wouter + - authzone cname chain, no rrset duplicates, wildcard doesn't change + rrsets added for cname chain. + +23 May 2017: Wouter + - first services/authzone check in, it compiles and reads and writes + zonefiles. + - iana portlist update + +22 May 2017: Wouter + - Fix #1268: SIGSEGV after log_reopen. + +18 May 2017: Wouter + - Fix #1265 to use /bin/kill. + - Fix #1267: Libunbound validator/val_secalgo.c uses obsolete APIs, + and compatibility with BoringSSL. + +17 May 2017: Wouter + - Fix #1265: contrib/unbound.service contains hardcoded path. + +17 May 2017: George + - Use qstate's region for IPSECKEY rrset (ipsecmod). + +16 May 2017: George + - Implemented opportunistic IPsec support module (ipsecmod). + - Some whitespace fixup. + +16 May 2017: Wouter + - updated dependencies in the makefile. + - document trust-anchor-signaling in example config file. + - updated configure, dependencies and flex output. + - better module memory lookup, fix of unbound-control shm names for + module memory printout of statistics. + - Fix type AVC sldns rrdef. + +12 May 2017: Wouter + - Adjust servfail by iterator to not store in cache when serve-expired + is enabled, to avoid overwriting useful information there. + - Fix queries for nameservers under a stub leaking to the internet. + +9 May 2017: Ralph + - Add 'c' to getopt() in testbound. + - iana portlist update + +8 May 2017: Wouter + - Fix tcp-mss failure printout text. + - Set SO_REUSEADDR on outgoing tcp connections to fix the bind before + connect limited tcp connections. With the option tcp connections + can share the same source port (for different destinations). + +2 May 2017: Ralph + - Added mesh_add_sub to add detached mesh entries. + - Use mesh_add_sub for key tag signaling query. + +2 May 2017: Wouter + - Added test for leak of stub information. + - Fix sldns wire2str printout of RR type CAA tags. + - Fix sldns int16_data parse. + - Fix sldns parse and printout of TSIG RRs. + - sldns SMIMEA and AVC definitions, same as getdns definitions. + +1 May 2017: Wouter + - Fix #1259: "--disable-ecdsa" argument overwritten + by "#ifdef SHA256_DIGEST_LENGTH@daemon/remote.c". + - iana portlist update + - Fix #1258: Windows 10 X64 unbound 1.6.2 service will not start. + and fix that 64bit getting installed in C:\Program Files (x86). + +26 April 2017: Ralph + - Implemented trust anchor signaling using key tag query. + +26 April 2017: Wouter + - Based on #1257: check parse limit before t increment in sldns RR + string parse routine. + +24 April 2017: Wouter + - unbound-checkconf -o allows query of dnstap config variables. + Also unbound-control get_option. Also for dnscrypt. + - trunk contains 1.6.3 version number (changes from 1.6.2 back from + when the 1.6.2rc1 tag has been created). + +21 April 2017: Ralph + - Fix #1254: clarify ratelimit-{for,below}-domain (from Manu Bretelle). + - iana portlist update + +18 April 2017: Ralph + - Fix #1252: more indentation inconsistencies. + - Fix #1253: unused variable in edns-subnet/addrtree.c:getbit(). + +13 April 2017: Ralph + - Added ECS unit test (from Manu Bretelle). + - ECS documentation fix (from Manu Bretelle). + +13 April 2017: Wouter + - Fix #1250: inconsistent indentation in services/listen_dnsport.c. + - tag for 1.6.2rc1 + - (for 1.6.3:) unbound.h exports the shm stats structures. They use + type long long and no ifdefs, and ub_ before the typenames. + +12 April 2017: Wouter + - subnet mem value is available in shm, also when not enabled, + to make the struct easier to memmap by other applications, + independent of the configuration of unbound. + +12 April 2017: Ralph + - Fix #1247: unbound does not shorten source prefix length when + forwarding ECS. + - Properly check for allocation failure in local_data_find_tag_datas. + - Fix #1249: unbound doesn't return FORMERR to bogus ECS. + - Set SHM ECS memory usage to 0 when module not loaded. + +11 April 2017: Ralph + - Display ECS module memory usage. + +10 April 2017: Wouter + - harden-algo-downgrade: no also makes unbound more lenient about + digest algorithms in DS records. + +10 April 2017: Ralph + - Remove ECS option after REFUSED answer. + - Fix small memory leak in edns_opt_copy_alloc. + - Respip dereference after NULL check. + - Zero initialize addrtree allocation. + - Use correct identifier for SHM destroy. + +7 April 2017: George + - Fix pythonmod for cb changes. + - Some whitespace fixup. + +7 April 2017: Ralph + - Unlock view in respip unit test + +6 April 2017: Ralph + - Generalise inplace callback (de)registration + - (de)register inplace callbacks for module id + - No unbound-control set_option for ECS options + - Deprecated client-subnet-opcode config option + - Introduced client-subnet-always-forward config option + - Changed max-client-subnet-ipv6 default to 56 (as in RFC) + - Removed extern ECS config options + - module_restart_next now calls clear on all following modules + - Also create ECS module qstate on module_event_pass event + - remove malloc from inplace_cb_register + +6 April 2017: Wouter + - Small fixup for documentation. + - iana portlist update + - Fix respip for braces when locks arent used. + - Fix pythonmod for cb changes. + +4 April 2017: Wouter + - Fix #1244: document that use of chroot requires trust anchor file to + be under chroot. + - iana portlist update + +3 April 2017: Ralph + - Do not add current time twice to TTL before ECS cache store. + - Do not touch rrset cache after ECS cache message generation. + - Use LDNS_EDNS_CLIENT_SUBNET as default ECS opcode. + +3 April 2017: Wouter + - Fix #1217: Add metrics to unbound-control interface showing + crypted, cert request, plaintext and malformed queries (from + Manu Bretelle). + - iana portlist update + +27 March 2017: Wouter + - Remove (now unused) event2 include from dnscrypt code. + +24 March 2017: George + - Fix to prevent non-referal query from being cached as referal when the + no_cache_store flag was set. + +23 March 2017: Wouter + - Fix #1239: configure fails to find python distutils if python + prints warning. + +22 March 2017: Wouter + - Fix #1238: segmentation fault when adding through the remote + interface a per-view local zone to a view with no previous + (configured) local zones. + - Fix #1229: Systemd service sandboxing, options in wrong sections. + +21 March 2017: Ralph + - Merge EDNS Client subnet implementation from feature branch into main + branch, using new EDNS processing framework. + +21 March 2017: Wouter + - Fix doxygen for dnscrypt files. + +20 March 2017: Wouter + - #1217. DNSCrypt support, with --enable-dnscrypt, libsodium and then + enabled in the config file from Manu Bretelle. + - make depend, autoconf, remove warnings about statement before var. + - lru_demote and lruhash_insert_or_retrieve functions for getdns. + - fixup for lruhash (whitespace and header file comment). + - dnscrypt tests. + +17 March 2017: Wouter + - Patch for view functionality for local-data-ptr from Björn Ketelaars. + - Fix #1237 - Wrong resolving in chain, for norec queries that get + SERVFAIL returned. + +16 March 2017: Wouter + - Fix that SHM is not inited if not enabled. + - Add trustanchor.unbound CH TXT that gets a response with a number + of TXT RRs with a string like "example.com. 2345 1234" with + the trust anchors and their keytags. + - Fix that looped DNAMEs do not cause unbound to spend effort. + - trustanchor tags are sorted. reusable routine to fetch taglist. + +13 March 2017: Wouter + - testbound understands Deckard MATCH rcode question answer commands. + - Fix #1235: Fix too long DNAME expansion produces SERVFAIL instead + of YXDOMAIN + query loop, reported by Petr Spacek. + +10 March 2017: Wouter + - Fix #1234: shortening DNAME loop produces duplicate DNAME records + in ANSWER section. + +9 March 2017: Wouter + - --disable-sha1 disables SHA1 support in RRSIG, so from DNSKEY and + DS records. NSEC3 is not disabled. + - fake-sha1 test option; print warning if used. To make unit tests. + - unbound-control list local zone and data commands listed in the + help output. + +8 March 2017: Wouter + - make depend for build dependencies. + - swig version 2.0.1 required. + - fix enum conversion warnings + +7 March 2017: Wouter + - Fix #1230: swig version 2.0.0 is required for pythonmod, with + 1.3.40 it crashes when running repeatly unbound-control reload. + - Response actions based on IP address from Jinmei Tatuya (Infoblox). + +6 March 2017: Wouter + - Fix #1229: Systemd service sandboxing in contrib/unbound.service. + - iana portlist update + +28 February 2017: Ralph + - Fix testpkts.c, check if DO bit is set, not only if there is an OPT + record. + +28 February 2017: Wouter + - For #1227: if we have sha256, set the cipher list to have no + known vulns. + +27 February 2017: Wouter + - Fix #1227: Fix that Unbound control allows weak ciphersuits. + - Fix #1226: provide official 32bit binary for windows. + +24 February 2017: Wouter + - include sys/time.h for new shm code on NetBSD. + +23 February 2017: Wouter + - Fix doc/CNAME-basedRedirectionDesignNotes.pdf zone static to + redirect. + - Patch from Luiz Fernando Softov for Stats Shared Memory. + - unbound-control stats_shm command prints stats using shared memory, + which uses less cpu. + - make depend, autoconf, doxygen and lint fixed up. + +22 February 2017: Wouter + - Fix #1224: Fix that defaults should not fall back to "Program Files + (x86) if Unbound is 64bit by default on windows. + +21 February 2017: Wouter + - iana portlist update + +16 February 2017: Wouter + - sldns updated for vfixed and buffer resize indication from getdns. + +15 February 2017: Wouter + - sldns has ED25519 and ED448 algorithm number and name for display. + +14 February 2017: Wouter + - tag 1.6.1rc3. -- which became 1.6.1 on 21feb, trunk has 1.6.2 + +13 February 2017: Wouter + - Fix autoconf of systemd check for lack of pkg-config. + +10 February 2017: Wouter + - Fix pythonmod for typedef changes. + - Fix dnstap for warning of set but not used. + - tag 1.6.1rc2. + +9 February 2017: Wouter + - tag 1.6.1rc1. + +8 February 2017: Wouter + - Fix for type name change and fix warning on windows compile. + +7 February 2017: Wouter + - Include root trust anchor id 20326 in unbound-anchor. + +6 February 2017: Wouter + - Fix compile on solaris of the fix to use $host detect. + +4 February 2017: Wouter + - fix root_anchor test for updated icannbundle.pem lower certificates. + +26 January 2017: Wouter + - Fix 1211: Fix can't enable interface-automatic if no IPv6 with + more helpful error message. + +20 January 2017: Wouter + - Increase MAX_MODULE to 16. + +19 January 2017: Wouter + - Fix to Rename ub_callback_t to ub_callback_type, because POSIX + reserves _t typedefs. + - Fix to rename internally used types from _t to _type, because _t + type names are reserved by POSIX. + - iana portlist update + +12 January 2017: Wouter + - Fix to also block meta types 128 through to 248 with formerr. + - Fix #1206: Some view-related commands are missing from 'unbound-control -h' + +9 January 2017: Wouter + - Fix #1202: Fix code comment that packed_rrset_data is not always + 'packed'. + +6 January 2017: Wouter + - Fix #1201: Fix missing unlock in answer_from_cache error condition. + +5 January 2017: Wouter + - Fix to return formerr for queries for meta-types, to avoid + packet amplification if this meta-type is sent on to upstream. + - Fix #1184: Log DNS replies. This includes the same logging + information that DNS queries and response code and response size, + patch from Larissa Feng. + - Fix #1187: Source IP rate limiting, patch from Larissa Feng. + +3 January 2017: Wouter + - configure --enable-systemd and lets unbound use systemd sockets if + you enable use-systemd: yes in unbound.conf. + Also there are contrib/unbound.socket and contrib/unbound.service: + systemd files for unbound, install them in /usr/lib/systemd/system. + Contributed by Sami Kerola and Pavel Odintsov. + - Fix reload chdir failure when also chrooted to that directory. + +2 January 2017: Wouter + - Fix #1194: Cross build fails when $host isn't `uname` for getentropy. + +23 December 2016: Ralph + - Fix #1190: Do not echo back EDNS options in local-zone error response. + - iana portlist update + +21 December 2016: Ralph + - Fix #1188: Unresolved symbol 'fake_dsa' in libunbound.so when built + with Nettle + +19 December 2016: Ralph + - Fix #1191: remove comment about view deletion. + +15 December 2016: Wouter + - iana portlist update + - 64bit is default for windows builds. + - Fix inet_ntop and inet_pton warnings in windows compile. + +14 December 2016: Wouter + - Fix #1178: attempt to fix setup error at end, pop result values + at end of install. + +13 December 2016: Wouter + - Fix #1182: Fix Resource leak (socket), at startup. + - Fix unbound-control and ipv6 only. + +9 December 2016: Wouter + - Fix #1176: stack size too small for Alpine Linux. + +8 December 2016: Wouter + - Fix downcast warnings from visual studio in sldns code. + - tag 1.6.0rc1 which became 1.6.0 on 15 dec, and trunk is 1.6.1. + +7 December 2016: Ralph + - Add DSA support for OpenSSL 1.1.0 + - Fix remote control without cert for LibreSSL + +6 December 2016: George + - Added generic EDNS code for registering known EDNS option codes, + bypassing the cache response stage and uniquifying mesh states. Four EDNS + option lists were added to module_qstate (module_qstate.edns_opts_*) to + store EDNS options from/to front/back side. + - Added two flags to module_qstate (no_cache_lookup, no_cache_store) that + control the modules' cache interactions. + - Added code for registering inplace callback functions. The registered + functions can be called just before replying with local data or Chaos, + replying from cache, replying with SERVFAIL, replying with a resolved + query, sending a query to a nameserver. The functions can inspect the + available data and maybe change response/query related data (i.e. append + EDNS options). + - Updated Python module for the above. + - Updated Python documentation. + +5 December 2016: Ralph + - Fix #1173: differ local-zone type deny from unset + tag_actions element. + +5 December 2016: Wouter + - Fix #1170: document that 'inform' local-zone uses local-data. + +1 December 2016: Ralph + - hyphen as minus fix, by Andreas Schulze + +30 November 2016: Ralph + - Added local-zones and local-data bulk addition and removal + functionality in unbound-control (local_zones, local_zones_remove, + local_datas and local_datas_remove). + - iana portlist update + +29 November 2016: Wouter + - version 1.6.0 is in the development branch. + - braces in view.c around lock statements. + +28 November 2016: Wouter + - new install-sh. + +25 November 2016: Wouter + - Fix that with openssl 1.1 control-use-cert: no uses less cpu, by + using no encryption over the unix socket. + +22 Novenber 2016: Ralph + - Make access-control-tag-data RDATA absolute. This makes the RDATA + origin consistent between local-data and access-control-tag-data. + - Fix NSEC ENT wildcard check. Matching wildcard does not have to be a + subdomain of the NSEC owner. + - QNAME minimisation uses QTYPE=A, therefore always check cache for + this type in harden-below-nxdomain functionality. + - Added unit test for QNAME minimisation + harden below nxdomain + synergy. + +22 November 2016: Wouter + - iana portlist update. + - Fix unit tests for DS hash processing for fake-dsa test option. + - patch from Dag-Erling Smorgrav that removes code that relies + on sbrk(). + +21 November 2016: Wouter + - Fix #1158: reference RFC 8020 "NXDOMAIN: There Really Is Nothing + Underneath" for the harden-below-nxdomain option. + +10 November 2016: Ralph + - Fix #1155: test status code of unbound-control in 04-checkconf, + not the status code from the tee command. + +4 November 2016: Ralph + - Added stub-ssl-upstream and forward-ssl-upstream options. + +4 November 2016: Wouter + - configure detects ssl security level API function in the autoconf + manner. Every function on its own, so that other libraries (eg. + LibreSSL) can develop their API without hindrance. + - Fix #1154: segfault when reading config with duplicate zones. + - Note that for harden-below-nxdomain the nxdomain must be secure, + this means nsec3 with optout is insufficient. + +3 November 2016: Ralph + - Set OpenSSL security level to 0 when using aNULL ciphers. + +3 November 2016: Wouter + - .gitattributes line for githubs code language display. + - log-identity: config option to set sys log identity, patch from + "Robin H. Johnson" + +2 November 2016: Wouter + - iana portlist update. + +31 October 2016: Wouter + - Fix failure to build on arm64 with no sbrk. + - iana portlist update. + +28 October 2016: Wouter + - Patch for server.num.zero_ttl stats for count of expired replies, + from Pavel Odintsov. + +26 October 2016: Wouter + - Fix unit tests for openssl 1.1, with no DSA, by faking DSA, enabled + with the undocumented switch 'fake-dsa'. It logs a warning. + +25 October 2016: Wouter + - Fix #1134: unbound-control set_option -- val-override-date: -1 works + immediately to ignore datetime, or back to 0 to enable it again. + The -- is to ignore the '-1' as an option flag. + +24 October 2016: Wouter + - serve-expired config option: serve expired responses with TTL 0. + - g.root-servers.net has AAAA address. + +21 October 2016: Wouter + - Ported tests for local_cname unit test to testbound framework. + +20 October 2016: Wouter + - suppress compile warning in lex files. + - init lzt variable, for older gcc compiler warnings. + - fix --enable-dsa to work, instead of copying ecdsa enable. + - Fix DNSSEC validation of query type ANY with DNAME answers. + - Fixup query_info local_alias init. + +19 October 2016: Wouter + - Fix #1130: whitespace in example.conf.in more consistent. + +18 October 2016: Wouter + - Patch that resolves CNAMEs entered in local-data conf statements that + point to data on the internet, from Jinmei Tatuya (Infoblox). + - Removed patch comments from acllist.c and msgencode.c + - Added documentation doc/CNAME-basedRedirectionDesignNotes.pdf, + from Jinmei Tatuya (Infoblox). + - Fix #1125: unbound could reuse an answer packet incorrectly for + clients with different EDNS parameters, from Jinmei Tatuya. + - Fix #1118: libunbound.pc sets strange Libs, Libs.private values. + - Added Requires line to libunbound.pc + - Please doxygen by modifying mesh.h + +17 October 2016: Wouter + - Re-fix #839 from view commit overwrite. + - Fixup const void cast warning. + +12 October 2016: Ralph + - Free view config elements. + +11 October 2016: Ralph + - Added qname-minimisation-strict config option. + - iana portlist update. + - fix memoryleak logfile when in debug mode. + +5 October 2016: Ralph + - Added views functionality. + - Fix #1117: spelling errors, from Robert Edmonds. + +30 September 2016: Wouter + - Fix Nits for 1.5.10 reported by Dag-Erling Smorgrav. + +29 September 2016: Wouter + - Fix #838: 1.5.10 cannot be built on Solaris, undefined PATH_MAX. + - Fix #839: Memory grows unexpectedly with large RPZ files. + - Fix #840: infinite loop in unbound_munin_ plugin on unowned lockfile. + - Fix #841: big local-zone's make it consume large amounts of memory. + +27 September 2016: Wouter + - tag for 1.5.10 release + - trunk contains 1.5.11 in development. + - Fix dnstap relaying "random" messages instead of resolver/forwarder + responses, from Nikolay Edigaryev. + - Fix #836: unbound could echo back EDNS options in an error response. + 20 September 2016: Wouter - iana portlist update. - Fix #835: fix --disable-dsa with nettle verify. @@ -273,7 +2965,7 @@ compatibility with cisco dns guard. This lowers false positives. 18 April 2016: Wouter - - Fix some malformed reponses to edns queries get fallback to nonedns. + - Fix some malformed responses to edns queries get fallback to nonedns. 15 April 2016: Wouter - cachedb module event handling design. --- contrib/unbound/doc/README.orig +++ contrib/unbound/doc/README @@ -1,4 +1,4 @@ -README for Unbound 1.5.10 +README for Unbound 1.10.1 Copyright 2007 NLnet Labs http://unbound.net @@ -76,6 +76,8 @@ Disable support for RSASHA256 and RSASHA512 crypto. * --disable-gost Disable support for GOST crypto, RFC 5933. + * --enable-subnet + Enable EDNS client subnet processing. * 'make test' runs a series of self checks. @@ -97,7 +99,7 @@ the config file is an alternative. The interface-automatic option uses non portable socket options, Linux and FreeBSD should work fine. o The warning 'openssl has no entropy, seeding with time', with chroot - enabled, may be solved with a symbolic link to /dev/random from . + enabled, may be solved with a symbolic link to /dev/urandom from . o On Solaris 5.10 some libtool packages from repositories do not work with gcc, showing errors gcc: unrecognized option `-KPIC' To solve this do ./configure libtool=./libtool [your options...]. --- contrib/unbound/doc/README.ipset.md.orig +++ contrib/unbound/doc/README.ipset.md @@ -0,0 +1,65 @@ +## Created a module to support the ipset that could add the domain's ip to a list easily. + +### Purposes: +* In my case, I can't access the facebook, twitter, youtube and thousands web site for some reason. VPN is a solution. But the internet too slow whether all traffics pass through the vpn. +So, I set up a transparent proxy to proxy the traffic which has been blocked only. +At the final step, I need to install a dns service which would work with ipset well to launch the system. +I did some research for this. Unfortunately, Unbound, My favorite dns service doesn't support ipset yet. So, I decided to implement it by my self and contribute the patch. It's good for me and the community. +``` +# unbound.conf +server: + ... + local-zone: "facebook.com" ipset + local-zone: "twitter.com" ipset + local-zone: "instagram.com" ipset + more social website + +ipset: + name-v4: "gfwlist" +``` +``` +# iptables +iptables -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800 +iptables -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800 +``` + +* This patch could work with iptables rules to batch block the IPs. +``` +# unbound.conf +server: + ... + local-zone: "facebook.com" ipset + local-zone: "twitter.com" ipset + local-zone: "instagram.com" ipset + more social website + +ipset: + name-v4: "blacklist" + name-v6: "blacklist6" +``` +``` +# iptables +iptables -A INPUT -m set --set blacklist src -j DROP +ip6tables -A INPUT -m set --set blacklist6 src -j DROP +``` + +### Notes: +* To enable this module the root privileges is required. +* Please create a set with ipset command first. eg. **ipset -N blacklist iphash** + +### How to use: +``` +./configure --enable-ipset +make && make install +``` + +### Configuration: +``` +# unbound.conf +server: + ... + local-zone: "example.com" ipset + +ipset: + name-v4: "blacklist" +``` --- contrib/unbound/doc/TODO.orig +++ contrib/unbound/doc/TODO @@ -29,7 +29,7 @@ o add local-file: config with authority features. o (option) to make local-data answers be secure for libunbound (default=no) o (option) to make chroot: copy all needed files into jail (or make jail) - perhaps also print reminder to link /dev/random and sysloghack. + perhaps also print reminder to link /dev/urandom and sysloghack. o overhaul outside-network servicedquery to merge with udpwait and tcpwait, to make timers in servicedquery independent of udpwait queues. o check into rebinding ports for efficiency, configure time test. --- contrib/unbound/doc/example.conf.orig +++ contrib/unbound/doc/example.conf @@ -1,7 +1,7 @@ # # Example configuration file. # -# See unbound.conf(5) man page, version 1.5.10. +# See unbound.conf(5) man page, version 1.9.2. # # this is a comment. @@ -19,6 +19,14 @@ # Set to "" or 0 to disable. Default is disabled. # statistics-interval: 0 + # enable shm for stats, default no. if you enable also enable + # statistics-interval, every time it also writes stats to the + # shared memory segment keyed with shm-key. + # shm-enable: no + + # shm for stats uses this key, and key+1 for the shared mem segment. + # shm-key: 11777 + # enable cumulative statistics, without clearing them after printing. # statistics-cumulative: no @@ -52,7 +60,7 @@ # outgoing-interface: 192.0.2.153 # outgoing-interface: 2001:DB8::5 # outgoing-interface: 2001:DB8::6 - + # Specify a netblock to use remainder 64 bits as random bits for # upstream queries. Uses freebind option (Linux). # outgoing-interface: 2001:DB8::/64 @@ -95,7 +103,8 @@ # so-sndbuf: 0 # use SO_REUSEPORT to distribute queries over threads. - # so-reuseport: no + # at extreme load it could be better to turn it off to distribute even. + # so-reuseport: yes # use IP_TRANSPARENT so the interface: addresses can be non-local # and you can config non-existing IPs that are going to work later on @@ -108,7 +117,7 @@ # ip-freebind: no # EDNS reassembly buffer to advertise to UDP peers (the actual buffer - # is set with msg-buffer-size). 1480 can solve fragmentation (timeouts). + # is set with msg-buffer-size). 1472 can solve fragmentation (timeouts) # edns-buffer-size: 4096 # Maximum UDP response size (not applied to TCP response). @@ -115,6 +124,9 @@ # Suggested values are 512 to 4096. Default is 4096. 65536 disables it. # max-udp-size: 4096 + # max memory to use for stream(tcp and tls) waiting result buffers. + # stream-wait-size: 4m + # buffer size for handling DNS data. No messages larger than this # size can be sent or received, by UDP or TCP. In bytes. # msg-buffer-size: 65552 @@ -137,6 +149,10 @@ # msec to wait before close of port on timeout UDP. 0 disables. # delay-close: 0 + # msec for waiting for an unknown server to reply. Increase if you + # are behind a slow satellite link, to eg. 1128. + # unknown-server-time-limit: 376 + # the amount of memory to use for the RRset cache. # plain value in bytes or you can append k, m or G. default is "4Mb". # rrset-cache-size: 4m @@ -171,7 +187,7 @@ # the maximum number of hosts that are cached (roundtrip, EDNS, lame). # infra-cache-numhosts: 10000 - + # define a number of tags here, use with local-zone, access-control. # repeat the define-tag statement to add additional tags. # define-tag: "tag1 tag2 tag3" @@ -192,6 +208,10 @@ # useful for tunneling scenarios, default no. # tcp-upstream: no + # upstream connections also use UDP (even if do-udp is no). + # useful if if you want UDP upstream, but don't provide UDP downstream. + # udp-upstream-without-downstream: no + # Maximum segment size (MSS) of TCP socket on which the server # responds to queries. Default is 0, system default MSS. # tcp-mss: 0 @@ -200,7 +220,20 @@ # Default is 0, system default MSS. # outgoing-tcp-mss: 0 + # Idle TCP timeout, connection closed in milliseconds + # tcp-idle-timeout: 30000 + + # Enable EDNS TCP keepalive option. + # edns-tcp-keepalive: no + + # Timeout for EDNS TCP keepalive, in msec. + # edns-tcp-keepalive-timeout: 120000 + + # Use systemd socket activation for UDP, TCP, and control sockets. + # use-systemd: no + # Detach from the terminal, run in background, "yes" or "no". + # Set the value to "no" when unbound runs as systemd service. # do-daemonize: yes # control which clients are allowed to make (recursive) queries @@ -207,7 +240,8 @@ # to this server. Specify classless netblocks with /size and action. # By default everything is refused, except for localhost. # Choose deny (drop message), refuse (polite error reply), - # allow (recursive ok), allow_snoop (recursive and nonrecursive ok) + # allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on), + # allow_snoop (recursive and nonrecursive ok) # deny_non_local (drop queries unless can be answered from local-data) # refuse_non_local (like deny_non_local but polite error reply). # access-control: 0.0.0.0/0 refuse @@ -230,6 +264,9 @@ # set redirect data for particular tag for access control element # access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1" + # Set view for access control element + # access-control-view: 192.0.2.0/24 viewname + # if given, a chroot(2) is done to the given directory. # i.e. you can chroot to the working directory, for example, # for extra security, but make sure all files are in that directory. @@ -272,9 +309,13 @@ # logfile: "" # Log to syslog(3) if yes. The log facility LOG_DAEMON is used to - # log to, with identity "unbound". If yes, it overrides the logfile. + # log to. If yes, it overrides the logfile. # use-syslog: yes + # Log identity to report. if empty, defaults to the name of argv[0] + # (usually "unbound"). + # log-identity: "" + # print UTC timestamp in ascii to logfile, default is epoch in seconds. # log-time-ascii: no @@ -281,6 +322,21 @@ # print one line with time, IP, name, type, class for every query. # log-queries: no + # print one line per reply, with time, IP, name, type, class, rcode, + # timetoresolve, fromcache and responsesize. + # log-replies: no + + # log with tag 'query' and 'reply' instead of 'info' for + # filtering log-queries and log-replies from the log. + # log-tag-queryreply: no + + # log the local-zone actions, like local-zone type inform is enabled + # also for the other local zone types. + # log-local-actions: no + + # print log lines that say why queries return SERVFAIL to clients. + # log-servfail: no + # the pid file. Can be an absolute path outside of chroot/work dir. # pidfile: "/var/unbound/unbound.pid" @@ -294,6 +350,9 @@ # enable to not answer version.server and version.bind queries. # hide-version: no + # enable to not answer trustanchor.unbound queries. + # hide-trustanchor: no + # the identity to report. Leave "" or default to return hostname. # identity: "" @@ -326,9 +385,9 @@ # harden-dnssec-stripped: yes # Harden against queries that fall under dnssec-signed nxdomain names. - # harden-below-nxdomain: no + # harden-below-nxdomain: yes - # Harden the referral path by performing additional queries for + # Harden the referral path by performing additional queries for # infrastructure data. Validates the replies (if possible). # Default off, because the lookups burden the server. Experimental # implementation of draft-wijngaards-dnsext-resolver-side-mitigation. @@ -341,9 +400,19 @@ # Sent minimum amount of information to upstream servers to enhance # privacy. Only sent minimum required labels of the QNAME and set QTYPE - # to NS when possible. - # qname-minimisation: no + # to A when possible. + # qname-minimisation: yes + # QNAME minimisation in strict mode. Do not fall-back to sending full + # QNAME to potentially broken nameservers. A lot of domains will not be + # resolvable when this option in enabled. + # This option only has effect when qname-minimisation is enabled. + # qname-minimisation-strict: no + + # Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN + # and other denials, using information from previous NXDOMAINs answers. + # aggressive-nsec: no + # Use 0x20-encoded random bits in the query to foil spoof attempts. # This feature is an experimental implementation of draft dns-0x20. # use-caps-for-id: no @@ -392,12 +461,15 @@ # if yes, perform key lookups adjacent to normal lookups. # prefetch-key: no + # deny queries of type ANY with an empty response. + # deny-any: no + # if yes, Unbound rotates RRSet order in response. # rrset-roundrobin: no # if yes, Unbound doesn't insert authority/additional sections # into response messages when those sections are not required. - # minimal-responses: no + # minimal-responses: yes # true to disable DNSSEC lameness check in iterator. # disable-dnssec-lame-check: no @@ -404,6 +476,9 @@ # module configuration of the server. A string with identifiers # separated by spaces. Syntax: "[dns64] [validator] iterator" + # most modules have to be listed at the beginning of the line, + # except cachedb(just before iterator), and python (at the beginning, + # or, just before the iterator). # module-config: "validator iterator" # File with trusted keys, kept uptodate using RFC5011 probes, @@ -416,6 +491,12 @@ # and under the terms of our LICENSE (see that file in the source). # auto-trust-anchor-file: "/var/unbound/root.key" + # trust anchor signaling sends a RFC8145 key tag query after priming. + # trust-anchor-signaling: yes + + # Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel) + # root-key-sentinel: yes + # File with DLV trusted keys. Same format as trust-anchor-file. # There can be only one DLV configured, it is trusted from root down. # DLV is going to be decommissioned. Please do not use it any more. @@ -477,6 +558,20 @@ # that set CD but cannot validate themselves. # ignore-cd-flag: no + # Serve expired responses from cache, with TTL 0 in the response, + # and then attempt to fetch the data afresh. + # serve-expired: no + # + # Limit serving of expired responses to configured seconds after + # expiration. 0 disables the limit. + # serve-expired-ttl: 0 + # + # Set the TTL of expired records to the serve-expired-ttl value after a + # failed attempt to retrieve the record from upstream. This makes sure + # that the expired records will be served as long as there are queries + # for it. + # serve-expired-ttl-reset: no + # Have the validator log failed validations for your diagnosis. # 0: off. 1: A line per failed user query. 2: With reason and bad IP. # val-log-level: 0 @@ -524,6 +619,8 @@ # local-zone: "127.in-addr.arpa." nodefault # local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault # local-zone: "onion." nodefault + # local-zone: "test." nodefault + # local-zone: "invalid." nodefault # local-zone: "10.in-addr.arpa." nodefault # local-zone: "16.172.in-addr.arpa." nodefault # local-zone: "17.172.in-addr.arpa." nodefault @@ -578,10 +675,12 @@ # o redirect serves the zone data for any subdomain in the zone. # o nodefault can be used to normally resolve AS112 zones. # o typetransparent resolves normally for other types and other names - # o inform resolves normally, but logs client IP address + # o inform acts like transparent, but logs client IP address # o inform_deny drops queries and logs client IP address + # o inform_redirect redirects queries and logs client IP address # o always_transparent, always_refuse, always_nxdomain, resolve in - # that way but ignore local data for that name. + # that way but ignore local data for that name + # o noview breaks out of that view towards global local-zones. # # defaults are localhost address, reverse for 127.0.0.1 and ::1 # and nxdomain for AS112 zones. If you configure one of these zones @@ -614,21 +713,46 @@ # add a netblock specific override to a localzone, with zone type # local-zone-override: "example.com" 192.0.2.0/24 refuse - # service clients over SSL (on the TCP sockets), with plain DNS inside - # the SSL stream. Give the certificate to use and private key. + # service clients over TLS (on the TCP sockets), with plain DNS inside + # the TLS stream. Give the certificate to use and private key. # default is "" (disabled). requires restart to take effect. - # ssl-service-key: "path/to/privatekeyfile.key" - # ssl-service-pem: "path/to/publiccertfile.pem" - # ssl-port: 853 + # tls-service-key: "path/to/privatekeyfile.key" + # tls-service-pem: "path/to/publiccertfile.pem" + # tls-port: 853 - # request upstream over SSL (with plain DNS inside the SSL stream). + # cipher setting for TLSv1.2 + # tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256" + # cipher setting for TLSv1.3 + # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" + + # Add the secret file for TLS Session Ticket. + # Secret file must be 80 bytes of random data. + # First key use to encrypt and decrypt TLS session tickets. + # Other keys use to decrypt only. + # requires restart to take effect. + # tls-session-ticket-keys: "path/to/secret_file1" + # tls-session-ticket-keys: "path/to/secret_file2" + + # request upstream over TLS (with plain DNS inside the TLS stream). # Default is no. Can be turned on and off with unbound-control. - # ssl-upstream: no + # tls-upstream: no + # Certificates used to authenticate connections made upstream. + # tls-cert-bundle: "" + + # Add system certs to the cert bundle, from the Windows Cert Store + # tls-win-cert: no + + # Also serve tls on these port numbers (eg. 443, ...), by listing + # tls-additional-port: portno for each of the port numbers. + # DNS64 prefix. Must be specified when DNS64 is use. # Enable dns64 in module-config. Used to synthesize IPv6 from IPv4. # dns64-prefix: 64:ff9b::0/96 + # DNS64 ignore AAAA records for these domains and use A instead. + # dns64-ignore-aaaa: "example.com" + # ratelimit for uncached, new queries, this limits recursion effort. # ratelimiting is experimental, and may help against randomqueryflood. # if 0(default) it is disabled, otherwise state qps allowed per zone. @@ -649,9 +773,62 @@ # can give this multiple times, the name closest to the zone is used. # ratelimit-below-domain: com 1000 + # global query ratelimit for all ip addresses. + # feature is experimental. + # if 0(default) it is disabled, otherwise states qps allowed per ip address + # ip-ratelimit: 0 + + # ip ratelimits are tracked in a cache, size in bytes of cache (or k,m). + # ip-ratelimit-size: 4m + # ip ratelimit cache slabs, reduces lock contention if equal to cpucount. + # ip-ratelimit-slabs: 4 + + # 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through + # ip-ratelimit-factor: 10 + + # Limit the number of connections simultaneous from a netblock + # tcp-connection-limit: 192.0.2.0/24 12 + + # select from the fastest servers this many times out of 1000. 0 means + # the fast server select is disabled. prefetches are not sped up. + # fast-server-permil: 0 + # the number of servers that will be used in the fast server selection. + # fast-server-num: 3 + + # Specific options for ipsecmod. unbound needs to be configured with + # --enable-ipsecmod for these to take effect. + # + # Enable or disable ipsecmod (it still needs to be defined in + # module-config above). Can be used when ipsecmod needs to be + # enabled/disabled via remote-control(below). + # ipsecmod-enabled: yes + # + # Path to executable external hook. It must be defined when ipsecmod is + # listed in module-config (above). + # ipsecmod-hook: "./my_executable" + # + # When enabled unbound will reply with SERVFAIL if the return value of + # the ipsecmod-hook is not 0. + # ipsecmod-strict: no + # + # Maximum time to live (TTL) for cached A/AAAA records with IPSECKEY. + # ipsecmod-max-ttl: 3600 + # + # Reply with A/AAAA even if the relevant IPSECKEY is bogus. Mainly used for + # testing. + # ipsecmod-ignore-bogus: no + # + # Domains for which ipsecmod will be triggered. If not defined (default) + # all domains are treated as being whitelisted. + # ipsecmod-whitelist: "example.com" + # ipsecmod-whitelist: "nlnetlabs.nl" + + # Python config section. To enable: # o use --with-pythonmodule to configure before compiling. # o list python in the module-config string (above) to enable. +# It can be at the start, it gets validated results, or just before +# the iterator and process before DNSSEC validation. # o and give a python-script to run. python: # Script file to load @@ -663,12 +840,10 @@ # set up the keys and certificates with unbound-control-setup. # control-enable: no - # Set to no and use an absolute path as control-interface to use - # a unix local named pipe for unbound-control. - # control-use-cert: yes - # what interfaces are listened to for remote control. # give 0.0.0.0 and ::0 to listen to all interfaces. + # set to an absolute path to use a unix local name pipe, certificates + # are not used for that, so key and cert files need not be present. # control-interface: 127.0.0.1 # control-interface: ::1 @@ -675,6 +850,10 @@ # port number for remote control operations. # control-port: 8953 + # for localhost, you can disable use of TLS by setting this to "no" + # For local sockets this option is ignored, and TLS is not used. + # control-use-cert: "yes" + # unbound server key file. # server-key-file: "/var/unbound/unbound_server.key" @@ -700,6 +879,8 @@ # stub-addr: 192.0.2.68 # stub-prime: no # stub-first: no +# stub-tls-upstream: no +# stub-no-cache: no # stub-zone: # name: "example.org" # stub-host: ns.example.com. @@ -715,6 +896,99 @@ # forward-addr: 192.0.2.68 # forward-addr: 192.0.2.73@5355 # forward to port 5355. # forward-first: no +# forward-tls-upstream: no +# forward-no-cache: no # forward-zone: # name: "example.org" # forward-host: fwd.example.com + +# Authority zones +# The data for these zones is kept locally, from a file or downloaded. +# The data can be served to downstream clients, or used instead of the +# upstream (which saves a lookup to the upstream). The first example +# has a copy of the root for local usage. The second serves example.org +# authoritatively. zonefile: reads from file (and writes to it if you also +# download it), master: fetches with AXFR and IXFR, or url to zonefile. +# With allow-notify: you can give additional (apart from masters) sources of +# notifies. +# auth-zone: +# name: "." +# master: 199.9.14.201 # b.root-servers.net +# master: 192.33.4.12 # c.root-servers.net +# master: 199.7.91.13 # d.root-servers.net +# master: 192.5.5.241 # f.root-servers.net +# master: 192.112.36.4 # g.root-servers.net +# master: 193.0.14.129 # k.root-servers.net +# master: 192.0.47.132 # xfr.cjr.dns.icann.org +# master: 192.0.32.132 # xfr.lax.dns.icann.org +# master: 2001:500:200::b # b.root-servers.net +# master: 2001:500:2::c # c.root-servers.net +# master: 2001:500:2d::d # d.root-servers.net +# master: 2001:500:2f::f # f.root-servers.net +# master: 2001:500:12::d0d # g.root-servers.net +# master: 2001:7fd::1 # k.root-servers.net +# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org +# master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org +# fallback-enabled: yes +# for-downstream: no +# for-upstream: yes +# auth-zone: +# name: "example.org" +# for-downstream: yes +# for-upstream: yes +# zonefile: "example.org.zone" + +# Views +# Create named views. Name must be unique. Map views to requests using +# the access-control-view option. Views can contain zero or more local-zone +# and local-data options. Options from matching views will override global +# options. Global options will be used if no matching view is found. +# With view-first yes, it will try to answer using the global local-zone and +# local-data elements if there is no view specific match. +# view: +# name: "viewname" +# local-zone: "example.com" redirect +# local-data: "example.com A 192.0.2.3" +# local-data-ptr: "192.0.2.3 www.example.com" +# view-first: no +# view: +# name: "anotherview" +# local-zone: "example.com" refuse + +# DNSCrypt +# Caveats: +# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper +# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage +# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to +# listen on `dnscrypt-port` with the follo0wing snippet: +# server: +# interface: 0.0.0.0@443 +# interface: ::0@443 +# +# Finally, `dnscrypt` config has its own section. +# dnscrypt: +# dnscrypt-enable: yes +# dnscrypt-port: 443 +# dnscrypt-provider: 2.dnscrypt-cert.example.com. +# dnscrypt-secret-key: /path/unbound-conf/keys1/1.key +# dnscrypt-secret-key: /path/unbound-conf/keys2/1.key +# dnscrypt-provider-cert: /path/unbound-conf/keys1/1.cert +# dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert + +# CacheDB +# Enable external backend DB as auxiliary cache. Specify the backend name +# (default is "testframe", which has no use other than for debugging and +# testing) and backend-specific options. The 'cachedb' module must be +# included in module-config, just before the iterator module. +# cachedb: +# backend: "testframe" +# # secret seed string to calculate hashed keys +# secret-seed: "default" +# +# # For "redis" backend: +# # redis server's IP address or host name +# redis-server-host: 127.0.0.1 +# # redis server's TCP port +# redis-server-port: 6379 +# # timeout (in ms) for communication with the redis server +# redis-timeout: 100 --- contrib/unbound/doc/example.conf.in.orig +++ contrib/unbound/doc/example.conf.in @@ -1,7 +1,7 @@ # # Example configuration file. # -# See unbound.conf(5) man page, version 1.5.10. +# See unbound.conf(5) man page, version 1.10.1. # # this is a comment. @@ -19,6 +19,14 @@ # Set to "" or 0 to disable. Default is disabled. # statistics-interval: 0 + # enable shm for stats, default no. if you enable also enable + # statistics-interval, every time it also writes stats to the + # shared memory segment keyed with shm-key. + # shm-enable: no + + # shm for stats uses this key, and key+1 for the shared mem segment. + # shm-key: 11777 + # enable cumulative statistics, without clearing them after printing. # statistics-cumulative: no @@ -52,7 +60,7 @@ # outgoing-interface: 192.0.2.153 # outgoing-interface: 2001:DB8::5 # outgoing-interface: 2001:DB8::6 - + # Specify a netblock to use remainder 64 bits as random bits for # upstream queries. Uses freebind option (Linux). # outgoing-interface: 2001:DB8::/64 @@ -95,7 +103,8 @@ # so-sndbuf: 0 # use SO_REUSEPORT to distribute queries over threads. - # so-reuseport: no + # at extreme load it could be better to turn it off to distribute even. + # so-reuseport: yes # use IP_TRANSPARENT so the interface: addresses can be non-local # and you can config non-existing IPs that are going to work later on @@ -108,7 +117,7 @@ # ip-freebind: no # EDNS reassembly buffer to advertise to UDP peers (the actual buffer - # is set with msg-buffer-size). 1480 can solve fragmentation (timeouts). + # is set with msg-buffer-size). 1472 can solve fragmentation (timeouts) # edns-buffer-size: 4096 # Maximum UDP response size (not applied to TCP response). @@ -115,6 +124,9 @@ # Suggested values are 512 to 4096. Default is 4096. 65536 disables it. # max-udp-size: 4096 + # max memory to use for stream(tcp and tls) waiting result buffers. + # stream-wait-size: 4m + # buffer size for handling DNS data. No messages larger than this # size can be sent or received, by UDP or TCP. In bytes. # msg-buffer-size: 65552 @@ -137,6 +149,10 @@ # msec to wait before close of port on timeout UDP. 0 disables. # delay-close: 0 + # msec for waiting for an unknown server to reply. Increase if you + # are behind a slow satellite link, to eg. 1128. + # unknown-server-time-limit: 376 + # the amount of memory to use for the RRset cache. # plain value in bytes or you can append k, m or G. default is "4Mb". # rrset-cache-size: 4m @@ -171,7 +187,7 @@ # the maximum number of hosts that are cached (roundtrip, EDNS, lame). # infra-cache-numhosts: 10000 - + # define a number of tags here, use with local-zone, access-control. # repeat the define-tag statement to add additional tags. # define-tag: "tag1 tag2 tag3" @@ -192,6 +208,10 @@ # useful for tunneling scenarios, default no. # tcp-upstream: no + # upstream connections also use UDP (even if do-udp is no). + # useful if if you want UDP upstream, but don't provide UDP downstream. + # udp-upstream-without-downstream: no + # Maximum segment size (MSS) of TCP socket on which the server # responds to queries. Default is 0, system default MSS. # tcp-mss: 0 @@ -200,7 +220,20 @@ # Default is 0, system default MSS. # outgoing-tcp-mss: 0 + # Idle TCP timeout, connection closed in milliseconds + # tcp-idle-timeout: 30000 + + # Enable EDNS TCP keepalive option. + # edns-tcp-keepalive: no + + # Timeout for EDNS TCP keepalive, in msec. + # edns-tcp-keepalive-timeout: 120000 + + # Use systemd socket activation for UDP, TCP, and control sockets. + # use-systemd: no + # Detach from the terminal, run in background, "yes" or "no". + # Set the value to "no" when unbound runs as systemd service. # do-daemonize: yes # control which clients are allowed to make (recursive) queries @@ -207,7 +240,8 @@ # to this server. Specify classless netblocks with /size and action. # By default everything is refused, except for localhost. # Choose deny (drop message), refuse (polite error reply), - # allow (recursive ok), allow_snoop (recursive and nonrecursive ok) + # allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on), + # allow_snoop (recursive and nonrecursive ok) # deny_non_local (drop queries unless can be answered from local-data) # refuse_non_local (like deny_non_local but polite error reply). # access-control: 0.0.0.0/0 refuse @@ -230,6 +264,9 @@ # set redirect data for particular tag for access control element # access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1" + # Set view for access control element + # access-control-view: 192.0.2.0/24 viewname + # if given, a chroot(2) is done to the given directory. # i.e. you can chroot to the working directory, for example, # for extra security, but make sure all files are in that directory. @@ -249,7 +286,7 @@ # The pid file can be absolute and outside of the chroot, it is # written just prior to performing the chroot and dropping permissions. # - # Additionally, unbound may need to access /dev/random (for entropy). + # Additionally, unbound may need to access /dev/urandom (for entropy). # How to do this is specific to your OS. # # If you give "" no chroot is performed. The path must not end in a /. @@ -272,9 +309,13 @@ # logfile: "" # Log to syslog(3) if yes. The log facility LOG_DAEMON is used to - # log to, with identity "unbound". If yes, it overrides the logfile. + # log to. If yes, it overrides the logfile. # use-syslog: yes + # Log identity to report. if empty, defaults to the name of argv[0] + # (usually "unbound"). + # log-identity: "" + # print UTC timestamp in ascii to logfile, default is epoch in seconds. # log-time-ascii: no @@ -281,6 +322,21 @@ # print one line with time, IP, name, type, class for every query. # log-queries: no + # print one line per reply, with time, IP, name, type, class, rcode, + # timetoresolve, fromcache and responsesize. + # log-replies: no + + # log with tag 'query' and 'reply' instead of 'info' for + # filtering log-queries and log-replies from the log. + # log-tag-queryreply: no + + # log the local-zone actions, like local-zone type inform is enabled + # also for the other local zone types. + # log-local-actions: no + + # print log lines that say why queries return SERVFAIL to clients. + # log-servfail: no + # the pid file. Can be an absolute path outside of chroot/work dir. # pidfile: "@UNBOUND_PIDFILE@" @@ -294,6 +350,9 @@ # enable to not answer version.server and version.bind queries. # hide-version: no + # enable to not answer trustanchor.unbound queries. + # hide-trustanchor: no + # the identity to report. Leave "" or default to return hostname. # identity: "" @@ -326,9 +385,9 @@ # harden-dnssec-stripped: yes # Harden against queries that fall under dnssec-signed nxdomain names. - # harden-below-nxdomain: no + # harden-below-nxdomain: yes - # Harden the referral path by performing additional queries for + # Harden the referral path by performing additional queries for # infrastructure data. Validates the replies (if possible). # Default off, because the lookups burden the server. Experimental # implementation of draft-wijngaards-dnsext-resolver-side-mitigation. @@ -341,9 +400,19 @@ # Sent minimum amount of information to upstream servers to enhance # privacy. Only sent minimum required labels of the QNAME and set QTYPE - # to NS when possible. - # qname-minimisation: no + # to A when possible. + # qname-minimisation: yes + # QNAME minimisation in strict mode. Do not fall-back to sending full + # QNAME to potentially broken nameservers. A lot of domains will not be + # resolvable when this option in enabled. + # This option only has effect when qname-minimisation is enabled. + # qname-minimisation-strict: no + + # Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN + # and other denials, using information from previous NXDOMAINs answers. + # aggressive-nsec: no + # Use 0x20-encoded random bits in the query to foil spoof attempts. # This feature is an experimental implementation of draft dns-0x20. # use-caps-for-id: no @@ -392,12 +461,15 @@ # if yes, perform key lookups adjacent to normal lookups. # prefetch-key: no + # deny queries of type ANY with an empty response. + # deny-any: no + # if yes, Unbound rotates RRSet order in response. # rrset-roundrobin: no # if yes, Unbound doesn't insert authority/additional sections # into response messages when those sections are not required. - # minimal-responses: no + # minimal-responses: yes # true to disable DNSSEC lameness check in iterator. # disable-dnssec-lame-check: no @@ -404,6 +476,9 @@ # module configuration of the server. A string with identifiers # separated by spaces. Syntax: "[dns64] [validator] iterator" + # most modules have to be listed at the beginning of the line, + # except cachedb(just before iterator), and python (at the beginning, + # or, just before the iterator). # module-config: "validator iterator" # File with trusted keys, kept uptodate using RFC5011 probes, @@ -416,6 +491,12 @@ # and under the terms of our LICENSE (see that file in the source). # auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@" + # trust anchor signaling sends a RFC8145 key tag query after priming. + # trust-anchor-signaling: yes + + # Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel) + # root-key-sentinel: yes + # File with DLV trusted keys. Same format as trust-anchor-file. # There can be only one DLV configured, it is trusted from root down. # DLV is going to be decommissioned. Please do not use it any more. @@ -477,6 +558,30 @@ # that set CD but cannot validate themselves. # ignore-cd-flag: no + # Serve expired responses from cache, with serve-expired-reply-ttl in + # the response, and then attempt to fetch the data afresh. + # serve-expired: no + # + # Limit serving of expired responses to configured seconds after + # expiration. 0 disables the limit. + # serve-expired-ttl: 0 + # + # Set the TTL of expired records to the serve-expired-ttl value after a + # failed attempt to retrieve the record from upstream. This makes sure + # that the expired records will be served as long as there are queries + # for it. + # serve-expired-ttl-reset: no + # + # TTL value to use when replying with expired data. + # serve-expired-reply-ttl: 30 + # + # Time in milliseconds before replying to the client with expired data. + # This essentially enables the serve-stale behavior as specified in + # draft-ietf-dnsop-serve-stale-10 that first tries to resolve before + # immediately responding with expired data. 0 disables this behavior. + # A recommended value is 1800. + # serve-expired-client-timeout: 0 + # Have the validator log failed validations for your diagnosis. # 0: off. 1: A line per failed user query. 2: With reason and bad IP. # val-log-level: 0 @@ -524,6 +629,8 @@ # local-zone: "127.in-addr.arpa." nodefault # local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault # local-zone: "onion." nodefault + # local-zone: "test." nodefault + # local-zone: "invalid." nodefault # local-zone: "10.in-addr.arpa." nodefault # local-zone: "16.172.in-addr.arpa." nodefault # local-zone: "17.172.in-addr.arpa." nodefault @@ -557,6 +664,9 @@ # local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault # And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa. + # Add example.com into ipset + # local-zone: "example.com" ipset + # If unbound is running service for the local host then it is useful # to perform lan-wide lookups to the upstream, and unblock the # long list of local-zones above. If this unbound is a dns server @@ -578,10 +688,12 @@ # o redirect serves the zone data for any subdomain in the zone. # o nodefault can be used to normally resolve AS112 zones. # o typetransparent resolves normally for other types and other names - # o inform resolves normally, but logs client IP address + # o inform acts like transparent, but logs client IP address # o inform_deny drops queries and logs client IP address + # o inform_redirect redirects queries and logs client IP address # o always_transparent, always_refuse, always_nxdomain, resolve in - # that way but ignore local data for that name. + # that way but ignore local data for that name + # o noview breaks out of that view towards global local-zones. # # defaults are localhost address, reverse for 127.0.0.1 and ::1 # and nxdomain for AS112 zones. If you configure one of these zones @@ -614,21 +726,46 @@ # add a netblock specific override to a localzone, with zone type # local-zone-override: "example.com" 192.0.2.0/24 refuse - # service clients over SSL (on the TCP sockets), with plain DNS inside - # the SSL stream. Give the certificate to use and private key. + # service clients over TLS (on the TCP sockets), with plain DNS inside + # the TLS stream. Give the certificate to use and private key. # default is "" (disabled). requires restart to take effect. - # ssl-service-key: "path/to/privatekeyfile.key" - # ssl-service-pem: "path/to/publiccertfile.pem" - # ssl-port: 853 + # tls-service-key: "path/to/privatekeyfile.key" + # tls-service-pem: "path/to/publiccertfile.pem" + # tls-port: 853 - # request upstream over SSL (with plain DNS inside the SSL stream). + # cipher setting for TLSv1.2 + # tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256" + # cipher setting for TLSv1.3 + # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" + + # Add the secret file for TLS Session Ticket. + # Secret file must be 80 bytes of random data. + # First key use to encrypt and decrypt TLS session tickets. + # Other keys use to decrypt only. + # requires restart to take effect. + # tls-session-ticket-keys: "path/to/secret_file1" + # tls-session-ticket-keys: "path/to/secret_file2" + + # request upstream over TLS (with plain DNS inside the TLS stream). # Default is no. Can be turned on and off with unbound-control. - # ssl-upstream: no + # tls-upstream: no + # Certificates used to authenticate connections made upstream. + # tls-cert-bundle: "" + + # Add system certs to the cert bundle, from the Windows Cert Store + # tls-win-cert: no + + # Also serve tls on these port numbers (eg. 443, ...), by listing + # tls-additional-port: portno for each of the port numbers. + # DNS64 prefix. Must be specified when DNS64 is use. # Enable dns64 in module-config. Used to synthesize IPv6 from IPv4. # dns64-prefix: 64:ff9b::0/96 + # DNS64 ignore AAAA records for these domains and use A instead. + # dns64-ignore-aaaa: "example.com" + # ratelimit for uncached, new queries, this limits recursion effort. # ratelimiting is experimental, and may help against randomqueryflood. # if 0(default) it is disabled, otherwise state qps allowed per zone. @@ -649,9 +786,62 @@ # can give this multiple times, the name closest to the zone is used. # ratelimit-below-domain: com 1000 + # global query ratelimit for all ip addresses. + # feature is experimental. + # if 0(default) it is disabled, otherwise states qps allowed per ip address + # ip-ratelimit: 0 + + # ip ratelimits are tracked in a cache, size in bytes of cache (or k,m). + # ip-ratelimit-size: 4m + # ip ratelimit cache slabs, reduces lock contention if equal to cpucount. + # ip-ratelimit-slabs: 4 + + # 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through + # ip-ratelimit-factor: 10 + + # Limit the number of connections simultaneous from a netblock + # tcp-connection-limit: 192.0.2.0/24 12 + + # select from the fastest servers this many times out of 1000. 0 means + # the fast server select is disabled. prefetches are not sped up. + # fast-server-permil: 0 + # the number of servers that will be used in the fast server selection. + # fast-server-num: 3 + + # Specific options for ipsecmod. unbound needs to be configured with + # --enable-ipsecmod for these to take effect. + # + # Enable or disable ipsecmod (it still needs to be defined in + # module-config above). Can be used when ipsecmod needs to be + # enabled/disabled via remote-control(below). + # ipsecmod-enabled: yes + # + # Path to executable external hook. It must be defined when ipsecmod is + # listed in module-config (above). + # ipsecmod-hook: "./my_executable" + # + # When enabled unbound will reply with SERVFAIL if the return value of + # the ipsecmod-hook is not 0. + # ipsecmod-strict: no + # + # Maximum time to live (TTL) for cached A/AAAA records with IPSECKEY. + # ipsecmod-max-ttl: 3600 + # + # Reply with A/AAAA even if the relevant IPSECKEY is bogus. Mainly used for + # testing. + # ipsecmod-ignore-bogus: no + # + # Domains for which ipsecmod will be triggered. If not defined (default) + # all domains are treated as being whitelisted. + # ipsecmod-whitelist: "example.com" + # ipsecmod-whitelist: "nlnetlabs.nl" + + # Python config section. To enable: # o use --with-pythonmodule to configure before compiling. # o list python in the module-config string (above) to enable. +# It can be at the start, it gets validated results, or just before +# the iterator and process before DNSSEC validation. # o and give a python-script to run. python: # Script file to load @@ -663,12 +853,10 @@ # set up the keys and certificates with unbound-control-setup. # control-enable: no - # Set to no and use an absolute path as control-interface to use - # a unix local named pipe for unbound-control. - # control-use-cert: yes - # what interfaces are listened to for remote control. # give 0.0.0.0 and ::0 to listen to all interfaces. + # set to an absolute path to use a unix local name pipe, certificates + # are not used for that, so key and cert files need not be present. # control-interface: 127.0.0.1 # control-interface: ::1 @@ -675,6 +863,10 @@ # port number for remote control operations. # control-port: 8953 + # for localhost, you can disable use of TLS by setting this to "no" + # For local sockets this option is ignored, and TLS is not used. + # control-use-cert: "yes" + # unbound server key file. # server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key" @@ -700,6 +892,8 @@ # stub-addr: 192.0.2.68 # stub-prime: no # stub-first: no +# stub-tls-upstream: no +# stub-no-cache: no # stub-zone: # name: "example.org" # stub-host: ns.example.com. @@ -715,6 +909,127 @@ # forward-addr: 192.0.2.68 # forward-addr: 192.0.2.73@5355 # forward to port 5355. # forward-first: no +# forward-tls-upstream: no +# forward-no-cache: no # forward-zone: # name: "example.org" # forward-host: fwd.example.com + +# Authority zones +# The data for these zones is kept locally, from a file or downloaded. +# The data can be served to downstream clients, or used instead of the +# upstream (which saves a lookup to the upstream). The first example +# has a copy of the root for local usage. The second serves example.org +# authoritatively. zonefile: reads from file (and writes to it if you also +# download it), master: fetches with AXFR and IXFR, or url to zonefile. +# With allow-notify: you can give additional (apart from masters) sources of +# notifies. +# auth-zone: +# name: "." +# master: 199.9.14.201 # b.root-servers.net +# master: 192.33.4.12 # c.root-servers.net +# master: 199.7.91.13 # d.root-servers.net +# master: 192.5.5.241 # f.root-servers.net +# master: 192.112.36.4 # g.root-servers.net +# master: 193.0.14.129 # k.root-servers.net +# master: 192.0.47.132 # xfr.cjr.dns.icann.org +# master: 192.0.32.132 # xfr.lax.dns.icann.org +# master: 2001:500:200::b # b.root-servers.net +# master: 2001:500:2::c # c.root-servers.net +# master: 2001:500:2d::d # d.root-servers.net +# master: 2001:500:2f::f # f.root-servers.net +# master: 2001:500:12::d0d # g.root-servers.net +# master: 2001:7fd::1 # k.root-servers.net +# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org +# master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org +# fallback-enabled: yes +# for-downstream: no +# for-upstream: yes +# auth-zone: +# name: "example.org" +# for-downstream: yes +# for-upstream: yes +# zonefile: "example.org.zone" + +# Views +# Create named views. Name must be unique. Map views to requests using +# the access-control-view option. Views can contain zero or more local-zone +# and local-data options. Options from matching views will override global +# options. Global options will be used if no matching view is found. +# With view-first yes, it will try to answer using the global local-zone and +# local-data elements if there is no view specific match. +# view: +# name: "viewname" +# local-zone: "example.com" redirect +# local-data: "example.com A 192.0.2.3" +# local-data-ptr: "192.0.2.3 www.example.com" +# view-first: no +# view: +# name: "anotherview" +# local-zone: "example.com" refuse + +# DNSCrypt +# Caveats: +# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper +# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage +# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to +# listen on `dnscrypt-port` with the follo0wing snippet: +# server: +# interface: 0.0.0.0@443 +# interface: ::0@443 +# +# Finally, `dnscrypt` config has its own section. +# dnscrypt: +# dnscrypt-enable: yes +# dnscrypt-port: 443 +# dnscrypt-provider: 2.dnscrypt-cert.example.com. +# dnscrypt-secret-key: /path/unbound-conf/keys1/1.key +# dnscrypt-secret-key: /path/unbound-conf/keys2/1.key +# dnscrypt-provider-cert: /path/unbound-conf/keys1/1.cert +# dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert + +# CacheDB +# Enable external backend DB as auxiliary cache. Specify the backend name +# (default is "testframe", which has no use other than for debugging and +# testing) and backend-specific options. The 'cachedb' module must be +# included in module-config, just before the iterator module. +# cachedb: +# backend: "testframe" +# # secret seed string to calculate hashed keys +# secret-seed: "default" +# +# # For "redis" backend: +# # redis server's IP address or host name +# redis-server-host: 127.0.0.1 +# # redis server's TCP port +# redis-server-port: 6379 +# # timeout (in ms) for communication with the redis server +# redis-timeout: 100 + +# IPSet +# Add specify domain into set via ipset. +# Note: To enable ipset needs run unbound as root user. +# ipset: +# # set name for ip v4 addresses +# name-v4: "list-v4" +# # set name for ip v6 addresses +# name-v6: "list-v6" +# + +# Response Policy Zones +# RPZ policies. Applied in order of configuration. QNAME and Response IP +# Address trigger are the only supported triggers. Supported actions are: +# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from +# file, using zone transfer, or using HTTP. The respip module needs to be added +# to the module-config, e.g.: module-config: "respip validator iterator". +# rpz: +# name: "rpz.example.com" +# zonefile: "rpz.example.com" +# master: 192.0.2.0 +# allow-notify: 192.0.2.0/32 +# url: http://www.example.com/rpz.example.org.zone +# rpz-action-override: cname +# rpz-cname-override: www.example.org +# rpz-log: yes +# rpz-log-name: "example policy" +# tags: "example" --- contrib/unbound/doc/libunbound.3.orig +++ contrib/unbound/doc/libunbound.3 @@ -1,4 +1,4 @@ -.TH "libunbound" "3" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "libunbound" "3" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" libunbound.3 -- unbound library functions manual .\" @@ -12,7 +12,7 @@ .B unbound.h, .B ub_ctx, .B ub_result, -.B ub_callback_t, +.B ub_callback_type, .B ub_ctx_create, .B ub_ctx_delete, .B ub_ctx_set_option, @@ -20,6 +20,7 @@ .B ub_ctx_config, .B ub_ctx_set_fwd, .B ub_ctx_set_stub, +.B ub_ctx_set_tls, .B ub_ctx_resolvconf, .B ub_ctx_hosts, .B ub_ctx_add_ta, @@ -43,7 +44,7 @@ .B ub_ctx_zone_remove, .B ub_ctx_data_add, .B ub_ctx_data_remove -\- Unbound DNS validating resolver 1.5.10 functions. +\- Unbound DNS validating resolver 1.9.2 functions. .SH "SYNOPSIS" .B #include .LP @@ -72,6 +73,9 @@ \fIint\fR isprime); .LP \fIint\fR +\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls); +.LP +\fIint\fR \fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname); .LP \fIint\fR @@ -120,7 +124,7 @@ .br \fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata, .br - \fIub_callback_t\fR callback, \fIint*\fR async_id); + \fIub_callback_type\fR callback, \fIint*\fR async_id); .LP \fIint\fR \fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id); @@ -150,7 +154,8 @@ is an implementation of a DNS resolver, that does caching and DNSSEC validation. This is the library API, for using the \-lunbound library. The server daemon is described in \fIunbound\fR(8). -The library can be used to convert hostnames to ip addresses, and back, +The library works independent from a running unbound server, and +can be used to convert hostnames to ip addresses, and back, and obtain other information from the DNS. The library performs public\-key validation of results with DNSSEC. .P @@ -162,7 +167,7 @@ It can be created and deleted at any time. Creating it anew removes any previous configuration (such as trusted keys) and clears any cached results. .P -The functions are thread\-safe, and a context an be used in a threaded (as +The functions are thread\-safe, and a context can be used in a threaded (as well as in a non\-threaded) environment. Also resolution (and validation) can be performed blocking and non\-blocking (also called asynchronous). The async method returns from the call immediately, so that processing @@ -180,7 +185,7 @@ .B ub_ctx_hosts to read them. Before you call this, use the openssl functions CRYPTO_set_id_callback and -CRYPTO_set_locking_callback to set up asyncronous operation if you use +CRYPTO_set_locking_callback to set up asynchronous operation if you use lib openssl (the application calls these functions once for initialisation). Openssl 1.0.0 or later uses the CRYPTO_THREADID_set_callback function. .TP @@ -203,7 +208,10 @@ A power\-user interface that lets you specify an unbound config file, see \fIunbound.conf\fR(5), which is read for configuration. Not all options are relevant. For some specific options, such as adding trust anchors, special -routines exist. +routines exist. This function is thread\-safe only if a single instance of +ub_ctx* exists in the application. If several instances exist the +application has to ensure that ub_ctx_config is not called in parallel by +the different instances. .TP .B ub_ctx_set_fwd Set machine to forward DNS queries to, the caching resolver to use. @@ -223,6 +231,12 @@ At this time it is only possible to set configuration before the first resolve is done. .TP +.B ub_ctx_set_tls +Enable DNS over TLS (DoT) for machines set with +.B ub_ctx_set_fwd. +At this time it is only possible to set configuration before the +first resolve is done. +.TP .B ub_ctx_resolvconf By default the root servers are queried and full resolver mode is used, but you can use this call to read the list of nameservers to use from the @@ -407,6 +421,10 @@ returns true if some information may be available, false otherwise. .B ub_fd returns a file descriptor or \-1 on error. +.B ub_ctx_config +and +.B ub_ctx_resolvconf +attempt to leave errno informative on a function return with file read failure. .SH "SEE ALSO" \fIunbound.conf\fR(5), \fIunbound\fR(8). --- contrib/unbound/doc/libunbound.3.in.orig +++ contrib/unbound/doc/libunbound.3.in @@ -1,4 +1,4 @@ -.TH "libunbound" "3" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "libunbound" "3" "May 19, 2020" "NLnet Labs" "unbound 1.10.1" .\" .\" libunbound.3 -- unbound library functions manual .\" @@ -12,7 +12,7 @@ .B unbound.h, .B ub_ctx, .B ub_result, -.B ub_callback_t, +.B ub_callback_type, .B ub_ctx_create, .B ub_ctx_delete, .B ub_ctx_set_option, @@ -20,6 +20,7 @@ .B ub_ctx_config, .B ub_ctx_set_fwd, .B ub_ctx_set_stub, +.B ub_ctx_set_tls, .B ub_ctx_resolvconf, .B ub_ctx_hosts, .B ub_ctx_add_ta, @@ -43,7 +44,7 @@ .B ub_ctx_zone_remove, .B ub_ctx_data_add, .B ub_ctx_data_remove -\- Unbound DNS validating resolver 1.5.10 functions. +\- Unbound DNS validating resolver 1.10.1 functions. .SH "SYNOPSIS" .B #include .LP @@ -72,6 +73,9 @@ \fIint\fR isprime); .LP \fIint\fR +\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls); +.LP +\fIint\fR \fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname); .LP \fIint\fR @@ -120,7 +124,7 @@ .br \fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata, .br - \fIub_callback_t\fR callback, \fIint*\fR async_id); + \fIub_callback_type\fR callback, \fIint*\fR async_id); .LP \fIint\fR \fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id); @@ -150,7 +154,8 @@ is an implementation of a DNS resolver, that does caching and DNSSEC validation. This is the library API, for using the \-lunbound library. The server daemon is described in \fIunbound\fR(8). -The library can be used to convert hostnames to ip addresses, and back, +The library works independent from a running unbound server, and +can be used to convert hostnames to ip addresses, and back, and obtain other information from the DNS. The library performs public\-key validation of results with DNSSEC. .P @@ -162,7 +167,7 @@ It can be created and deleted at any time. Creating it anew removes any previous configuration (such as trusted keys) and clears any cached results. .P -The functions are thread\-safe, and a context an be used in a threaded (as +The functions are thread\-safe, and a context can be used in a threaded (as well as in a non\-threaded) environment. Also resolution (and validation) can be performed blocking and non\-blocking (also called asynchronous). The async method returns from the call immediately, so that processing @@ -180,7 +185,7 @@ .B ub_ctx_hosts to read them. Before you call this, use the openssl functions CRYPTO_set_id_callback and -CRYPTO_set_locking_callback to set up asyncronous operation if you use +CRYPTO_set_locking_callback to set up asynchronous operation if you use lib openssl (the application calls these functions once for initialisation). Openssl 1.0.0 or later uses the CRYPTO_THREADID_set_callback function. .TP @@ -203,7 +208,10 @@ A power\-user interface that lets you specify an unbound config file, see \fIunbound.conf\fR(5), which is read for configuration. Not all options are relevant. For some specific options, such as adding trust anchors, special -routines exist. +routines exist. This function is thread\-safe only if a single instance of +ub_ctx* exists in the application. If several instances exist the +application has to ensure that ub_ctx_config is not called in parallel by +the different instances. .TP .B ub_ctx_set_fwd Set machine to forward DNS queries to, the caching resolver to use. @@ -223,6 +231,12 @@ At this time it is only possible to set configuration before the first resolve is done. .TP +.B ub_ctx_set_tls +Enable DNS over TLS (DoT) for machines set with +.B ub_ctx_set_fwd. +At this time it is only possible to set configuration before the +first resolve is done. +.TP .B ub_ctx_resolvconf By default the root servers are queried and full resolver mode is used, but you can use this call to read the list of nameservers to use from the @@ -382,12 +396,13 @@ char* canonname; /* canonical name of result */ int rcode; /* additional error code in case of no data */ void* answer_packet; /* full network format answer packet */ - int answer_len; /* length of packet in octets */ + int answer_len; /* length of packet in octets */ int havedata; /* true if there is data */ int nxdomain; /* true if nodata because name does not exist */ - int secure; /* true if result is secure */ - int bogus; /* true if a security failure happened */ + int secure; /* true if result is secure */ + int bogus; /* true if a security failure happened */ char* why_bogus; /* string with error if bogus */ + int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */ int ttl; /* number of seconds the result is valid */ }; .fi @@ -407,6 +422,10 @@ returns true if some information may be available, false otherwise. .B ub_fd returns a file descriptor or \-1 on error. +.B ub_ctx_config +and +.B ub_ctx_resolvconf +attempt to leave errno informative on a function return with file read failure. .SH "SEE ALSO" \fIunbound.conf\fR(5), \fIunbound\fR(8). --- contrib/unbound/doc/requirements.txt.orig +++ contrib/unbound/doc/requirements.txt @@ -81,7 +81,7 @@ 5. Choices ---------- -o rfc2181 decourages duplicates RRs in RRsets. unbound does not create +o rfc2181 discourages duplicates RRs in RRsets. unbound does not create duplicates, but when presented with duplicates on the wire from the authoritative servers, does not perform duplicate removal. It does do some rrsig duplicate removal, in the msgparser, for dnssec qtype --- contrib/unbound/doc/unbound-anchor.8.orig +++ contrib/unbound/doc/unbound-anchor.8 @@ -1,4 +1,4 @@ -.TH "unbound-anchor" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound-anchor" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" unbound-anchor.8 -- unbound anchor maintenance utility manual .\" @@ -67,7 +67,7 @@ .B \-u \fIname The server name, it connects to https://name. Specify without https:// prefix. The default is "data.iana.org". It connects to the port specified with \-P. -You can pass an IPv4 addres or IPv6 address (no brackets) if you want. +You can pass an IPv4 address or IPv6 address (no brackets) if you want. .TP .B \-x \fIpath The pathname to the root\-anchors.xml file on the server. (forms URL with \-u). @@ -109,6 +109,11 @@ resolver, cannot use that recursive resolver itself because it is bootstrapping that server. .TP +.B \-R +Allow fallback from \-f resolv.conf file to direct root servers query. +It allows you to prefer local resolvers, but fallback automatically +to direct root query if they do not respond or do not support DNSSEC. +.TP .B \-v More verbose. Once prints informational messages, multiple times may enable large debug amounts (such as full certificates or byte\-dumps of downloaded --- contrib/unbound/doc/unbound-anchor.8.in.orig +++ contrib/unbound/doc/unbound-anchor.8.in @@ -1,4 +1,4 @@ -.TH "unbound-anchor" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound-anchor" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1" .\" .\" unbound-anchor.8 -- unbound anchor maintenance utility manual .\" @@ -67,8 +67,12 @@ .B \-u \fIname The server name, it connects to https://name. Specify without https:// prefix. The default is "data.iana.org". It connects to the port specified with \-P. -You can pass an IPv4 addres or IPv6 address (no brackets) if you want. +You can pass an IPv4 address or IPv6 address (no brackets) if you want. .TP +.B \-b \fIaddress +The source address to bind to for domain resolution and contacting the server +on https. May be either an IPv4 address or IPv6 address (no brackets). +.TP .B \-x \fIpath The pathname to the root\-anchors.xml file on the server. (forms URL with \-u). The default is /root\-anchors/root\-anchors.xml. @@ -109,6 +113,11 @@ resolver, cannot use that recursive resolver itself because it is bootstrapping that server. .TP +.B \-R +Allow fallback from \-f resolv.conf file to direct root servers query. +It allows you to prefer local resolvers, but fallback automatically +to direct root query if they do not respond or do not support DNSSEC. +.TP .B \-v More verbose. Once prints informational messages, multiple times may enable large debug amounts (such as full certificates or byte\-dumps of downloaded --- contrib/unbound/doc/unbound-checkconf.8.orig +++ contrib/unbound/doc/unbound-checkconf.8 @@ -1,4 +1,4 @@ -.TH "unbound-checkconf" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound-checkconf" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" unbound-checkconf.8 -- unbound configuration checker manual .\" @@ -8,7 +8,7 @@ .\" .\" .SH "NAME" -unbound\-checkconf +.B unbound\-checkconf \- Check unbound configuration file for errors. .SH "SYNOPSIS" .B unbound\-checkconf --- contrib/unbound/doc/unbound-checkconf.8.in.orig +++ contrib/unbound/doc/unbound-checkconf.8.in @@ -1,4 +1,4 @@ -.TH "unbound-checkconf" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound-checkconf" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1" .\" .\" unbound-checkconf.8 -- unbound configuration checker manual .\" @@ -8,7 +8,7 @@ .\" .\" .SH "NAME" -unbound\-checkconf +.B unbound\-checkconf \- Check unbound configuration file for errors. .SH "SYNOPSIS" .B unbound\-checkconf --- contrib/unbound/doc/unbound-control.8.orig +++ contrib/unbound/doc/unbound-control.8 @@ -1,4 +1,4 @@ -.TH "unbound-control" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound-control" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" unbound-control.8 -- unbound remote control manual .\" @@ -99,6 +99,22 @@ domain names below the removed name), NOERROR nodata answers are the result for that name. .TP +.B local_zones +Add local zones read from stdin of unbound\-control. Input is read per line, +with name space type on a line. For bulk additions. +.TP +.B local_zones_remove +Remove local zones read from stdin of unbound\-control. Input is one name per +line. For bulk removals. +.TP +.B local_datas +Add local data RRs read from stdin of unbound\-control. Input is one RR per +line. For bulk additions. +.TP +.B local_datas_remove +Remove local data RRs read from stdin of unbound\-control. Input is one name per +line. For bulk removals. +.TP .B dump_cache The contents of the cache is printed in a text format to stdout. You can redirect it to a file to store the cache in a file. @@ -128,6 +144,9 @@ Remove all information at or below the name from the cache. The rrsets and key entries are removed so that new lookups will be performed. This needs to walk and inspect the entire cache, and is a slow operation. +The entries are set to expired in the implementation of this command (so, +with serve\-expired enabled, it'll serve that information but schedule a +prefetch for new information). .TP .B flush_bogus Remove all bogus data from the cache. @@ -178,7 +197,7 @@ hide\-identity, hide\-version, identity, version, val\-log\-level, val\-log\-squelch, ignore\-cd\-flag, add\-holddown, del\-holddown, keep\-missing, tcp\-upstream, ssl\-upstream, max\-udp\-size, ratelimit, -cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl. +ip\-ratelimit, cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl. .TP .B get_option \fIopt Get the value of the option. Give the option name without a trailing ':'. @@ -263,6 +282,49 @@ just the ratelimited domains, with their estimated qps. The ratelimited domains return an error for uncached (new) queries, but cached queries work as normal. +.TP +.B ip_ratelimit_list \fR[\fI+a\fR] +List the ip addresses that are ratelimited. Printed one per line with current +estimated qps and qps limit from config. With +a it prints all ips, not +just the ratelimited ips, with their estimated qps. The ratelimited +ips are dropped before checking the cache. +.TP +.B list_auth_zones +List the auth zones that are configured. Printed one per line with a +status, indicating if the zone is expired and current serial number. +.TP +.B auth_zone_reload \fIzone\fR +Reload the auth zone from zonefile. The zonefile is read in overwriting +the current contents of the zone in memory. This changes the auth zone +contents itself, not the cache contents. Such cache contents exists if +you set unbound to validate with for-upstream yes and that can be cleared +with \fBflush_zone\fR \fIzone\fR. +.TP +.B auth_zone_transfer \fIzone\fR +Transfer the auth zone from master. The auth zone probe sequence is started, +where the masters are probed to see if they have an updated zone (with the SOA +serial check). And then the zone is transferred for a newer zone version. +.TP +.B view_list_local_zones \fIview\fR +\fIlist_local_zones\fR for given view. +.TP +.B view_local_zone \fIview\fR \fIname\fR \fItype +\fIlocal_zone\fR for given view. +.TP +.B view_local_zone_remove \fIview\fR \fIname +\fIlocal_zone_remove\fR for given view. +.TP +.B view_list_local_data \fIview\fR +\fIlist_local_data\fR for given view. +.TP +.B view_local_data \fIview\fR \fIRR data... +\fIlocal_data\fR for given view. +.TP +.B view_local_data_remove \fIview\fR \fIname +\fIlocal_data_remove\fR for given view. +.TP +.B view_local_datas \fIview\fR +Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas. .SH "EXIT CODE" The unbound\-control program exits with status code 1 on error, 0 on success. .SH "SET UP" @@ -288,6 +350,9 @@ .I threadX.num.queries number of queries received by thread .TP +.I threadX.num.queries_ip_ratelimited +number of queries rate limited by thread +.TP .I threadX.num.cachehits number of queries that were successfully answered using a cache lookup .TP @@ -294,6 +359,19 @@ .I threadX.num.cachemiss number of queries that needed recursive processing .TP +.I threadX.num.dnscrypt.crypted +number of queries that were encrypted and successfully decapsulated by dnscrypt. +.TP +.I threadX.num.dnscrypt.cert +number of queries that were requesting dnscrypt certificates. +.TP +.I threadX.num.dnscrypt.cleartext +number of queries received on dnscrypt port that were cleartext and not a +request for certificates. +.TP +.I threadX.num.dnscrypt.malformed +number of request that were neither cleartext, not valid dnscrypt messages. +.TP .I threadX.num.prefetch number of cache prefetches performed. This number is included in cachehits, as the original query had the unprefetched answer from cache, @@ -301,6 +379,9 @@ Not part of the recursivereplies (or the histogram thereof) or cachemiss, as a cache response was sent. .TP +.I threadX.num.zero_ttl +number of replies with ttl zero, because they served an expired cache entry. +.TP .I threadX.num.recursivereplies The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries. .TP @@ -347,9 +428,24 @@ .I total.num.cachemiss summed over threads. .TP +.I total.num.dnscrypt.crypted +summed over threads. +.TP +.I total.num.dnscrypt.cert +summed over threads. +.TP +.I total.num.dnscrypt.cleartext +summed over threads. +.TP +.I total.num.dnscrypt.malformed +summed over threads. +.TP .I total.num.prefetch summed over threads. .TP +.I total.num.zero_ttl +summed over threads. +.TP .I total.num.recursivereplies summed over threads. .TP @@ -384,9 +480,6 @@ time since last statistics printout, in seconds. .SH EXTENDED STATISTICS .TP -.I mem.total.sbrk -If sbrk(2) is available, an estimate of the heap size of the program in number of bytes. Close to the total memory used by the program, as reported by top and ps. Could be wrong if the OS allocates memory non\-contiguously. -.TP .I mem.cache.rrset Memory in bytes in use by the RRset cache. .TP @@ -393,6 +486,12 @@ .I mem.cache.message Memory in bytes in use by the message cache. .TP +.I mem.cache.dnscrypt_shared_secret +Memory in bytes in use by the dnscrypt shared secrets cache. +.TP +.I mem.cache.dnscrypt_nonce +Memory in bytes in use by the dnscrypt nonce cache. +.TP .I mem.mod.iterator Memory in bytes in use by the iterator module. .TP @@ -400,6 +499,10 @@ Memory in bytes in use by the validator module. Includes the key cache and negative cache. .TP +.I mem.streamwait +Memory in bytes in used by the TCP and TLS stream wait buffers. These are +answers waiting to be written back to the clients. +.TP .I histogram...to.. Shows a histogram, summed over all threads. Every element counts the recursive queries whose reply time fit between the lower and upper bound. @@ -431,6 +534,14 @@ Number of queries that the unbound server made using TCP outgoing towards other servers. .TP +.I num.query.tls +Number of queries that were made using TLS towards the unbound server. +These are also counted in num.query.tcp, because TLS uses TCP. +.TP +.I num.query.tls.resume +Number of TLS session resumptions, these are queries over TLS towards +the unbound server where the client negotiated a TLS session resumption key. +.TP .I num.query.ipv6 Number of queries that were made using IPv6 towards the unbound server. .TP @@ -447,6 +558,18 @@ number of queries that had an EDNS OPT record with the DO (DNSSEC OK) bit set. These queries are also included in the num.query.edns.present number. .TP +.I num.query.ratelimited +The number of queries that are turned away from being send to nameserver due to +ratelimiting. +.TP +.I num.query.dnscrypt.shared_secret.cachemiss +The number of dnscrypt queries that did not find a shared secret in the cache. +The can be use to compute the shared secret hitrate. +.TP +.I num.query.dnscrypt.replay +The number of dnscrypt queries that found a nonce hit in the nonce cache and +hence are considered a query replay. +.TP .I num.answer.rcode.NXDOMAIN The number of answers to queries, from cache or from recursion, that had the return code NXDOMAIN. Also printed for the other return codes. @@ -496,6 +619,47 @@ .I key.cache.count The number of items in the key cache. These are DNSSEC keys, one item per delegation point, and their validation status. +.TP +.I dnscrypt_shared_secret.cache.count +The number of items in the shared secret cache. These are precomputed shared +secrets for a given client public key/server secret key pair. Shared secrets +are CPU intensive and this cache allows unbound to avoid recomputing the +shared secret when multiple dnscrypt queries are sent from the same client. +.TP +.I dnscrypt_nonce.cache.count +The number of items in the client nonce cache. This cache is used to prevent +dnscrypt queries replay. The client nonce must be unique for each client public +key/server secret key pair. This cache should be able to host QPS * `replay +window` interval keys to prevent replay of a query during `replay window` +seconds. +.TP +.I num.query.authzone.up +The number of queries answered from auth\-zone data, upstream queries. +These queries would otherwise have been sent (with fallback enabled) to +the internet, but are now answered from the auth zone. +.TP +.I num.query.authzone.down +The number of queries for downstream answered from auth\-zone data. +These queries are from downstream clients, and have had an answer from +the data in the auth zone. +.TP +.I num.query.aggressive.NOERROR +The number of queries answered using cached NSEC records with NODATA RCODE. +These queries would otherwise have been sent to the internet, but are now +answered using cached data. +.TP +.I num.query.aggressive.NXDOMAIN +The number of queries answered using cached NSEC records with NXDOMAIN RCODE. +These queries would otherwise have been sent to the internet, but are now +answered using cached data. +.TP +.I num.query.subnet +Number of queries that got an answer that contained EDNS client subnet data. +.TP +.I num.query.subnet_cache +Number of queries answered from the edns client subnet cache. These are +counted as cachemiss by the main counters, but hit the client subnet +specific cache, after getting processed by the edns client subnet module. .SH "FILES" .TP .I /var/unbound/unbound.conf --- contrib/unbound/doc/unbound-control.8.in.orig +++ contrib/unbound/doc/unbound-control.8.in @@ -1,4 +1,4 @@ -.TH "unbound-control" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound-control" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1" .\" .\" unbound-control.8 -- unbound remote control manual .\" @@ -99,6 +99,22 @@ domain names below the removed name), NOERROR nodata answers are the result for that name. .TP +.B local_zones +Add local zones read from stdin of unbound\-control. Input is read per line, +with name space type on a line. For bulk additions. +.TP +.B local_zones_remove +Remove local zones read from stdin of unbound\-control. Input is one name per +line. For bulk removals. +.TP +.B local_datas +Add local data RRs read from stdin of unbound\-control. Input is one RR per +line. For bulk additions. +.TP +.B local_datas_remove +Remove local data RRs read from stdin of unbound\-control. Input is one name per +line. For bulk removals. +.TP .B dump_cache The contents of the cache is printed in a text format to stdout. You can redirect it to a file to store the cache in a file. @@ -128,6 +144,9 @@ Remove all information at or below the name from the cache. The rrsets and key entries are removed so that new lookups will be performed. This needs to walk and inspect the entire cache, and is a slow operation. +The entries are set to expired in the implementation of this command (so, +with serve\-expired enabled, it'll serve that information but schedule a +prefetch for new information). .TP .B flush_bogus Remove all bogus data from the cache. @@ -178,7 +197,7 @@ hide\-identity, hide\-version, identity, version, val\-log\-level, val\-log\-squelch, ignore\-cd\-flag, add\-holddown, del\-holddown, keep\-missing, tcp\-upstream, ssl\-upstream, max\-udp\-size, ratelimit, -cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl. +ip\-ratelimit, cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl. .TP .B get_option \fIopt Get the value of the option. Give the option name without a trailing ':'. @@ -263,6 +282,52 @@ just the ratelimited domains, with their estimated qps. The ratelimited domains return an error for uncached (new) queries, but cached queries work as normal. +.TP +.B ip_ratelimit_list \fR[\fI+a\fR] +List the ip addresses that are ratelimited. Printed one per line with current +estimated qps and qps limit from config. With +a it prints all ips, not +just the ratelimited ips, with their estimated qps. The ratelimited +ips are dropped before checking the cache. +.TP +.B list_auth_zones +List the auth zones that are configured. Printed one per line with a +status, indicating if the zone is expired and current serial number. +.TP +.B auth_zone_reload \fIzone\fR +Reload the auth zone from zonefile. The zonefile is read in overwriting +the current contents of the zone in memory. This changes the auth zone +contents itself, not the cache contents. Such cache contents exists if +you set unbound to validate with for-upstream yes and that can be cleared +with \fBflush_zone\fR \fIzone\fR. +.TP +.B auth_zone_transfer \fIzone\fR +Transfer the auth zone from master. The auth zone probe sequence is started, +where the masters are probed to see if they have an updated zone (with the SOA +serial check). And then the zone is transferred for a newer zone version. +.TP +.B view_list_local_zones \fIview\fR +\fIlist_local_zones\fR for given view. +.TP +.B view_local_zone \fIview\fR \fIname\fR \fItype +\fIlocal_zone\fR for given view. +.TP +.B view_local_zone_remove \fIview\fR \fIname +\fIlocal_zone_remove\fR for given view. +.TP +.B view_list_local_data \fIview\fR +\fIlist_local_data\fR for given view. +.TP +.B view_local_data \fIview\fR \fIRR data... +\fIlocal_data\fR for given view. +.TP +.B view_local_data_remove \fIview\fR \fIname +\fIlocal_data_remove\fR for given view. +.TP +.B view_local_datas_remove \fIview\fR +Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_remove. +.TP +.B view_local_datas \fIview\fR +Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas. .SH "EXIT CODE" The unbound\-control program exits with status code 1 on error, 0 on success. .SH "SET UP" @@ -288,6 +353,9 @@ .I threadX.num.queries number of queries received by thread .TP +.I threadX.num.queries_ip_ratelimited +number of queries rate limited by thread +.TP .I threadX.num.cachehits number of queries that were successfully answered using a cache lookup .TP @@ -294,6 +362,19 @@ .I threadX.num.cachemiss number of queries that needed recursive processing .TP +.I threadX.num.dnscrypt.crypted +number of queries that were encrypted and successfully decapsulated by dnscrypt. +.TP +.I threadX.num.dnscrypt.cert +number of queries that were requesting dnscrypt certificates. +.TP +.I threadX.num.dnscrypt.cleartext +number of queries received on dnscrypt port that were cleartext and not a +request for certificates. +.TP +.I threadX.num.dnscrypt.malformed +number of request that were neither cleartext, not valid dnscrypt messages. +.TP .I threadX.num.prefetch number of cache prefetches performed. This number is included in cachehits, as the original query had the unprefetched answer from cache, @@ -301,6 +382,9 @@ Not part of the recursivereplies (or the histogram thereof) or cachemiss, as a cache response was sent. .TP +.I threadX.num.expired +number of replies that served an expired cache entry. +.TP .I threadX.num.recursivereplies The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries. .TP @@ -347,9 +431,24 @@ .I total.num.cachemiss summed over threads. .TP +.I total.num.dnscrypt.crypted +summed over threads. +.TP +.I total.num.dnscrypt.cert +summed over threads. +.TP +.I total.num.dnscrypt.cleartext +summed over threads. +.TP +.I total.num.dnscrypt.malformed +summed over threads. +.TP .I total.num.prefetch summed over threads. .TP +.I total.num.expired +summed over threads. +.TP .I total.num.recursivereplies summed over threads. .TP @@ -384,9 +483,6 @@ time since last statistics printout, in seconds. .SH EXTENDED STATISTICS .TP -.I mem.total.sbrk -If sbrk(2) is available, an estimate of the heap size of the program in number of bytes. Close to the total memory used by the program, as reported by top and ps. Could be wrong if the OS allocates memory non\-contiguously. -.TP .I mem.cache.rrset Memory in bytes in use by the RRset cache. .TP @@ -393,6 +489,12 @@ .I mem.cache.message Memory in bytes in use by the message cache. .TP +.I mem.cache.dnscrypt_shared_secret +Memory in bytes in use by the dnscrypt shared secrets cache. +.TP +.I mem.cache.dnscrypt_nonce +Memory in bytes in use by the dnscrypt nonce cache. +.TP .I mem.mod.iterator Memory in bytes in use by the iterator module. .TP @@ -400,6 +502,10 @@ Memory in bytes in use by the validator module. Includes the key cache and negative cache. .TP +.I mem.streamwait +Memory in bytes in used by the TCP and TLS stream wait buffers. These are +answers waiting to be written back to the clients. +.TP .I histogram...to.. Shows a histogram, summed over all threads. Every element counts the recursive queries whose reply time fit between the lower and upper bound. @@ -431,6 +537,14 @@ Number of queries that the unbound server made using TCP outgoing towards other servers. .TP +.I num.query.tls +Number of queries that were made using TLS towards the unbound server. +These are also counted in num.query.tcp, because TLS uses TCP. +.TP +.I num.query.tls.resume +Number of TLS session resumptions, these are queries over TLS towards +the unbound server where the client negotiated a TLS session resumption key. +.TP .I num.query.ipv6 Number of queries that were made using IPv6 towards the unbound server. .TP @@ -447,6 +561,18 @@ number of queries that had an EDNS OPT record with the DO (DNSSEC OK) bit set. These queries are also included in the num.query.edns.present number. .TP +.I num.query.ratelimited +The number of queries that are turned away from being send to nameserver due to +ratelimiting. +.TP +.I num.query.dnscrypt.shared_secret.cachemiss +The number of dnscrypt queries that did not find a shared secret in the cache. +The can be use to compute the shared secret hitrate. +.TP +.I num.query.dnscrypt.replay +The number of dnscrypt queries that found a nonce hit in the nonce cache and +hence are considered a query replay. +.TP .I num.answer.rcode.NXDOMAIN The number of answers to queries, from cache or from recursion, that had the return code NXDOMAIN. Also printed for the other return codes. @@ -496,6 +622,52 @@ .I key.cache.count The number of items in the key cache. These are DNSSEC keys, one item per delegation point, and their validation status. +.TP +.I dnscrypt_shared_secret.cache.count +The number of items in the shared secret cache. These are precomputed shared +secrets for a given client public key/server secret key pair. Shared secrets +are CPU intensive and this cache allows unbound to avoid recomputing the +shared secret when multiple dnscrypt queries are sent from the same client. +.TP +.I dnscrypt_nonce.cache.count +The number of items in the client nonce cache. This cache is used to prevent +dnscrypt queries replay. The client nonce must be unique for each client public +key/server secret key pair. This cache should be able to host QPS * `replay +window` interval keys to prevent replay of a query during `replay window` +seconds. +.TP +.I num.query.authzone.up +The number of queries answered from auth\-zone data, upstream queries. +These queries would otherwise have been sent (with fallback enabled) to +the internet, but are now answered from the auth zone. +.TP +.I num.query.authzone.down +The number of queries for downstream answered from auth\-zone data. +These queries are from downstream clients, and have had an answer from +the data in the auth zone. +.TP +.I num.query.aggressive.NOERROR +The number of queries answered using cached NSEC records with NODATA RCODE. +These queries would otherwise have been sent to the internet, but are now +answered using cached data. +.TP +.I num.query.aggressive.NXDOMAIN +The number of queries answered using cached NSEC records with NXDOMAIN RCODE. +These queries would otherwise have been sent to the internet, but are now +answered using cached data. +.TP +.I num.query.subnet +Number of queries that got an answer that contained EDNS client subnet data. +.TP +.I num.query.subnet_cache +Number of queries answered from the edns client subnet cache. These are +counted as cachemiss by the main counters, but hit the client subnet +specific cache, after getting processed by the edns client subnet module. +.TP +.I num.rpz.action. +Number of queries answered using configured RPZ policy, per RPZ action type. +Possible actions are: nxdomain, nodata, passthru, drop, local_data, disabled, +and cname_override. .SH "FILES" .TP .I @ub_conf_file@ --- contrib/unbound/doc/unbound-host.1.orig +++ contrib/unbound/doc/unbound-host.1 @@ -1,4 +1,4 @@ -.TH "unbound\-host" "1" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound\-host" "1" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" unbound-host.1 -- unbound DNS lookup utility .\" @@ -12,12 +12,13 @@ \- unbound DNS lookup utility .SH "SYNOPSIS" .B unbound\-host +.RB [ \-C +.IR configfile ] .RB [ \-vdhr46D ] .RB [ \-c .IR class ] .RB [ \-t .IR type ] -.I hostname .RB [ \-y .IR key ] .RB [ \-f @@ -24,8 +25,7 @@ .IR keyfile ] .RB [ \-F .IR namedkeyfile ] -.RB [ \-C -.IR configfile ] +.I hostname .SH "DESCRIPTION" .B Unbound\-host uses the unbound validating resolver to query for the hostname and display @@ -86,6 +86,8 @@ .B \-C \fIconfigfile Uses the specified unbound.conf to prime .IR libunbound (3). +Pass it as first argument if you want to override some options from the +config file with further arguments on the commandline. .TP .B \-r Read /etc/resolv.conf, and use the forward DNS servers from there (those could --- contrib/unbound/doc/unbound-host.1.in.orig +++ contrib/unbound/doc/unbound-host.1.in @@ -1,4 +1,4 @@ -.TH "unbound\-host" "1" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound\-host" "1" "May 19, 2020" "NLnet Labs" "unbound 1.10.1" .\" .\" unbound-host.1 -- unbound DNS lookup utility .\" @@ -12,12 +12,13 @@ \- unbound DNS lookup utility .SH "SYNOPSIS" .B unbound\-host +.RB [ \-C +.IR configfile ] .RB [ \-vdhr46D ] .RB [ \-c .IR class ] .RB [ \-t .IR type ] -.I hostname .RB [ \-y .IR key ] .RB [ \-f @@ -24,8 +25,7 @@ .IR keyfile ] .RB [ \-F .IR namedkeyfile ] -.RB [ \-C -.IR configfile ] +.I hostname .SH "DESCRIPTION" .B Unbound\-host uses the unbound validating resolver to query for the hostname and display @@ -86,6 +86,8 @@ .B \-C \fIconfigfile Uses the specified unbound.conf to prime .IR libunbound (3). +Pass it as first argument if you want to override some options from the +config file with further arguments on the commandline. .TP .B \-r Read /etc/resolv.conf, and use the forward DNS servers from there (those could --- contrib/unbound/doc/unbound.8.orig +++ contrib/unbound/doc/unbound.8 @@ -1,4 +1,4 @@ -.TH "unbound" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" unbound.8 -- unbound manual .\" @@ -9,11 +9,12 @@ .\" .SH "NAME" .B unbound -\- Unbound DNS validating resolver 1.5.10. +\- Unbound DNS validating resolver 1.9.2. .SH "SYNOPSIS" .B unbound .RB [ \-h ] .RB [ \-d ] +.RB [ \-p ] .RB [ \-v ] .RB [ \-c .IR cfgfile ] @@ -67,6 +68,11 @@ stderr. If given twice or more, logging does not switch to the log file or to syslog, but the log messages are printed to stderr all the time. .TP +.B \-p +Don't use a pidfile. This argument should only be used by supervision +systems which can ensure that only one instance of unbound will run +concurrently. +.TP .B \-v Increase verbosity. If given multiple times, more information is logged. This is in addition to the verbosity (if any) from the config file. --- contrib/unbound/doc/unbound.8.in.orig +++ contrib/unbound/doc/unbound.8.in @@ -1,4 +1,4 @@ -.TH "unbound" "8" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1" .\" .\" unbound.8 -- unbound manual .\" @@ -9,11 +9,12 @@ .\" .SH "NAME" .B unbound -\- Unbound DNS validating resolver 1.5.10. +\- Unbound DNS validating resolver 1.10.1. .SH "SYNOPSIS" .B unbound .RB [ \-h ] .RB [ \-d ] +.RB [ \-p ] .RB [ \-v ] .RB [ \-c .IR cfgfile ] @@ -53,7 +54,7 @@ The available options are: .TP .B \-h -Show the version and commandline option help. +Show the version number and commandline option help, and exit. .TP .B \-c\fI cfgfile Set the config file with settings for unbound to read instead of reading the @@ -67,9 +68,17 @@ stderr. If given twice or more, logging does not switch to the log file or to syslog, but the log messages are printed to stderr all the time. .TP +.B \-p +Don't use a pidfile. This argument should only be used by supervision +systems which can ensure that only one instance of unbound will run +concurrently. +.TP .B \-v Increase verbosity. If given multiple times, more information is logged. This is in addition to the verbosity (if any) from the config file. +.TP +.B \-V +Show the version number and build options, and exit. .SH "SEE ALSO" \fIunbound.conf\fR(5), \fIunbound\-checkconf\fR(8), --- contrib/unbound/doc/unbound.conf.5.orig +++ contrib/unbound/doc/unbound.conf.5 @@ -1,4 +1,4 @@ -.TH "unbound.conf" "5" "Sep 27, 2016" "NLnet Labs" "unbound 1.5.10" +.TH "unbound.conf" "5" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2" .\" .\" unbound.conf.5 -- unbound.conf manual .\" @@ -16,13 +16,14 @@ .B unbound.conf is used to configure \fIunbound\fR(8). -The file format has attributes and values. Some attributes have attributes inside them. +The file format has attributes and values. Some attributes have attributes +inside them. The notation is: attribute: value. .P Comments start with # and last to the end of line. Empty lines are ignored as is whitespace at the beginning of a line. .P -The utility +The utility \fIunbound\-checkconf\fR(8) can be used to check unbound.conf prior to usage. .SH "EXAMPLE" @@ -30,7 +31,7 @@ and start the server with: .P .nf - $ unbound \-c /etc/unbound/unbound.conf + $ unbound \-c /etc/unbound/unbound.conf .fi .P Most settings are the defaults. Stop the server with: @@ -62,8 +63,8 @@ access\-control: 2001:DB8::/64 allow .fi .SH "FILE FORMAT" -There must be whitespace between keywords. Attribute keywords end with a colon ':'. An attribute -is followed by its containing attributes, or a value. +There must be whitespace between keywords. Attribute keywords end with a colon ':'. +An attribute is followed by its containing attributes, or a value. .P Files can be included using the .B include: @@ -71,7 +72,7 @@ Processing continues as if the text from the included file was copied into the config file at that point. If also using chroot, using full path names for the included files works, relative pathnames for the included names work -if the directory where the daemon is started equals its chroot/working +if the directory where the daemon is started equals its chroot/working directory or is specified before the include statement with directory: dir. Wildcards can be used to include multiple files, see \fIglob\fR(7). .SS "Server Options" @@ -80,17 +81,17 @@ clause. .TP .B verbosity: \fI -The verbosity number, level 0 means no verbosity, only errors. Level 1 +The verbosity number, level 0 means no verbosity, only errors. Level 1 gives operational information. Level 2 gives detailed operational -information. Level 3 gives query level information, output per query. -Level 4 gives algorithm level information. Level 5 logs client -identification for cache misses. Default is level 1. +information. Level 3 gives query level information, output per query. +Level 4 gives algorithm level information. Level 5 logs client +identification for cache misses. Default is level 1. The verbosity can also be increased from the commandline, see \fIunbound\fR(8). .TP .B statistics\-interval: \fI The number of seconds between printing statistics to the log for every thread. Disable with value 0 or "". Default is disabled. The histogram statistics -are only printed if replies were sent during the statistics interval, +are only printed if replies were sent during the statistics interval, requestlist statistics are printed for every interval (but can be 0). This is because the median calculation requires data to be present. .TP @@ -99,7 +100,7 @@ the statistics counters after logging the statistics. Default is no. .TP .B extended\-statistics: \fI -If enabled, extended statistics are printed from \fIunbound\-control\fR(8). +If enabled, extended statistics are printed from \fIunbound\-control\fR(8). Default is off, because keeping track of more statistics takes time. The counters are listed in \fIunbound\-control\fR(8). .TP @@ -112,7 +113,7 @@ .B interface: \fI Interface to use to connect to the network. This interface is listened to for queries from clients, and answers to clients are given from it. -Can be given multiple times to work on several interfaces. If none are +Can be given multiple times to work on several interfaces. If none are given the default is to listen to localhost. The interfaces are not changed on a reload (kill \-HUP) but only on restart. A port number can be specified with @port (without spaces between @@ -120,22 +121,22 @@ \fBport\fR) is used. .TP .B ip\-address: \fI -Same as interface: (for easy of compatibility with nsd.conf). +Same as interface: (for ease of compatibility with nsd.conf). .TP .B interface\-automatic: \fI -Detect source interface on UDP queries and copy them to replies. This +Detect source interface on UDP queries and copy them to replies. This feature is experimental, and needs support in your OS for particular socket options. Default value is no. .TP .B outgoing\-interface: \fI Interface to use to connect to the network. This interface is used to send -queries to authoritative servers and receive their replies. Can be given -multiple times to work on several interfaces. If none are given the -default (all) is used. You can specify the same interfaces in +queries to authoritative servers and receive their replies. Can be given +multiple times to work on several interfaces. If none are given the +default (all) is used. You can specify the same interfaces in .B interface: and .B outgoing\-interface: -lines, the interfaces are then used for both purposes. Outgoing queries are +lines, the interfaces are then used for both purposes. Outgoing queries are sent via a random outgoing interface to counter spoofing. .IP If an IPv6 netblock is specified instead of an individual IPv6 address, @@ -151,12 +152,12 @@ to increase the likelihood of IPv6 nameservers being selected for queries. On Linux you need these two commands to be able to use the freebind socket option to receive traffic for the ip6 netblock: -ip -6 addr add mynetblock/64 dev lo && -ip -6 route add local mynetblock/64 dev lo +ip \-6 addr add mynetblock/64 dev lo && +ip \-6 route add local mynetblock/64 dev lo .TP .B outgoing\-range: \fI -Number of ports to open. This number of file descriptors can be opened per -thread. Must be at least 1. Default depends on compile options. Larger +Number of ports to open. This number of file descriptors can be opened per +thread. Must be at least 1. Default depends on compile options. Larger numbers need extra resources from the operating system. For performance a very large value is best, use libevent to make this possible. .TP @@ -163,18 +164,18 @@ .B outgoing\-port\-permit: \fI Permit unbound to open this port or range of ports for use to send queries. A larger number of permitted outgoing ports increases resilience against -spoofing attempts. Make sure these ports are not needed by other daemons. +spoofing attempts. Make sure these ports are not needed by other daemons. By default only ports above 1024 that have not been assigned by IANA are used. Give a port number or a range of the form "low\-high", without spaces. .IP -The \fBoutgoing\-port\-permit\fR and \fBoutgoing\-port\-avoid\fR statements -are processed in the line order of the config file, adding the permitted ports -and subtracting the avoided ports from the set of allowed ports. The -processing starts with the non IANA allocated ports above 1024 in the set +The \fBoutgoing\-port\-permit\fR and \fBoutgoing\-port\-avoid\fR statements +are processed in the line order of the config file, adding the permitted ports +and subtracting the avoided ports from the set of allowed ports. The +processing starts with the non IANA allocated ports above 1024 in the set of allowed ports. .TP .B outgoing\-port\-avoid: \fI -Do not permit unbound to open this port or range of ports for use to send +Do not permit unbound to open this port or range of ports for use to send queries. Use this to make sure unbound does not grab a port that another daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6. By default only ports above 1024 that have not been assigned by IANA are used. @@ -196,7 +197,7 @@ buffer size is determined by msg\-buffer\-size (both for TCP and UDP). Do not set higher than that value. Default is 4096 which is RFC recommended. If you have fragmentation reassembly problems, usually seen as timeouts, -then a value of 1480 can fix it. Setting to 512 bypasses even the most +then a value of 1472 can fix it. Setting to 512 bypasses even the most stringent path MTU problems, but is seen as extreme, since the amount of TCP fallback generated is excessive (probably also for this resolver, consider tuning the outgoing tcp number). @@ -204,13 +205,23 @@ .B max\-udp\-size: \fI Maximum UDP response size (not applied to TCP response). 65536 disables the udp response size maximum, and uses the choice from the client, always. -Suggested values are 512 to 4096. Default is 4096. +Suggested values are 512 to 4096. Default is 4096. .TP +.B stream\-wait\-size: \fI +Number of bytes size maximum to use for waiting stream buffers. Default is +4 megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, +megabytes or gigabytes (1024*1024 bytes in a megabyte). As TCP and TLS streams +queue up multiple results, the amount of memory used for these buffers does +not exceed this number, otherwise the responses are dropped. This manages +the total memory usage of the server (under heavy use), the number of requests +that can be queued up per connection is also limited, with further requests +waiting in TCP buffers. +.TP .B msg\-buffer\-size: \fI Number of bytes size of the message buffers. Default is 65552 bytes, enough for 64 Kb packets, the maximum DNS message size. No message larger than this can be sent or received. Can be reduced to use less memory, but some requests -for DNS data, such as for huge resource records, will result in a SERVFAIL +for DNS data, such as for huge resource records, will result in a SERVFAIL reply to the client. .TP .B msg\-cache\-size: \fI @@ -220,7 +231,7 @@ .TP .B msg\-cache\-slabs: \fI Number of slabs in the message cache. Slabs reduce lock contention by threads. -Must be set to a power of 2. Setting (close) to the number of cpus is a +Must be set to a power of 2. Setting (close) to the number of cpus is a reasonable guess. .TP .B num\-queries\-per\-thread: \fI @@ -232,12 +243,12 @@ .TP .B jostle\-timeout: \fI Timeout used when the server is very busy. Set to a value that usually -results in one roundtrip to the authority servers. If too many queries +results in one roundtrip to the authority servers. If too many queries arrive, then 50% of the queries are allowed to run to completion, and -the other 50% are replaced with the new incoming query if they have already -spent more than their allowed time. This protects against denial of +the other 50% are replaced with the new incoming query if they have already +spent more than their allowed time. This protects against denial of service by slow queries or high query rates. Default 200 milliseconds. -The effect is that the qps for long-lasting queries is about +The effect is that the qps for long-lasting queries is about (numqueriesperthread / 2) / (average time for such long queries) qps. The qps for short queries can be about (numqueriesperthread / 2) / (jostletimeout in whole seconds) qps per thread, about (1024/2)*5 = 2560 @@ -252,6 +263,12 @@ the ID and remote IP of packets, and unwanted packets are added to the unwanted packet counter. .TP +.B unknown\-server\-time\-limit: \fI +The wait time in msec for waiting for an unknown server to reply. +Increase this if you are behind a slow satellite link, to eg. 1128. +That would then avoid re\-querying every initial query because it times out. +Default is 376 msec. +.TP .B so\-rcvbuf: \fI If not 0, then set the SO_RCVBUF socket option to get more buffer space on UDP port 53 incoming queries. So that short spikes on busy @@ -277,22 +294,25 @@ .B so\-reuseport: \fI If yes, then open dedicated listening sockets for incoming queries for each thread and try to set the SO_REUSEPORT socket option on each socket. May -distribute incoming queries to threads more evenly. Default is no. On Linux -it is supported in kernels >= 3.9. On other systems, FreeBSD, OSX it may -also work. You can enable it (on any platform and kernel), +distribute incoming queries to threads more evenly. Default is yes. +On Linux it is supported in kernels >= 3.9. On other systems, FreeBSD, OSX +it may also work. You can enable it (on any platform and kernel), it then attempts to open the port and passes the option if it was available at compile time, if that works it is used, if it fails, it continues silently (unless verbosity 3) without the option. +At extreme load it could be better to turn it off to distribute the queries +evenly, reported for Linux systems (4.4.x). .TP .B ip\-transparent: \fI If yes, then use IP_TRANSPARENT socket option on sockets where unbound is listening for incoming traffic. Default no. Allows you to bind to -non\-local interfaces. For example for non\-existant IP addresses that +non\-local interfaces. For example for non\-existent IP addresses that are going to exist later on, with host failover configuration. This is a lot like interface\-automatic, but that one services all interfaces and with this option you can select which (future) interfaces unbound provides service on. This option needs unbound to be started with root -permissions on some systems. The option uses IP_BINDANY on FreeBSD systems. +permissions on some systems. The option uses IP_BINDANY on FreeBSD systems +and SO_BINDANY on OpenBSD systems. .TP .B ip\-freebind: \fI If yes, then use IP_FREEBIND socket option on sockets where unbound @@ -308,15 +328,13 @@ .TP .B rrset\-cache\-slabs: \fI Number of slabs in the RRset cache. Slabs reduce lock contention by threads. -Must be set to a power of 2. +Must be set to a power of 2. .TP .B cache\-max\-ttl: \fI -Time to live maximum for RRsets and messages in the cache. Default is -86400 seconds (1 day). If the maximum kicks in, responses to clients -still get decrementing TTLs based on the original (larger) values. -When the internal TTL expires, the cache item has expired. +Time to live maximum for RRsets and messages in the cache. Default is +86400 seconds (1 day). When the TTL expires, the cache item has expired. Can be set lower to force the resolver to query for data often, and not -trust (very large) TTL values. +trust (very large) TTL values. Downstream clients also see the lower TTL. .TP .B cache\-min\-ttl: \fI Time to live minimum for RRsets and messages in the cache. Default is 0. @@ -323,20 +341,21 @@ If the minimum kicks in, the data is cached for longer than the domain owner intended, and thus less queries are made to look up the data. Zero makes sure the data in the cache is as the domain owner intended, -higher values, especially more than an hour or so, can lead to trouble as +higher values, especially more than an hour or so, can lead to trouble as the data in the cache does not match up with the actual data any more. .TP .B cache\-max\-negative\-ttl: \fI Time to live maximum for negative responses, these have a SOA in the authority section that is limited in time. Default is 3600. +This applies to nxdomain and nodata answers. .TP .B infra\-host\-ttl: \fI -Time to live for entries in the host cache. The host cache contains +Time to live for entries in the host cache. The host cache contains roundtrip timing, lameness and EDNS support information. Default is 900. .TP .B infra\-cache\-slabs: \fI -Number of slabs in the infrastructure cache. Slabs reduce lock contention -by threads. Must be set to a power of 2. +Number of slabs in the infrastructure cache. Slabs reduce lock contention +by threads. Must be set to a power of 2. .TP .B infra\-cache\-numhosts: \fI Number of hosts for which information is cached. Default is 10000. @@ -372,7 +391,7 @@ .TP .B tcp\-mss: \fI Maximum segment size (MSS) of TCP socket on which the server responds -to queries. Value lower than common MSS on Ethernet +to queries. Value lower than common MSS on Ethernet (1220 for example) will address path MTU problem. Note that not all platform supports socket option to set MSS (TCP_MAXSEG). Default is system default MSS determined by interface MTU and @@ -386,69 +405,186 @@ Default is system default MSS determined by interface MTU and negotiation between Unbound and other servers. .TP +.B tcp-idle-timeout: \fI\fR +The period Unbound will wait for a query on a TCP connection. +If this timeout expires Unbound closes the connection. +This option defaults to 30000 milliseconds. +When the number of free incoming TCP buffers falls below 50% of the +total number configured, the option value used is progressively +reduced, first to 1% of the configured value, then to 0.2% of the +configured value if the number of free buffers falls below 35% of the +total number configured, and finally to 0 if the number of free buffers +falls below 20% of the total number configured. A minimum timeout of +200 milliseconds is observed regardless of the option value used. +.TP +.B edns-tcp-keepalive: \fI\fR +Enable or disable EDNS TCP Keepalive. Default is no. +.TP +.B edns-tcp-keepalive-timeout: \fI\fR +The period Unbound will wait for a query on a TCP connection when +EDNS TCP Keepalive is active. If this timeout expires Unbound closes +the connection. If the client supports the EDNS TCP Keepalive option, +Unbound sends the timeout value to the client to encourage it to +close the connection before the server times out. +This option defaults to 120000 milliseconds. +When the number of free incoming TCP buffers falls below 50% of +the total number configured, the advertised timeout is progressively +reduced to 1% of the configured value, then to 0.2% of the configured +value if the number of free buffers falls below 35% of the total number +configured, and finally to 0 if the number of free buffers falls below +20% of the total number configured. +A minimum actual timeout of 200 milliseconds is observed regardless of the +advertised timeout. +.TP .B tcp\-upstream: \fI Enable or disable whether the upstream queries use TCP only for transport. Default is no. Useful in tunneling scenarios. .TP +.B udp\-upstream\-without\-downstream: \fI +Enable udp upstream even if do-udp is no. Default is no, and this does not +change anything. Useful for TLS service providers, that want no udp downstream +but use udp to fetch data upstream. +.TP +.B tls\-upstream: \fI +Enabled or disable whether the upstream queries use TLS only for transport. +Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in +TCP wireformat. The other server must support this (see +\fBtls\-service\-key\fR). +If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to +load CA certs, otherwise the connections cannot be authenticated. +This option enables TLS for all of them, but if you do not set this you can +configure TLS specifically for some forward zones with forward\-tls\-upstream. And also with stub\-tls\-upstream. +.TP .B ssl\-upstream: \fI -Enabled or disable whether the upstream queries use SSL only for transport. -Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in -TCP wireformat. The other server must support this (see \fBssl\-service\-key\fR). +Alternate syntax for \fBtls\-upstream\fR. If both are present in the config +file the last is used. .TP -.B ssl\-service-key: \fI -If enabled, the server provider SSL service on its TCP sockets. The clients -have to use ssl\-upstream: yes. The file is the private key for the TLS -session. The public certificate is in the ssl\-service\-pem file. Default -is "", turned off. Requires a restart (a reload is not enough) if changed, -because the private key is read while root permissions are held and before -chroot (if any). Normal DNS TCP service is not provided and gives errors, -this service is best run with a different \fBport:\fR config or \fI@port\fR -suffixes in the \fBinterface\fR config. +.B tls\-service\-key: \fI +If enabled, the server provides TLS service on the TCP ports marked +implicitly or explicitly for TLS service with tls\-port. The file must +contain the private key for the TLS session, the public certificate is in +the tls\-service\-pem file and it must also be specified if tls\-service\-key +is specified. The default is "", turned off. Enabling or disabling +this service requires a restart (a reload is not enough), because the +key is read while root permissions are held and before chroot (if any). +The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide +normal DNS TCP service. .TP -.B ssl\-service\-pem: \fI -The public key certificate pem file for the ssl service. Default is "", +.B ssl\-service\-key: \fI +Alternate syntax for \fBtls\-service\-key\fR. +.TP +.B tls\-service\-pem: \fI +The public key certificate pem file for the tls service. Default is "", turned off. .TP +.B ssl\-service\-pem: \fI +Alternate syntax for \fBtls\-service\-pem\fR. +.TP +.B tls\-port: \fI +The port number on which to provide TCP TLS service, default 853, only +interfaces configured with that port number as @number get the TLS service. +.TP .B ssl\-port: \fI -The port number on which to provide TCP SSL service, default 853, only -interfaces configured with that port number as @number get the SSL service. +Alternate syntax for \fBtls\-port\fR. .TP +.B tls\-cert\-bundle: \fI +If null or "", no file is used. Set it to the certificate bundle file, +for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used +for authenticating connections made to outside peers. For example auth\-zone +urls, and also DNS over TLS connections. +.TP +.B ssl\-cert\-bundle: \fI +Alternate syntax for \fBtls\-cert\-bundle\fR. +.TP +.B tls\-win\-cert: \fI +Add the system certificates to the cert bundle certificates for authentication. +If no cert bundle, it uses only these certificates. Default is no. +On windows this option uses the certificates from the cert store. Use +the tls\-cert\-bundle option on other systems. +.TP +.B tls\-additional\-port: \fI +List portnumbers as tls\-additional\-port, and when interfaces are defined, +eg. with the @port suffix, as this port number, they provide dns over TLS +service. Can list multiple, each on a new statement. +.TP +.B tls-session-ticket-keys: \fI +If not "", lists files with 80 bytes of random contents that are used to +perform TLS session resumption for clients using the unbound server. +These files contain the secret key for the TLS session tickets. +First key use to encrypt and decrypt TLS session tickets. +Other keys use to decrypt only. With this you can roll over to new keys, +by generating a new first file and allowing decrypt of the old file by +listing it after the first file for some time, after the wait clients are not +using the old key any more and the old key can be removed. +One way to create the file is dd if=/dev/random bs=1 count=80 of=ticket.dat +The first 16 bytes should be different from the old one if you create a second key, that is the name used to identify the key. Then there is 32 bytes random +data for an AES key and then 32 bytes random data for the HMAC key. +.TP +.B tls\-ciphers: \fI +Set the list of ciphers to allow when serving TLS. Use "" for defaults, +and that is the default. +.TP +.B tls\-ciphersuites: \fI +Set the list of ciphersuites to allow when serving TLS. This is for newer +TLS 1.3 connections. Use "" for defaults, and that is the default. +.TP +.B use\-systemd: \fI +Enable or disable systemd socket activation. +Default is no. +.TP .B do\-daemonize: \fI Enable or disable whether the unbound server forks into the background as -a daemon. Default is yes. +a daemon. Set the value to \fIno\fR when unbound runs as systemd service. +Default is yes. .TP +.B tcp\-connection\-limit: \fI +Allow up to \fIlimit\fR simultaneous TCP connections from the given netblock. +When at the limit, further connections are accepted but closed immediately. +This option is experimental at this time. +.TP .B access\-control: \fI -The netblock is given as an IP4 or IP6 address with /size appended for a -classless network block. The action can be \fIdeny\fR, \fIrefuse\fR, -\fIallow\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or \fIrefuse_non_local\fR. +The netblock is given as an IP4 or IP6 address with /size appended for a +classless network block. The action can be \fIdeny\fR, \fIrefuse\fR, +\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or +\fIrefuse_non_local\fR. The most specific netblock match is used, if none match \fIdeny\fR is used. +The order of the access\-control statements therefore does not matter. .IP The action \fIdeny\fR stops queries from hosts from that netblock. .IP -The action \fIrefuse\fR stops queries too, but sends a DNS rcode REFUSED +The action \fIrefuse\fR stops queries too, but sends a DNS rcode REFUSED error message back. .IP -The action \fIallow\fR gives access to clients from that netblock. -It gives only access for recursion clients (which is +The action \fIallow\fR gives access to clients from that netblock. +It gives only access for recursion clients (which is what almost all clients need). Nonrecursive queries are refused. .IP -The \fIallow\fR action does allow nonrecursive queries to access the +The \fIallow\fR action does allow nonrecursive queries to access the local\-data that is configured. The reason is that this does not involve -the unbound server recursive lookup algorithm, and static data is served -in the reply. This supports normal operations where nonrecursive queries -are made for the authoritative data. For nonrecursive queries any replies +the unbound server recursive lookup algorithm, and static data is served +in the reply. This supports normal operations where nonrecursive queries +are made for the authoritative data. For nonrecursive queries any replies from the dynamic cache are refused. .IP -The action \fIallow_snoop\fR gives nonrecursive access too. This give -both recursive and non recursive access. The name \fIallow_snoop\fR refers +The \fIallow_setrd\fR action ignores the recursion desired (RD) bit and +treats all requests as if the recursion desired bit is set. Note that this +behavior violates RFC 1034 which states that a name server should never perform +recursive service unless asked via the RD bit since this interferes with +trouble shooting of name servers and their databases. This prohibited behavior +may be useful if another DNS server must forward requests for specific +zones to a resolver DNS server, but only supports stub domains and +sends queries to the resolver DNS server with the RD bit cleared. +.IP +The action \fIallow_snoop\fR gives nonrecursive access too. This give +both recursive and non recursive access. The name \fIallow_snoop\fR refers to cache snooping, a technique to use nonrecursive queries to examine -the cache contents (for malicious acts). However, nonrecursive queries can -also be a valuable debugging tool (when you want to examine the cache +the cache contents (for malicious acts). However, nonrecursive queries can +also be a valuable debugging tool (when you want to examine the cache contents). In that case use \fIallow_snoop\fR for your administration host. .IP By default only localhost is \fIallow\fRed, the rest is \fIrefuse\fRd. -The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS -protocol is not designed to handle dropped packets due to policy, and +The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS +protocol is not designed to handle dropped packets due to policy, and dropping may result in (possibly excessive) retried queries. .IP The deny_non_local and refuse_non_local settings are for hosts that are @@ -474,11 +610,14 @@ .B access\-control\-tag\-data: \fI <"resource record string"> Set redirect data for particular tag for given access control element. .TP +.B access\-control\-view: \fI +Set view for given access control element. +.TP .B chroot: \fI If chroot is enabled, you should pass the configfile (from the commandline) as a full path from the original root. After the -chroot has been performed the now defunct portion of the config -file path is removed to be able to reread the config after a reload. +chroot has been performed the now defunct portion of the config +file path is removed to be able to reread the config after a reload. .IP All other file paths (working dir, logfile, roothints, and key files) can be specified in several ways: @@ -489,22 +628,23 @@ .IP The pidfile can be either a relative path to the working directory, or an absolute path relative to the original root. It is written just prior -to chroot and dropping permissions. This allows the pidfile to be +to chroot and dropping permissions. This allows the pidfile to be /var/run/unbound.pid and the chroot to be /var/unbound, for example. .IP Additionally, unbound may need to access /dev/random (for entropy) from inside the chroot. .IP -If given a chroot is done to the given directory. The default is -"/var/unbound". If you give "" no chroot is performed. +If given a chroot is done to the given directory. By default chroot is +enabled and the default is "/var/unbound". If you give "" no +chroot is performed. .TP .B username: \fI If given, after binding the port the user privileges are dropped. Default is -"unbound". If you give username: "" no user change is performed. +"unbound". If you give username: "" no user change is performed. .IP If this user is not capable of binding the port, reloads (by signal HUP) will still retain the opened ports. -If you change the port number in the config file, and that new port number +If you change the port number in the config file, and that new port number requires privileges, then a reload will fail; a restart is needed. .TP .B directory: \fI @@ -516,21 +656,28 @@ .TP .B logfile: \fI If "" is given, logging goes to stderr, or nowhere once daemonized. -The logfile is appended to, in the following format: +The logfile is appended to, in the following format: .nf -[seconds since 1970] unbound[pid:tid]: type: message. +[seconds since 1970] unbound[pid:tid]: type: message. .fi If this option is given, the use\-syslog is option is set to "no". -The logfile is reopened (for append) when the config file is reread, on +The logfile is reopened (for append) when the config file is reread, on SIGHUP. .TP .B use\-syslog: \fI -Sets unbound to send log messages to the syslogd, using -\fIsyslog\fR(3). +Sets unbound to send log messages to the syslogd, using +\fIsyslog\fR(3). The log facility LOG_DAEMON is used, with identity "unbound". The logfile setting is overridden when use\-syslog is turned on. The default is to log to syslog. .TP +.B log\-identity: \fI +If "" is given (default), then the name of the executable, usually "unbound" +is used to report to the log. Enter a string to override it +with that, which is useful on systems that run more than one instance of +unbound, with different configurations, so that the logs can be easily +distinguished against. +.TP .B log\-time\-ascii: \fI Sets logfile lines to use a timestamp in UTC ascii. Default is no, which prints the seconds since 1970 in brackets. No effect if using syslog, in @@ -542,21 +689,43 @@ lines which makes the server (significantly) slower. Odd (nonprintable) characters in names are printed as '?'. .TP +.B log\-replies: \fI +Prints one line per reply to the log, with the log timestamp and IP address, +name, type, class, return code, time to resolve, from cache and response size. +Default is no. Note that it takes time to print these +lines which makes the server (significantly) slower. Odd (nonprintable) +characters in names are printed as '?'. +.TP +.B log\-tag\-queryreply: \fI +Prints the word 'query' and 'reply' with log\-queries and log\-replies. +This makes filtering logs easier. The default is off (for backwards +compatibility). +.TP +.B log\-local\-actions: \fI +Print log lines to inform about local zone actions. These lines are like the +local\-zone type inform prints out, but they are also printed for the other +types of local zones. +.TP +.B log\-servfail: \fI +Print log lines that say why queries return SERVFAIL to clients. +This is separate from the verbosity debug logs, much smaller, and printed +at the error level, not the info level of debug info from verbosity. +.TP .B pidfile: \fI -The process id is written to the file. Default is "/var/unbound/unbound.pid". +The process id is written to the file. Default is "/var/unbound/unbound.pid". So, .nf -kill \-HUP `cat /var/unbound/unbound.pid` +kill \-HUP `cat /var/unbound/unbound.pid` .fi triggers a reload, .nf -kill \-TERM `cat /var/unbound/unbound.pid` +kill \-TERM `cat /var/unbound/unbound.pid` .fi gracefully terminates. .TP .B root\-hints: \fI Read the root hints from this file. Default is nothing, using builtin hints -for the IN class. The file has the format of zone files, with root +for the IN class. The file has the format of zone files, with root nameserver names and addresses only. The default may become outdated, when servers change, therefore it is good practice to use a root\-hints file. .TP @@ -574,25 +743,28 @@ Set the version to report. If set to "", the default, then the package version is returned. .TP +.B hide\-trustanchor: \fI +If enabled trustanchor.unbound queries are refused. +.TP .B target\-fetch\-policy: \fI<"list of numbers"> Set the target fetch policy used by unbound to determine if it should fetch nameserver target addresses opportunistically. The policy is described per -dependency depth. +dependency depth. .IP The number of values determines the maximum dependency depth -that unbound will pursue in answering a query. +that unbound will pursue in answering a query. A value of \-1 means to fetch all targets opportunistically for that dependency depth. A value of 0 means to fetch on demand only. A positive value fetches -that many targets opportunistically. +that many targets opportunistically. .IP Enclose the list between quotes ("") and put spaces between numbers. The default is "3 2 1 0 0". Setting all zeroes, "0 0 0 0 0" gives behaviour -closer to that of BIND 9, while setting "\-1 \-1 \-1 \-1 \-1" gives behaviour +closer to that of BIND 9, while setting "\-1 \-1 \-1 \-1 \-1" gives behaviour rumoured to be closer to that of BIND 8. .TP .B harden\-short\-bufsize: \fI Very small EDNS buffer sizes from queries are ignored. Default is off, since -it is legal protocol wise to send these, and unbound tries to give very +it is legal protocol wise to send these, and unbound tries to give very small answers to these queries, where possible. .TP .B harden\-large\-queries: \fI @@ -606,30 +778,31 @@ .B harden\-dnssec\-stripped: \fI Require DNSSEC data for trust\-anchored zones, if such data is absent, the zone becomes bogus. If turned off, and no DNSSEC data is received -(or the DNSKEY data fails to validate), then the zone is made insecure, -this behaves like there is no trust anchor. You could turn this off if -you are sometimes behind an intrusive firewall (of some sort) that -removes DNSSEC data from packets, or a zone changes from signed to -unsigned to badly signed often. If turned off you run the risk of a +(or the DNSKEY data fails to validate), then the zone is made insecure, +this behaves like there is no trust anchor. You could turn this off if +you are sometimes behind an intrusive firewall (of some sort) that +removes DNSSEC data from packets, or a zone changes from signed to +unsigned to badly signed often. If turned off you run the risk of a downgrade attack that disables security for a zone. Default is on. .TP .B harden\-below\-nxdomain: \fI -From draft\-vixie\-dnsext\-resimprove, returns nxdomain to queries for a name +From RFC 8020 (with title "NXDOMAIN: There Really Is Nothing Underneath"), +returns nxdomain to queries for a name below another name that is already known to be nxdomain. DNSSEC mandates noerror for empty nonterminals, hence this is possible. Very old software might return nxdomain for empty nonterminals (that usually happen for reverse IP address lookups), and thus may be incompatible with this. To try to avoid this only DNSSEC-secure nxdomains are used, because the old software does not -have DNSSEC. Default is off. -Currently, draft\-ietf\-dnsop\-nxdomain\-cut promotes this technique. +have DNSSEC. Default is on. +The nxdomain must be secure, this means nsec3 with optout is insufficient. .TP .B harden\-referral\-path: \fI Harden the referral path by performing additional queries for infrastructure data. Validates the replies if trust anchors are configured and the zones are signed. This enforces DNSSEC validation on nameserver -NS sets and the nameserver addresses that are encountered on the referral +NS sets and the nameserver addresses that are encountered on the referral path to the answer. -Default off, because it burdens the authority servers, and it is +Default no, because it burdens the authority servers, and it is not RFC standard, and could lead to performance problems because of the extra query load that is generated. Experimental option. If you enable it consider adding more numbers after the target\-fetch\-policy @@ -644,9 +817,9 @@ .TP .B use\-caps\-for\-id: \fI Use 0x20\-encoded random bits in the query to foil spoof attempts. -This perturbs the lowercase and uppercase of query names sent to -authority servers and checks if the reply still has the correct casing. -Disabled by default. +This perturbs the lowercase and uppercase of query names sent to +authority servers and checks if the reply still has the correct casing. +Disabled by default. This feature is an experimental implementation of draft dns\-0x20. .TP .B caps\-whitelist: \fI @@ -657,10 +830,23 @@ .TP .B qname\-minimisation: \fI Send minimum amount of information to upstream servers to enhance privacy. -Only sent minimum required labels of the QNAME and set QTYPE to NS when -possible. Best effort approach, full QNAME and original QTYPE will be sent when -upstream replies with a RCODE other than NOERROR. Default is off. +Only send minimum required labels of the QNAME and set QTYPE to A when +possible. Best effort approach; full QNAME and original QTYPE will be sent when +upstream replies with a RCODE other than NOERROR, except when receiving +NXDOMAIN from a DNSSEC signed zone. Default is yes. .TP +.B qname\-minimisation\-strict: \fI +QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to +potentially broken nameservers. A lot of domains will not be resolvable when +this option in enabled. Only use if you know what you are doing. +This option only has effect when qname-minimisation is enabled. Default is off. +.TP +.B aggressive\-nsec: \fI +Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN +and other denials, using information from previous NXDOMAINs answers. +Default is no. It helps to reduce the query rate towards targets that get +a very high nonexistent name lookup rate. +.TP .B private\-address: \fI Give IPv4 of IPv6 addresses or classless subnets. These are addresses on your private network, and are not allowed to be returned for @@ -682,7 +868,7 @@ .TP .B private\-domain: \fI Allow this domain, and all its subdomains to contain private addresses. -Give multiple times to allow multiple domain names to contain private +Give multiple times to allow multiple domain names to contain private addresses. Default is none. .TP .B unwanted\-reply\-threshold: \fI @@ -693,7 +879,7 @@ is suggested. Default is 0 (turned off). .TP .B do\-not\-query\-address: \fI -Do not query the given IP address. Can be IP4 or IP6. Append /num to +Do not query the given IP address. Can be IP4 or IP6. Append /num to indicate a classless delegation netblock, for example like 10.2.3.4/24 or 2001::11/64. .TP @@ -708,12 +894,18 @@ 10 percent more traffic and load on the machine, but popular items do not expire from the cache. .TP -.B prefetch-key: \fI +.B prefetch\-key: \fI If yes, fetch the DNSKEYs earlier in the validation process, when a DS record is encountered. This lowers the latency of requests. It does use a little more CPU. Also if the cache is set to 0, it is no use. Default is no. .TP -.B rrset-roundrobin: \fI +.B deny\-any: \fI +If yes, deny queries of type ANY with an empty response. Default is no. +If disabled, unbound responds with a short list of resource records if some +can be found in the cache and makes the upstream type ANY query if there +are none. +.TP +.B rrset\-roundrobin: \fI If yes, Unbound rotates RRSet order in response (the random number is taken from the query ID, for speed and thread safety). Default is no. .TP @@ -721,9 +913,11 @@ If yes, Unbound doesn't insert authority/additional sections into response messages when those sections are not required. This reduces response size significantly, and may avoid TCP fallback for some responses. -This may cause a slight speedup. The default is no, because the DNS +This may cause a slight speedup. The default is yes, even though the DNS protocol RFCs mandate these sections, and the additional content could -be of use and save roundtrips for clients. +be of use and save roundtrips for clients. Because they are not used, +and the saved roundtrips are easier saved with prefetch, whilst this is +faster. .TP .B disable-dnssec-lame-check: \fI If true, disables the DNSSEC lameness check in the iterator. This check @@ -739,6 +933,12 @@ Setting this to "validator iterator" will turn on DNSSEC validation. The ordering of the modules is important. You must also set trust\-anchors for validation to be useful. +The default is "validator iterator". When the server is built with +EDNS client subnet support the default is "subnetcache validator iterator". +Most modules that need to be listed here have to be listed at the beginning +of the line. The cachedb module has to be listed just before the iterator. +The python module can be listed in different places, it then processes the +output of the module it is just before. .TP .B trust\-anchor\-file: \fI File with trusted keys for validation. Both DS and DNSKEY entries can appear @@ -752,7 +952,8 @@ \fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated, so the unbound user must have write permission. Write permission to the file, but also to the directory it is in (to create a temporary file, which is -necessary to deal with filesystem full events). +necessary to deal with filesystem full events), it must also be inside the +chroot (if that is used). .TP .B trust\-anchor: \fI<"Resource Record"> A DS or DNSKEY RR for a key to use for validation. Multiple entries can be @@ -759,17 +960,23 @@ given to specify multiple trusted keys, in addition to the trust\-anchor\-files. The resource record is entered in the same format as 'dig' or 'drill' prints them, the same format as in the zone file. Has to be on a single line, with -"" around it. A TTL can be specified for ease of cut and paste, but is ignored. +"" around it. A TTL can be specified for ease of cut and paste, but is ignored. A class can be specified, but class IN is default. .TP .B trusted\-keys\-file: \fI File with trusted keys for validation. Specify more than one file with several entries, one file per entry. Like \fBtrust\-anchor\-file\fR -but has a different file format. Format is BIND\-9 style format, +but has a different file format. Format is BIND\-9 style format, the trusted\-keys { name flag proto algo "key"; }; clauses are read. It is possible to use wildcards with this statement, the wildcard is expanded on start and on reload. .TP +.B trust\-anchor\-signaling: \fI +Send RFC8145 key tag query after trust anchor priming. Default is on. +.TP +.B root\-key\-sentinel: \fI +Root key trust anchor sentinel. Default is on. +.TP .B dlv\-anchor\-file: \fI This option was used during early days DNSSEC deployment when no parent-side DS record registrations were easily available. Nowadays, it is best to have @@ -777,9 +984,9 @@ File with trusted keys for DLV (DNSSEC Lookaside Validation). Both DS and DNSKEY entries can be used in the file, in the same format as for \fItrust\-anchor\-file:\fR statements. Only one DLV can be configured, more -would be slow. The DLV configured is used as a root trusted DLV, this -means that it is a lookaside for the root. Default is "", or no dlv anchor file. -DLV is going to be decommissioned. Please do not use it any more. +would be slow. The DLV configured is used as a root trusted DLV, this +means that it is a lookaside for the root. Default is "", or no dlv anchor +file. DLV is going to be decommissioned. Please do not use it any more. .TP .B dlv\-anchor: \fI<"Resource Record"> Much like trust\-anchor, this is a DLV anchor with the DS or DNSKEY inline. @@ -791,17 +998,17 @@ domain secure with a DS record, such a DS record is then ignored. Also keys from DLV are ignored for the domain. Can be given multiple times to specify multiple domains that are treated as if unsigned. If you set -trust anchors for the domain they override this setting (and the domain +trust anchors for the domain they override this setting (and the domain is secured). .IP This can be useful if you want to make sure a trust anchor for external -lookups does not affect an (unsigned) internal domain. A DS record +lookups does not affect an (unsigned) internal domain. A DS record externally can create validation failures for that internal domain. .TP .B val\-override\-date: \fI Default is "" or "0", which disables this debugging feature. If enabled by giving a RRSIG style date, that date is used for verifying RRSIG inception -and expiration dates, instead of the current date. Do not set this unless +and expiration dates, instead of the current date. Do not set this unless you are debugging signature inception and expiration. The value \-1 ignores the date altogether, useful for some special applications. .TP @@ -831,7 +1038,7 @@ Instruct the validator to remove data from the additional section of secure messages that are not signed properly. Messages that are insecure, bogus, indeterminate or unchecked are not affected. Default is yes. Use this setting -to protect the users that rely on this validator for authentication from +to protect the users that rely on this validator for authentication from potentially bad data in the additional section. .TP .B val\-log\-level: \fI @@ -846,10 +1053,10 @@ .B val\-permissive\-mode: \fI Instruct the validator to mark bogus messages as indeterminate. The security checks are performed, but if the result is bogus (failed security), the -reply is not withheld from the client with SERVFAIL as usual. The client -receives the bogus data. For messages that are found to be secure the AD bit +reply is not withheld from the client with SERVFAIL as usual. The client +receives the bogus data. For messages that are found to be secure the AD bit is set in replies. Also logging is performed as for full validation. -The default value is "no". +The default value is "no". .TP .B ignore\-cd\-flag: \fI Instruct unbound to ignore the CD flag from clients and refuse to @@ -859,12 +1066,28 @@ the clients, and then unbound provides them with DNSSEC protection. The default value is "no". .TP +.B serve\-expired: \fI +If enabled, unbound attempts to serve old responses from cache with a +TTL of 0 in the response without waiting for the actual resolution to finish. +The actual resolution answer ends up in the cache later on. Default is "no". +.TP +.B serve\-expired\-ttl: \fI +Limit serving of expired responses to configured seconds after expiration. 0 +disables the limit. This option only applies when \fBserve\-expired\fR is +enabled. The default is 0. +.TP +.B serve\-expired\-ttl\-reset: \fI +Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a +failed attempt to retrieve the record from upstream. This makes sure that the +expired records will be served as long as there are queries for it. Default is +"no". +.TP .B val\-nsec3\-keysize\-iterations: \fI<"list of values"> List of keysize and iteration count values, separated by spaces, surrounded by quotes. Default is "1024 150 2048 500 4096 2500". This determines the maximum allowed NSEC3 iteration count before a message is simply marked insecure instead of performing the many hashing iterations. The list must -be in ascending order and have at least one entry. If you set it to +be in ascending order and have at least one entry. If you set it to "1024 65535" there is no restriction to NSEC3 iteration values. This table must be kept short; a very long list could cause slower operation. .TP @@ -899,7 +1122,7 @@ .TP .B key\-cache\-slabs: \fI Number of slabs in the key cache. Slabs reduce lock contention by threads. -Must be set to a power of 2. Setting (close) to the number of cpus is a +Must be set to a power of 2. Setting (close) to the number of cpus is a reasonable guess. .TP .B neg\-cache\-size: \fI @@ -907,7 +1130,7 @@ A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes or gigabytes (1024*1024 bytes in a megabyte). .TP -.B unblock\-lan\-zones: \fI +.B unblock\-lan\-zones: \fI Default is disabled. If enabled, then for private address space, the reverse lookups are no longer filtered. This allows unbound when running as dns service on a host where it provides service for that host, @@ -918,7 +1141,7 @@ lookups should be filtered (RFC compliance), this also stops potential data leakage about the local network to the upstream DNS servers. .TP -.B insecure\-lan\-zones: \fI +.B insecure\-lan\-zones: \fI Default is disabled. If enabled, then reverse lookups in private address space are not validated. This is usually required whenever \fIunblock\-lan\-zones\fR is used. @@ -927,7 +1150,7 @@ Configure a local zone. The type determines the answer to give if there is no match from local\-data. The types are deny, refuse, static, transparent, redirect, nodefault, typetransparent, inform, inform_deny, -always_transparent, always_refuse, always_nxdomain, +inform_redirect, always_transparent, always_refuse, always_nxdomain, noview, and are explained below. After that the default settings are listed. Use local\-data: to enter data into the local zone. Answers for local zones are authoritative DNS answers. By default the zones are class IN. @@ -950,7 +1173,7 @@ For a negative answer a SOA is included in the answer if present as local\-data for the zone apex domain. .TP 10 -\h'5'\fItransparent\fR +\h'5'\fItransparent\fR If there is a match from local data, the query is answered. Otherwise if the query has a different name, the query is resolved normally. If the query is for a name given in localdata but no such type of data is @@ -958,7 +1181,7 @@ If no local\-zone is given local\-data causes a transparent zone to be created by default. .TP 10 -\h'5'\fItypetransparent\fR +\h'5'\fItypetransparent\fR If there is a match from local data, the query is answered. If the query is for a different name, or for the same name but for a different type, the query is resolved normally. So, similar to transparent but types @@ -965,115 +1188,144 @@ that are not listed in local data are resolved normally, so if an A record is in the local data that does not cause a nodata reply for AAAA queries. .TP 10 -\h'5'\fIredirect\fR +\h'5'\fIredirect\fR The query is answered from the local data for the zone name. There may be no local data beneath the zone name. This answers queries for the zone, and all subdomains of the zone with the local data for the zone. It can be used to redirect a domain to return a different address record -to the end user, with -local\-zone: "example.com." redirect and +to the end user, with +local\-zone: "example.com." redirect and local\-data: "example.com. A 127.0.0.1" queries for www.example.com and www.foo.example.com are redirected, so that users with web browsers cannot access sites with suffix example.com. .TP 10 -\h'5'\fIinform\fR -The query is answered normally. The client IP address (@portnumber) -is printed to the logfile. The log message is: timestamp, unbound-pid, -info: zonename inform IP@port queryname type class. This option can be -used for normal resolution, but machines looking up infected names are -logged, eg. to run antivirus on them. +\h'5'\fIinform\fR +The query is answered normally, same as transparent. The client IP +address (@portnumber) is printed to the logfile. The log message is: +timestamp, unbound-pid, info: zonename inform IP@port queryname type +class. This option can be used for normal resolution, but machines +looking up infected names are logged, eg. to run antivirus on them. .TP 10 -\h'5'\fIinform_deny\fR +\h'5'\fIinform_deny\fR The query is dropped, like 'deny', and logged, like 'inform'. Ie. find infected machines without answering the queries. .TP 10 -\h'5'\fIalways_transparent\fR +\h'5'\fIinform_redirect\fR +The query is redirected, like 'redirect', and logged, like 'inform'. +Ie. answer queries with fixed data and also log the machines that ask. +.TP 10 +\h'5'\fIalways_transparent\fR Like transparent, but ignores local data and resolves normally. .TP 10 -\h'5'\fIalways_refuse\fR +\h'5'\fIalways_refuse\fR Like refuse, but ignores local data and refuses the query. .TP 10 -\h'5'\fIalways_nxdomain\fR +\h'5'\fIalways_nxdomain\fR Like static, but ignores local data and returns nxdomain for the query. .TP 10 -\h'5'\fInodefault\fR +\h'5'\fInoview\fR +Breaks out of that view and moves towards the global local zones for answer +to the query. If the view first is no, it'll resolve normally. If view first +is enabled, it'll break perform that step and check the global answers. +For when the view has view specific overrides but some zone has to be +answered from global local zone contents. +.TP 10 +\h'5'\fInodefault\fR Used to turn off default contents for AS112 zones. The other types -also turn off default contents for the zone. The 'nodefault' option -has no other effect than turning off default contents for the +also turn off default contents for the zone. The 'nodefault' option +has no other effect than turning off default contents for the given zone. Use \fInodefault\fR if you use exactly that zone, if you want to use a subzone, use \fItransparent\fR. .P -The default zones are localhost, reverse 127.0.0.1 and ::1, the onion and -the AS112 zones. The AS112 zones are reverse DNS zones for private use and -reserved IP addresses for which the servers on the internet cannot provide -correct answers. They are configured by default to give nxdomain (no reverse -information) answers. The defaults can be turned off by specifying your -own local\-zone of that name, or using the 'nodefault' type. Below is a -list of the default zone contents. +The default zones are localhost, reverse 127.0.0.1 and ::1, the onion, test, +invalid and the AS112 zones. The AS112 zones are reverse DNS zones for +private use and reserved IP addresses for which the servers on the internet +cannot provide correct answers. They are configured by default to give +nxdomain (no reverse information) answers. The defaults can be turned off +by specifying your own local\-zone of that name, or using the 'nodefault' +type. Below is a list of the default zone contents. .TP 10 -\h'5'\fIlocalhost\fR +\h'5'\fIlocalhost\fR The IP4 and IP6 localhost information is given. NS and SOA records are provided for completeness and to satisfy some DNS update tools. Default content: .nf -local\-zone: "localhost." static +local\-zone: "localhost." redirect local\-data: "localhost. 10800 IN NS localhost." -local\-data: "localhost. 10800 IN +local\-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" local\-data: "localhost. 10800 IN A 127.0.0.1" local\-data: "localhost. 10800 IN AAAA ::1" .fi .TP 10 -\h'5'\fIreverse IPv4 loopback\fR +\h'5'\fIreverse IPv4 loopback\fR Default content: .nf local\-zone: "127.in\-addr.arpa." static local\-data: "127.in\-addr.arpa. 10800 IN NS localhost." -local\-data: "127.in\-addr.arpa. 10800 IN +local\-data: "127.in\-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" -local\-data: "1.0.0.127.in\-addr.arpa. 10800 IN +local\-data: "1.0.0.127.in\-addr.arpa. 10800 IN PTR localhost." .fi .TP 10 -\h'5'\fIreverse IPv6 loopback\fR +\h'5'\fIreverse IPv6 loopback\fR Default content: .nf local\-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." static local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0. - 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost." local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0. - 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0. - 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost." .fi .TP 10 -\h'5'\fIonion (RFC 7686)\fR +\h'5'\fIonion (RFC 7686)\fR Default content: .nf local\-zone: "onion." static local\-data: "onion. 10800 IN NS localhost." -local\-data: "onion. 10800 IN +local\-data: "onion. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" .fi .TP 10 -\h'5'\fIreverse RFC1918 local use zones\fR -Reverse data for zones 10.in\-addr.arpa, 16.172.in\-addr.arpa to +\h'5'\fItest (RFC 2606)\fR +Default content: +.nf +local\-zone: "test." static +local\-data: "test. 10800 IN NS localhost." +local\-data: "test. 10800 IN + SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" +.fi +.TP 10 +\h'5'\fIinvalid (RFC 2606)\fR +Default content: +.nf +local\-zone: "invalid." static +local\-data: "invalid. 10800 IN NS localhost." +local\-data: "invalid. 10800 IN + SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" +.fi +.TP 10 +\h'5'\fIreverse RFC1918 local use zones\fR +Reverse data for zones 10.in\-addr.arpa, 16.172.in\-addr.arpa to 31.172.in\-addr.arpa, 168.192.in\-addr.arpa. -The \fBlocal\-zone:\fR is set static and as \fBlocal\-data:\fR SOA and NS +The \fBlocal\-zone:\fR is set static and as \fBlocal\-data:\fR SOA and NS records are provided. .TP 10 -\h'5'\fIreverse RFC3330 IP4 this, link\-local, testnet and broadcast\fR -Reverse data for zones 0.in\-addr.arpa, 254.169.in\-addr.arpa, +\h'5'\fIreverse RFC3330 IP4 this, link\-local, testnet and broadcast\fR +Reverse data for zones 0.in\-addr.arpa, 254.169.in\-addr.arpa, 2.0.192.in\-addr.arpa (TEST NET 1), 100.51.198.in\-addr.arpa (TEST NET 2), 113.0.203.in\-addr.arpa (TEST NET 3), 255.255.255.255.in\-addr.arpa. And from 64.100.in\-addr.arpa to 127.100.in\-addr.arpa (Shared Address Space). .TP 10 \h'5'\fIreverse RFC4291 IP6 unspecified\fR -Reverse data for zone +Reverse data for zone .nf 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. @@ -1098,11 +1350,11 @@ .TP 5 .B local\-data: \fI"" Configure local data, which is served in reply to queries for it. -The query has to match exactly unless you configure the local\-zone as +The query has to match exactly unless you configure the local\-zone as redirect. If not matched exactly, the local\-zone type determines further processing. If local\-data is configured that is not a subdomain of -a local\-zone, a transparent local\-zone is configured. -For record types such as TXT, use single quotes, as in +a local\-zone, a transparent local\-zone is configured. +For record types such as TXT, use single quotes, as in local\-data: 'example. TXT "text"'. .IP If you need more complicated authoritative data, with referrals, wildcards, @@ -1118,10 +1370,11 @@ Assign tags to localzones. Tagged localzones will only be applied when the used access-control element has a matching tag. Tags must be defined in \fIdefine\-tags\fR. Enclose list of tags in quotes ("") and put spaces between -tags. +tags. When there are multiple tags it checks if the intersection of the +list of tags for the query and local\-zone\-tag is non-empty. .TP 5 .B local\-zone\-override: \fI -Override the localzone type for queries from addresses matching netblock. +Override the localzone type for queries from addresses matching netblock. Use this localzone type, regardless the type configured for the local-zone (both tagged and untagged) and regardless the type configured using access\-control\-tag\-action. @@ -1158,12 +1411,13 @@ and enter the cache, whilst also mitigating the traffic flow by the factor given. .TP 5 -.B ratelimit\-for\-domain: \fI +.B ratelimit\-for\-domain: \fI Override the global ratelimit for an exact match domain name with the listed number. You can give this for any number of names. For example, for a top\-level\-domain you may want to have a higher limit than other names. +A value of 0 will disable ratelimiting for that domain. .TP 5 -.B ratelimit\-below\-domain: \fI +.B ratelimit\-below\-domain: \fI Override the global ratelimit for a domain name that ends in this name. You can give this multiple times, it then describes different settings in different parts of the namespace. The closest matching suffix is used @@ -1170,6 +1424,50 @@ to determine the qps limit. The rate for the exact matching domain name is not changed, use ratelimit\-for\-domain to set that, you might want to use different settings for a top\-level\-domain and subdomains. +A value of 0 will disable ratelimiting for domain names that end in this name. +.TP 5 +.B ip\-ratelimit: \fI +Enable global ratelimiting of queries accepted per ip address. +If 0, the default, it is disabled. This option is experimental at this time. +The ratelimit is in queries per second that are allowed. More queries are +completely dropped and will not receive a reply, SERVFAIL or otherwise. +IP ratelimiting happens before looking in the cache. This may be useful for +mitigating amplification attacks. +.TP 5 +.B ip\-ratelimit\-size: \fI +Give the size of the data structure in which the current ongoing rates are +kept track in. Default 4m. In bytes or use m(mega), k(kilo), g(giga). +The ip ratelimit structure is small, so this data structure likely does +not need to be large. +.TP 5 +.B ip\-ratelimit\-slabs: \fI +Give power of 2 number of slabs, this is used to reduce lock contention +in the ip ratelimit tracking data structure. Close to the number of cpus is +a fairly good setting. +.TP 5 +.B ip\-ratelimit\-factor: \fI +Set the amount of queries to rate limit when the limit is exceeded. +If set to 0, all queries are dropped for addresses where the limit is +exceeded. If set to another value, 1 in that number is allowed through +to complete. Default is 10, allowing 1/10 traffic to flow normally. +This can make ordinary queries complete (if repeatedly queried for), +and enter the cache, whilst also mitigating the traffic flow by the +factor given. +.TP 5 +.B fast\-server\-permil: \fI +Specify how many times out of 1000 to pick from the set of fastest servers. +0 turns the feature off. A value of 900 would pick from the fastest +servers 90 percent of the time, and would perform normal exploration of random +servers for the remaining time. When prefetch is enabled (or serve\-expired), +such prefetches are not sped up, because there is no one waiting for it, and it +presents a good moment to perform server exploration. The +\fBfast\-server\-num\fR option can be used to specify the size of the fastest +servers set. The default for fast\-server\-permil is 0. +.TP 5 +.B fast\-server\-num: \fI +Set the number of servers that should be used for fast server selection. Only +use the fastest specified number of servers with the fast\-server\-permil +option, that turns this on or off. The default is to use the fastest 3 servers. .SS "Remote Control Options" In the .B remote\-control: @@ -1176,7 +1474,7 @@ clause are the declarations for the remote control facility. If this is enabled, the \fIunbound\-control\fR(8) utility can be used to send commands to the running unbound server. The server uses these clauses -to setup SSLv3 / TLSv1 security for the connection. The +to setup TLSv1 security for the connection. The \fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR section for options. To setup the correct self\-signed certificates use the \fIunbound\-control\-setup\fR(8) utility. @@ -1192,6 +1490,14 @@ Use 0.0.0.0 and ::0 to listen to all interfaces. If you change this and permissions have been dropped, you must restart the server for the change to take effect. +.IP +If you set it to an absolute path, a local socket is used. The local socket +does not use the certificates and keys, so those files need not be present. +To restrict access, unbound sets permissions on the file to the user and +group that is configured, the access bits are set to allow the group members +to access the control socket file. Put users that need to access the socket +in the that group. To restrict access further, create a directory to put +the control socket in and restrict access to that directory. .TP 5 .B control\-port: \fI The port number to listen on for IPv4 or IPv6 control interfaces, @@ -1200,11 +1506,9 @@ the server for the change to take effect. .TP 5 .B control\-use\-cert: \fI -Whether to require certificate authentication of control connections. -The default is "yes". -This should not be changed unless there are other mechanisms in place -to prevent untrusted users from accessing the remote control -interface. +For localhost control-interface you can disable the use of TLS by setting +this option to "no", default is "yes". For local sockets, TLS is disabled +and the value of this option is ignored. .TP 5 .B server\-key\-file: \fI Path to the server private key, by default unbound_server.key. @@ -1237,21 +1541,21 @@ .P The stub zone can be used to configure authoritative data to be used by the resolver that cannot be accessed using the public internet servers. -This is useful for company\-local data or private zones. Setup an -authoritative server on a different host (or different port). Enter a config -entry for unbound with +This is useful for company\-local data or private zones. Setup an +authoritative server on a different host (or different port). Enter a config +entry for unbound with .B stub\-addr: -. -The unbound resolver can then access the data, without referring to the -public internet for it. +. +The unbound resolver can then access the data, without referring to the +public internet for it. .P -This setup allows DNSSEC signed zones to be served by that +This setup allows DNSSEC signed zones to be served by that authoritative server, in which case a trusted key entry with the public key -can be put in config, so that unbound can validate the data and set the AD -bit on replies for the private zone (authoritative servers do not set the -AD bit). This setup makes unbound capable of answering queries for the -private zone, and can even set the AD bit ('authentic'), but the AA -('authoritative') bit is not set on these replies. +can be put in config, so that unbound can validate the data and set the AD +bit on replies for the private zone (authoritative servers do not set the +AD bit). This setup makes unbound capable of answering queries for the +private zone, and can even set the AD bit ('authentic'), but the AA +('authoritative') bit is not set on these replies. .P Consider adding \fBserver:\fR statements for \fBdomain\-insecure:\fR and for \fBlocal\-zone:\fI name nodefault\fR for the zone if it is a locally @@ -1270,8 +1574,8 @@ To use a nondefault port for DNS communication append '@' with the port number. .TP .B stub\-prime: \fI -This option is by default off. If enabled it performs NS set priming, -which is similar to root hints, where it starts using the list of nameservers +This option is by default no. If enabled it performs NS set priming, +which is similar to root hints, where it starts using the list of nameservers currently published by the zone. Thus, if the hint list is slightly outdated, the resolver picks up a correct list online. .TP @@ -1280,6 +1584,17 @@ The data could not be retrieved and would have caused SERVFAIL because the servers are unreachable, instead it is tried without this clause. The default is no. +.TP +.B stub\-tls\-upstream: \fI +Enabled or disable whether the queries to this stub use TLS for transport. +Default is no. +.TP +.B stub\-ssl\-upstream: \fI +Alternate syntax for \fBstub\-tls\-upstream\fR. +.TP +.B stub\-no\-cache: \fI +Default is no. If enabled, data inside the stub is not cached. This is +useful when you want immediate changes to be visible. .SS "Forward Zone Options" .LP There may be multiple @@ -1291,6 +1606,9 @@ those servers are not authority servers, but are (just like unbound is) recursive servers too; unbound does not perform recursion itself for the forward zone, it lets the remote server do it. Class IN is assumed. +CNAMEs are chased by unbound itself, asking the remote server for every +name in the indirection chain, to protect the local cache from illegal +indirect referenced items. A forward\-zone entry with name "." and a forward\-addr target will forward all queries to that other server (unless it can answer from the cache). @@ -1304,11 +1622,143 @@ .B forward\-addr: \fI IP address of server to forward to. Can be IP 4 or IP 6. To use a nondefault port for DNS communication append '@' with the port number. +If tls is enabled, then you can append a '#' and a name, then it'll check +the tls authentication certificates with that name. If you combine +the '@' and '#', the '@' comes first. +.IP +At high verbosity it logs the TLS certificate, with TLS enabled. +If you leave out the '#' and auth name from the forward\-addr, any +name is accepted. The cert must also match a CA from the tls\-cert\-bundle. .TP .B forward\-first: \fI -If enabled, a query is attempted without the forward clause if it fails. -The data could not be retrieved and would have caused SERVFAIL because -the servers are unreachable, instead it is tried without this clause. +If a forwarded query is met with a SERVFAIL error, and this option is +enabled, unbound will fall back to normal recursive resolution for this +query as if no query forwarding had been specified. The default is "no". +.TP +.B forward\-tls\-upstream: \fI +Enabled or disable whether the queries to this forwarder use TLS for transport. +Default is no. +If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to +load CA certs, otherwise the connections cannot be authenticated. +.TP +.B forward\-ssl\-upstream: \fI +Alternate syntax for \fBforward\-tls\-upstream\fR. +.TP +.B forward\-no\-cache: \fI +Default is no. If enabled, data inside the forward is not cached. This is +useful when you want immediate changes to be visible. +.SS "Authority Zone Options" +.LP +Authority zones are configured with \fBauth\-zone:\fR, and each one must +have a \fBname:\fR. There can be multiple ones, by listing multiple auth\-zone clauses, each with a different name, pertaining to that part of the namespace. +The authority zone with the name closest to the name looked up is used. +Authority zones are processed after \fBlocal\-zones\fR and before +cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner +make unbound respond like an authority server. Authority zones are also +processed after cache, just before going to the network to fetch +information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used +in this manner provide a l