Index: vendor/unbound/dist/Makefile.in =================================================================== --- vendor/unbound/dist/Makefile.in (revision 295529) +++ vendor/unbound/dist/Makefile.in (revision 295530) @@ -1,1213 +1,1214 @@ # Copyright 2007 NLnet Labs # See the file LICENSE for the license SHELL=@SHELL@ VERSION=@PACKAGE_VERSION@ srcdir=@srcdir@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ sbindir=@sbindir@ mandir=@mandir@ libdir=@libdir@ # datarootdir is here to please some checkers, use datadir. datarootdir=@datarootdir@ datadir=@datadir@ includedir=@includedir@ doxygen=@doxygen@ libtool=@libtool@ staticexe=@staticexe@ EXEEXT=@EXEEXT@ configfile=@ub_conf_file@ CHECKLOCK_SRC=testcode/checklocks.c CHECKLOCK_OBJ=@CHECKLOCK_OBJ@ DNSTAP_SRC=@DNSTAP_SRC@ DNSTAP_OBJ=@DNSTAP_OBJ@ WITH_PYTHONMODULE=@WITH_PYTHONMODULE@ WITH_PYUNBOUND=@WITH_PYUNBOUND@ PY_MAJOR_VERSION=@PY_MAJOR_VERSION@ PYTHON_SITE_PKG=@PYTHON_SITE_PKG@ PYTHONMOD_INSTALL=@PYTHONMOD_INSTALL@ PYTHONMOD_UNINSTALL=@PYTHONMOD_UNINSTALL@ PYUNBOUND_INSTALL=@PYUNBOUND_INSTALL@ PYUNBOUND_UNINSTALL=@PYUNBOUND_UNINSTALL@ UNBOUND_EVENT_INSTALL=@UNBOUND_EVENT_INSTALL@ UNBOUND_EVENT_UNINSTALL=@UNBOUND_EVENT_UNINSTALL@ UNBOUND_VERSION_MAJOR=@UNBOUND_VERSION_MAJOR@ UNBOUND_VERSION_MINOR=@UNBOUND_VERSION_MINOR@ UNBOUND_VERSION_MICRO=@UNBOUND_VERSION_MICRO@ ALLTARGET=@ALLTARGET@ INSTALLTARGET=@INSTALLTARGET@ SSLLIB=@SSLLIB@ # _unbound.la if pyunbound enabled. PYUNBOUND_TARGET=@PYUNBOUND_TARGET@ # override $U variable which is used by autotools for deansification (for # K&R C compilers), but causes problems if $U is defined in the env). U= PROTOC_C=@PROTOC_C@ SWIG=@SWIG@ YACC=@YACC@ LEX=@LEX@ STRIP=@STRIP@ CC=@CC@ CPPFLAGS=-I. @CPPFLAGS@ CFLAGS=@CFLAGS@ LDFLAGS=@LDFLAGS@ LIBS=@LIBS@ LIBOBJS=@LIBOBJS@ # filter out ctime_r from compat obj. LIBOBJ_WITHOUT_CTIME=@LIBOBJ_WITHOUT_CTIME@ LIBOBJ_WITHOUT_CTIMEARC4=@LIBOBJ_WITHOUT_CTIMEARC4@ RUNTIME_PATH=@RUNTIME_PATH@ DEPFLAG=@DEPFLAG@ DATE=@CONFIG_DATE@ LIBTOOL=$(libtool) BUILD=build/ UBSYMS=@UBSYMS@ EXTRALINK=@EXTRALINK@ WINDRES=@WINDRES@ LINT=splint LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list -formatcode #-Dglob64=glob -Dglobfree64=globfree # compat with openssl linux edition. LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned" -D"ECDSA_SIG=DSA_SIG" -Dfstrm_res=int # compat with NetBSD LINTFLAGS+=@NETBSD_LINTFLAGS@ # 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" INSTALL=$(SHELL) $(srcdir)/install-sh #pythonmod.c is not here, it is mentioned by itself in its own rules, #makedepend fails on missing interface.h otherwise. PYTHONMOD_SRC=pythonmod/pythonmod_utils.c # pythonmod.lo pythonmod_utils.lo if python mod enabled. PYTHONMOD_OBJ=@PYTHONMOD_OBJ@ PYTHONMOD_HEADER=@PYTHONMOD_HEADER@ # libunbound/python/libunbound_wrap.c is dealt with by its own rules. PYUNBOUND_SRC= # libunbound_wrap.lo if python libunbound wrapper enabled. PYUNBOUND_OBJ=@PYUNBOUND_OBJ@ COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \ -util/data/dname.c util/data/msgencode.c util/data/msgparse.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 \ 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/outbound_list.c services/outside_network.c util/alloc.c \ util/config_file.c util/configlexer.c util/configparser.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/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 $(CHECKLOCK_SRC) $(DNSTAP_SRC) COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \ -msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.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 \ 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 \ 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 \ 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 \ $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) COMMON_OBJ=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \ outside_network.lo # set to $COMMON_OBJ or to "" if --enableallsymbols COMMON_OBJ_ALL_SYMBOLS=@COMMON_OBJ_ALL_SYMBOLS@ 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/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 COMPAT_OBJ=$(LIBOBJS:.o=.lo) COMPAT_OBJ_WITHOUT_CTIME=$(LIBOBJ_WITHOUT_CTIME:.o=.lo) COMPAT_OBJ_WITHOUT_CTIMEARC4=$(LIBOBJ_WITHOUT_CTIMEARC4:.o=.lo) SLDNS_SRC=sldns/keyraw.c sldns/sbuffer.c sldns/wire2str.c sldns/parse.c \ 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 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 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 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 \ worker.lo @WIN_DAEMON_OBJ@ DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \ $(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@ 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) \ $(COMPAT_OBJ) @WIN_CHECKCONF_OBJ_LINK@ CONTROL_SRC=smallapp/unbound-control.c CONTROL_OBJ=unbound-control.lo CONTROL_OBJ_LINK=$(CONTROL_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) \ $(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@ 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@ TESTBOUND_SRC=testcode/testbound.c testcode/testpkts.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) $(SLDNS_OBJ) $(COMPAT_OBJ) LOCKVERIFY_SRC=testcode/lock_verify.c LOCKVERIFY_OBJ=lock_verify.lo LOCKVERIFY_OBJ_LINK=$(LOCKVERIFY_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) PETAL_SRC=testcode/petal.c PETAL_OBJ=petal.lo PETAL_OBJ_LINK=$(PETAL_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c PKTVIEW_OBJ=pktview.lo PKTVIEW_OBJ_LINK=$(PKTVIEW_OBJ) worker_cb.lo readhex.lo $(COMMON_OBJ) \ $(COMPAT_OBJ) $(SLDNS_OBJ) MEMSTATS_SRC=testcode/memstats.c MEMSTATS_OBJ=memstats.lo MEMSTATS_OBJ_LINK=$(MEMSTATS_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) ASYNCLOOK_SRC=testcode/asynclook.c ASYNCLOOK_OBJ=asynclook.lo ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) STREAMTCP_SRC=testcode/streamtcp.c STREAMTCP_OBJ=streamtcp.lo STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) PERF_SRC=testcode/perf.c PERF_OBJ=perf.lo PERF_OBJ_LINK=$(PERF_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ) DELAYER_SRC=testcode/delayer.c DELAYER_OBJ=delayer.lo DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \ libunbound/libworker.c LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo LIBUNBOUND_OBJ_LINK=$(LIBUNBOUND_OBJ) $(COMMON_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ) # win apps or "" if not on windows WINAPPS=@WINAPPS@ WIN_DAEMON_THE_SRC=winrc/win_svc.c winrc/w_inst.c SVCINST_SRC=winrc/unbound-service-install.c SVCINST_OBJ=unbound-service-install.lo SVCINST_OBJ_LINK=$(SVCINST_OBJ) w_inst.lo rsrc_svcinst.o $(COMPAT_OBJ_WITHOUT_CTIME) SVCUNINST_SRC=winrc/unbound-service-remove.c SVCUNINST_OBJ=unbound-service-remove.lo SVCUNINST_OBJ_LINK=$(SVCUNINST_OBJ) w_inst.lo rsrc_svcuninst.o \ $(COMPAT_OBJ_WITHOUT_CTIME) ANCHORUPD_SRC=winrc/anchor-update.c ANCHORUPD_OBJ=anchor-update.lo ANCHORUPD_OBJ_LINK=$(ANCHORUPD_OBJ) rsrc_anchorupd.o $(COMPAT_OBJ_WITHOUT_CTIME) RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \ rsrc_unbound_host.o rsrc_unbound_anchor.o rsrc_unbound_control.o \ rsrc_unbound_checkconf.o ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \ $(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \ $(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)\ $(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) \ $(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \ $(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) \ $(COMPAT_OBJ) $(PYUNBOUND_OBJ) \ $(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) 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 .PHONY: clean realclean doc lint all install uninstall tests test strip lib longtest longcheck check alltargets 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) # compat with BSD make, register suffix, and an implicit rule to actualise it. .SUFFIXES: .lo .c.lo: $(COMPILE) -o $@ -c $< $(ALL_OBJ): @@SOURCEDETERMINE@ $(COMPILE) -o $@ -c @SOURCEFILE@ $(RSRC_OBJ): @@SOURCEDETERMINE@ $(WINDRES) $(CPPFLAGS) @SOURCEFILE@ $@ rsrc_svcinst.o: $(srcdir)/winrc/rsrc_svcinst.rc config.h rsrc_svcuninst.o: $(srcdir)/winrc/rsrc_svcuninst.rc config.h rsrc_anchorupd.o: $(srcdir)/winrc/rsrc_anchorupd.rc config.h rsrc_unbound.o: $(srcdir)/winrc/rsrc_unbound.rc config.h rsrc_unbound_host.o: $(srcdir)/winrc/rsrc_unbound_host.rc config.h rsrc_unbound_anchor.o: $(srcdir)/winrc/rsrc_unbound_anchor.rc config.h rsrc_unbound_control.o: $(srcdir)/winrc/rsrc_unbound_control.rc config.h rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \ lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \ petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \ testbound$(EXEEXT) unittest$(EXEEXT) tests: all $(TEST_BIN) check: test longcheck: longtest 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 @echo test OK longtest: tests if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi lib: libunbound.la unbound.h libunbound.la: $(LIBUNBOUND_OBJ_LINK) $(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS) unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la $(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la $(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) unbound-control$(EXEEXT): $(CONTROL_OBJ_LINK) libunbound.la $(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) unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ_LINK) libunbound.la $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat $(SSLLIB) $(LIBS) unbound-service-install$(EXEEXT): $(SVCINST_OBJ_LINK) $(LINK) -o $@ $(SVCINST_OBJ_LINK) $(LIBS) unbound-service-remove$(EXEEXT): $(SVCUNINST_OBJ_LINK) $(LINK) -o $@ $(SVCUNINST_OBJ_LINK) $(LIBS) anchor-update$(EXEEXT): $(ANCHORUPD_OBJ_LINK) libunbound.la $(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) -L. -L.libs -lunbound $(LIBS) unittest$(EXEEXT): $(UNITTEST_OBJ_LINK) $(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS) testbound$(EXEEXT): $(TESTBOUND_OBJ_LINK) $(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SSLLIB) $(LIBS) lock-verify$(EXEEXT): $(LOCKVERIFY_OBJ_LINK) $(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SSLLIB) $(LIBS) petal$(EXEEXT): $(PETAL_OBJ_LINK) $(LINK) -o $@ $(PETAL_OBJ_LINK) $(SSLLIB) $(LIBS) pktview$(EXEEXT): $(PKTVIEW_OBJ_LINK) $(LINK) -o $@ $(PKTVIEW_OBJ_LINK) $(SSLLIB) $(LIBS) memstats$(EXEEXT): $(MEMSTATS_OBJ_LINK) $(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS) asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) $(LIBS) -L. -L.libs -lunbound streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK) $(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS) perf$(EXEEXT): $(PERF_OBJ_LINK) $(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS) delayer$(EXEEXT): $(DELAYER_OBJ_LINK) $(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS) signit$(EXEEXT): testcode/signit.c $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ testcode/signit.c $(LDFLAGS) -lldns $(SSLLIB) $(LIBS) unbound.h: $(srcdir)/libunbound/unbound.h sed -e 's/@''UNBOUND_VERSION_MAJOR@/$(UNBOUND_VERSION_MAJOR)/' -e 's/@''UNBOUND_VERSION_MINOR@/$(UNBOUND_VERSION_MINOR)/' -e 's/@''UNBOUND_VERSION_MICRO@/$(UNBOUND_VERSION_MICRO)/' < $(srcdir)/libunbound/unbound.h > $@ unbound-control-setup: smallapp/unbound-control-setup.sh cp smallapp/unbound-control-setup.sh $@ -chmod +x $@ # dnstap dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \ dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/util/config_file.h $(srcdir)/util/log.h \ $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h 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 dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h # Python Module pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \ pythonmod/interface.h \ $(srcdir)/pythonmod/pythonmod.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)/services/outbound_list.h $(srcdir)/util/config_file.h \ $(srcdir)/pythonmod/pythonmod_utils.h $(srcdir)/util/netevent.h \ $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h \ $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h \ $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h pythonmod/interface.h: $(srcdir)/pythonmod/interface.i config.h @-if test ! -d pythonmod; then $(INSTALL) -d pythonmod; fi $(SWIG) $(CPPFLAGS) -o $@ -python $(srcdir)/pythonmod/interface.i libunbound_wrap.lo libunbound_wrap.o: libunbound/python/libunbound_wrap.c \ unbound.h libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i unbound.h @-if test ! -d libunbound/python; then $(INSTALL) -d libunbound/python; fi $(SWIG) -python -o $@ $(CPPFLAGS) -DPY_MAJOR_VERSION=$(PY_MAJOR_VERSION) $(srcdir)/libunbound/python/libunbound.i # 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 util/config_file.c: util/configparser.h util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h @-if test ! -d util; then $(INSTALL) -d util; fi if test "$(LEX)" != ":"; then \ echo "#include \"config.h\"" > $@ ;\ echo "#include \"util/configyyrename.h\"" >> $@ ;\ $(LEX) -t $(srcdir)/util/configlexer.lex >> $@ ;\ fi util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y @-if test ! -d util; then $(INSTALL) -d util; fi $(YACC) -d -o util/configparser.c $(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 $(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 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 rm -f $(TEST_BIN) rm -f Makefile .SUFFIXES: .lint .c.lint: $(LINT) $(LINTFLAGS) -I. -I$(srcdir) $< touch $@ util/configparser.lint util/configlexer.lint pythonmod/pythonmod.lint libunbound/python/libunbound_wrap.lint dnstap/dnstap.pb-c.lint: # skip lint for generated code touch $@ winrc/win_svc.lint winrc/w_inst.lint winrc/unbound-service-install.lint winrc/unbound-service-remove.lint: # skip lint for windows types touch $@ lint: $(ALL_SRC:.c=.lint) tags: $(srcdir)/*.[ch] $(srcdir)/*/*.[ch] ctags -f $(srcdir)/tags $(srcdir)/*.[ch] $(srcdir)/*/*.[ch] doc: 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;\ fi ;\ fi strip: $(STRIP) unbound$(EXEEXT) $(STRIP) unbound-checkconf$(EXEEXT) $(STRIP) unbound-control$(EXEEXT) $(STRIP) unbound-host$(EXEEXT) || $(STRIP) .libs/unbound-host$(EXEEXT) $(STRIP) unbound-anchor$(EXEEXT) || $(STRIP) .libs/unbound-anchor$(EXEEXT) pythonmod-install: $(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG) $(INSTALL) -c -m 644 pythonmod/unboundmodule.py $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py pyunbound-install: $(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG) $(INSTALL) -c -m 644 $(srcdir)/libunbound/python/unbound.py $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py $(LIBTOOL) --mode=install cp _unbound.la $(DESTDIR)$(PYTHON_SITE_PKG) $(LIBTOOL) --mode=finish $(DESTDIR)$(PYTHON_SITE_PKG) unbound-event-install: $(INSTALL) -m 755 -d $(DESTDIR)$(includedir) $(LIBTOOL) --mode=install cp $(srcdir)/libunbound/unbound-event.h $(DESTDIR)$(includedir)/unbound-event.h install: $(INSTALLTARGET) install-lib: lib $(UNBOUND_EVENT_INSTALL) $(INSTALL) -m 755 -d $(DESTDIR)$(libdir) $(INSTALL) -m 755 -d $(DESTDIR)$(includedir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man3 $(INSTALL) -c -m 644 doc/libunbound.3 $(DESTDIR)$(mandir)/man3 for mpage in ub_ctx ub_result ub_ctx_create ub_ctx_delete \ ub_ctx_set_option ub_ctx_get_option ub_ctx_config ub_ctx_set_fwd \ ub_ctx_resolvconf ub_ctx_hosts ub_ctx_add_ta ub_ctx_add_ta_file \ ub_ctx_trustedkeys ub_ctx_debugout ub_ctx_debuglevel ub_ctx_async \ ub_poll ub_wait ub_fd ub_process ub_resolve ub_resolve_async ub_cancel \ ub_resolve_free ub_strerror ub_ctx_print_local_zones ub_ctx_zone_add \ ub_ctx_zone_remove ub_ctx_data_add ub_ctx_data_remove; \ do \ echo ".so man3/libunbound.3" > $(DESTDIR)$(mandir)/man3/$$mpage.3 ; \ done $(LIBTOOL) --mode=install cp unbound.h $(DESTDIR)$(includedir)/unbound.h $(LIBTOOL) --mode=install cp libunbound.la $(DESTDIR)$(libdir) $(LIBTOOL) --mode=finish $(DESTDIR)$(libdir) install-all: all $(PYTHONMOD_INSTALL) $(PYUNBOUND_INSTALL) $(UNBOUND_EVENT_INSTALL) install-lib $(INSTALL) -m 755 -d $(DESTDIR)$(sbindir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man5 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1 $(LIBTOOL) --mode=install cp unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(LIBTOOL) --mode=install cp unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(LIBTOOL) --mode=install cp unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(LIBTOOL) --mode=install cp unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(LIBTOOL) --mode=install cp unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT) $(INSTALL) -c -m 644 doc/unbound.8 $(DESTDIR)$(mandir)/man8 $(INSTALL) -c -m 644 doc/unbound-checkconf.8 $(DESTDIR)$(mandir)/man8 $(INSTALL) -c -m 644 doc/unbound-control.8 $(DESTDIR)$(mandir)/man8 $(INSTALL) -c -m 644 doc/unbound-control.8 $(DESTDIR)$(mandir)/man8/unbound-control-setup.8 $(INSTALL) -c -m 644 doc/unbound-anchor.8 $(DESTDIR)$(mandir)/man8 $(INSTALL) -c -m 644 doc/unbound.conf.5 $(DESTDIR)$(mandir)/man5 $(INSTALL) -c -m 644 doc/unbound-host.1 $(DESTDIR)$(mandir)/man1 $(INSTALL) -c -m 755 unbound-control-setup $(DESTDIR)$(sbindir)/unbound-control-setup if test ! -e $(DESTDIR)$(configfile); then $(INSTALL) -d `dirname $(DESTDIR)$(configfile)`; $(INSTALL) -c -m 644 doc/example.conf $(DESTDIR)$(configfile); fi pythonmod-uninstall: rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py pyunbound-uninstall: rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(PYTHON_SITE_PKG)/_unbound.la unbound-event-uninstall: rm -f -- $(DESTDIR)$(includedir)/unbound-event.h uninstall: $(PYTHONMOD_UNINSTALL) $(PYUNBOUND_UNINSTALL) $(UNBOUND_EVENT_UNINSTALL) rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8 $(DESTDIR)$(mandir)/man8/unbound-anchor.8 $(DESTDIR)$(mandir)/man8/unbound-control-setup.8 rm -f -- $(DESTDIR)$(mandir)/man1/unbound-host.1 $(DESTDIR)$(mandir)/man3/libunbound.3 for mpage in ub_ctx ub_result ub_ctx_create ub_ctx_delete \ ub_ctx_set_option ub_ctx_get_option ub_ctx_config ub_ctx_set_fwd \ ub_ctx_resolvconf ub_ctx_hosts ub_ctx_add_ta ub_ctx_add_ta_file \ ub_ctx_trustedkeys ub_ctx_debugout ub_ctx_debuglevel ub_ctx_async \ ub_poll ub_wait ub_fd ub_process ub_resolve ub_resolve_async ub_cancel \ ub_resolve_free ub_strerror ub_ctx_print_local_zones ub_ctx_zone_add \ ub_ctx_zone_remove ub_ctx_data_add ub_ctx_data_remove; \ do \ rm -f -- $(DESTDIR)$(mandir)/man3/$$mpage.3 ; \ done rm -f -- $(DESTDIR)$(includedir)/unbound.h $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libunbound.la @echo @echo "You still need to remove "`dirname $(DESTDIR)$(configfile)`" , $(DESTDIR)$(configfile) by hand" iana_update: curl -o port-numbers.tmp http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml --compressed if file port-numbers.tmp | grep 'gzip' >/dev/null; then zcat port-numbers.tmp; else cat port-numbers.tmp; fi | awk '// {p=0;} /udp/ {p=1;} /[^u]/ {p=0;} /Decomissioned|Decommissioned|Removed|De-registered|unassigned|Unassigned|Reserved/ {u=1;} // { if(u==1) {u=0;} else { if(p==1) { match($$0,/[0-9]+/); print substr($$0, RSTART, RLENGTH) ","}}}' | sort -nu > util/iana_ports.inc rm -f port-numbers.tmp # dependency generation DEPEND_TMP=depend1073.tmp DEPEND_TMP2=depend1074.tmp DEPEND_TARGET=Makefile DEPEND_TARGET2=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 # then, add srcdir before .c and .h in deps. # then, remove srcdir from the (generated) parser and lexer. # and mention the .lo depend: (cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) $(ALL_SRC) $(COMPAT_SRC)) | \ 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' | \ sed -e '/^ \\$$/d' | \ sed -e 's? *\([^ ]*\.[ch]\)? $$(srcdir)/\1?g' | \ sed -e 's? *\([^ ]*\.inc\)? $$(srcdir)/\1?g' | \ sed -e 's?$$(srcdir)/config.h?config.h?g' \ -e 's?$$(srcdir)/util/configlexer.c?util/configlexer.c?g' \ -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)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \ -e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \ > $(DEPEND_TMP) cp $(DEPEND_TARGET) $(DEPEND_TMP2) head -`egrep -n "# Dependencies" $(DEPEND_TARGET) | tail -1 | sed -e 's/:.*$$//'` $(DEPEND_TMP2) > $(DEPEND_TARGET) cat $(DEPEND_TMP) >> $(DEPEND_TARGET) @if diff $(DEPEND_TARGET) $(DEPEND_TMP2); then echo " $(DEPEND_TARGET) unchanged"; else echo " Updated $(DEPEND_TARGET))"; fi @if test -f $(DEPEND_TARGET2); then \ cp $(DEPEND_TARGET2) $(DEPEND_TMP2); \ head -`egrep -n "# Dependencies" $(DEPEND_TARGET2) | tail -1 | sed -e 's/:.*$$//'` $(DEPEND_TMP2) > $(DEPEND_TARGET2); \ cat $(DEPEND_TMP) >> $(DEPEND_TARGET2); \ if diff $(DEPEND_TARGET2) $(DEPEND_TMP2); then echo " $(DEPEND_TARGET2) unchanged"; else echo " Updated $(DEPEND_TARGET2))"; fi; \ fi rm -f $(DEPEND_TMP) $(DEPEND_TMP2) # Dependencies +as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h 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)/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 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 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 \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/storage/lookup3.h $(srcdir)/sldns/sbuffer.h msgencode.lo msgencode.o: $(srcdir)/util/data/msgencode.c config.h $(srcdir)/util/data/msgencode.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/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 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/dname.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/sldns/sbuffer.h $(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 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 \ $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.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 $(srcdir)/iterator/iter_utils.h \ $(srcdir)/iterator/iter_resptype.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_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/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 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 \ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h iter_donotq.lo iter_donotq.o: $(srcdir)/iterator/iter_donotq.c config.h $(srcdir)/iterator/iter_donotq.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 iter_fwd.lo iter_fwd.o: $(srcdir)/iterator/iter_fwd.c config.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h iter_hints.lo iter_hints.o: $(srcdir)/iterator/iter_hints.c config.h $(srcdir)/iterator/iter_hints.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \ $(srcdir)/sldns/wire2str.h iter_priv.lo iter_priv.o: $(srcdir)/iterator/iter_priv.c config.h $(srcdir)/iterator/iter_priv.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h $(srcdir)/util/config_file.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)/util/net_help.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h iter_resptype.lo iter_resptype.o: $(srcdir)/iterator/iter_resptype.c config.h \ $(srcdir)/iterator/iter_resptype.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/net_help.h \ $(srcdir)/util/data/dname.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h iter_scrub.lo iter_scrub.o: $(srcdir)/iterator/iter_scrub.c config.h $(srcdir)/iterator/iter_scrub.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 \ $(srcdir)/iterator/iter_priv.h $(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h $(srcdir)/sldns/sbuffer.h iter_utils.lo iter_utils.o: $(srcdir)/iterator/iter_utils.c config.h $(srcdir)/iterator/iter_utils.h \ $(srcdir)/iterator/iter_resptype.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 $(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 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 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)/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/data/msgparse.h $(srcdir)/sldns/pkthdr.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)/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 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 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 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 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/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 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 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 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)/services/cache/infra.h $(srcdir)/util/storage/dnstree.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 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/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 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/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/mini_event.h $(srcdir)/util/rbtree.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 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 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 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/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 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 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 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 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)/sldns/sbuffer.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/as112.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 \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \ $(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 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 \ $(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 val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h 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)/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 \ $(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_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)/validator/val_kentry.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \ $(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)/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 \ $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \ $(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 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)/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 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 checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/testcode/checklocks.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 unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \ $(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 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 \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/testcode/readhex.h \ $(srcdir)/testcode/testpkts.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h unitneg.lo unitneg.o: $(srcdir)/testcode/unitneg.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/data/dname.h $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \ $(srcdir)/sldns/rrdef.h unitregional.lo unitregional.o: $(srcdir)/testcode/unitregional.c config.h $(srcdir)/testcode/unitmain.h \ $(srcdir)/util/log.h $(srcdir)/util/regional.h unitslabhash.lo unitslabhash.o: $(srcdir)/testcode/unitslabhash.c config.h $(srcdir)/testcode/unitmain.h \ $(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)/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 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 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 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 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 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/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 \ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \ $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h \ $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \ $(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/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/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 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)/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/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 \ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \ $(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)/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 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)/util/mini_event.h $(srcdir)/util/rbtree.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/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)/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)/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 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)/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/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/mini_event.h $(srcdir)/util/rbtree.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 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/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)/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)/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 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 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/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/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 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)/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 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 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 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 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 \ $(srcdir)/sldns/parseutil.h 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 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 \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ $(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 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 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)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/sldns/sbuffer.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 \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/libworker.h \ $(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)/services/localzone.h \ $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/sldns/sbuffer.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)/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)/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)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \ $(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 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 \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \ $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.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/wire2str.h $(srcdir)/sldns/str2wire.h 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 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 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)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.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/winsock_event.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 unbound-service-remove.lo unbound-service-remove.o: $(srcdir)/winrc/unbound-service-remove.c config.h \ $(srcdir)/winrc/w_inst.h anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/rrdef.h 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 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 rrdef.lo rrdef.o: $(srcdir)/sldns/rrdef.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h str2wire.lo str2wire.o: $(srcdir)/sldns/str2wire.c config.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h inet_aton.lo inet_aton.o: $(srcdir)/compat/inet_aton.c config.h inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h malloc.lo malloc.o: $(srcdir)/compat/malloc.c config.h memcmp.lo memcmp.o: $(srcdir)/compat/memcmp.c config.h memmove.lo memmove.o: $(srcdir)/compat/memmove.c config.h snprintf.lo snprintf.o: $(srcdir)/compat/snprintf.c config.h 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_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_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 arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h $(srcdir)/util/locks.h sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h reallocarray.lo reallocarray.o: $(srcdir)/compat/reallocarray.c config.h isblank.lo isblank.o: $(srcdir)/compat/isblank.c config.h Index: vendor/unbound/dist/doc/example.conf.in =================================================================== --- vendor/unbound/dist/doc/example.conf.in (revision 295529) +++ vendor/unbound/dist/doc/example.conf.in (revision 295530) @@ -1,659 +1,663 @@ # # Example configuration file. # # See unbound.conf(5) man page, version 1.5.7. # # this is a comment. #Use this to include other text into the file. #include: "otherfile.conf" # The server clause sets the main parameters. server: # whitespace is not necessary, but looks cleaner. # verbosity number, 0 is least verbose. 1 is default. verbosity: 1 # print statistics to the log (for every thread) every N seconds. # Set to "" or 0 to disable. Default is disabled. # statistics-interval: 0 # enable cumulative statistics, without clearing them after printing. # statistics-cumulative: no # enable extended statistics (query types, answer codes, status) # printed from unbound-control. default off, because of speed. # extended-statistics: no # number of threads to create. 1 disables threading. # num-threads: 1 # specify the interfaces to answer queries from by ip-address. # The default is to listen to localhost (127.0.0.1 and ::1). # specify 0.0.0.0 and ::0 to bind to all available interfaces. # specify every interface[@port] on a new 'interface:' labelled line. # The listen interfaces are not changed on reload, only on restart. # interface: 192.0.2.153 # interface: 192.0.2.154 # interface: 192.0.2.154@5003 # interface: 2001:DB8::5 # enable this feature to copy the source address of queries to reply. # Socket options are not supported on all platforms. experimental. # interface-automatic: no # port to answer queries from # port: 53 # specify the interfaces to send outgoing queries to authoritative # server from by ip-address. If none, the default (all) interface # is used. Specify every interface on a 'outgoing-interface:' line. # outgoing-interface: 192.0.2.153 # outgoing-interface: 2001:DB8::5 # outgoing-interface: 2001:DB8::6 # number of ports to allocate per thread, determines the size of the # port range that can be open simultaneously. About double the # num-queries-per-thread, or, use as many as the OS will allow you. # outgoing-range: 4096 # permit unbound to use this port number or port range for # making outgoing queries, using an outgoing interface. # outgoing-port-permit: 32768 # deny unbound the use this of port number or port range for # making outgoing queries, using an outgoing interface. # Use this to make sure unbound does not grab a UDP port that some # other server on this computer needs. The default is to avoid # IANA-assigned port numbers. # If multiple outgoing-port-permit and outgoing-port-avoid options # are present, they are processed in order. # outgoing-port-avoid: "3200-3208" # number of outgoing simultaneous tcp buffers to hold per thread. # outgoing-num-tcp: 10 # number of incoming simultaneous tcp buffers to hold per thread. # incoming-num-tcp: 10 # buffer size for UDP port 53 incoming (SO_RCVBUF socket option). # 0 is system default. Use 4m to catch query spikes for busy servers. # so-rcvbuf: 0 # buffer size for UDP port 53 outgoing (SO_SNDBUF socket option). # 0 is system default. Use 4m to handle spikes on very busy servers. # so-sndbuf: 0 # use SO_REUSEPORT to distribute queries over threads. # so-reuseport: no # 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 # ip-transparent: no # EDNS reassembly buffer to advertise to UDP peers (the actual buffer # is set with msg-buffer-size). 1480 can solve fragmentation (timeouts). # edns-buffer-size: 4096 # Maximum UDP response size (not applied to TCP response). # Suggested values are 512 to 4096. Default is 4096. 65536 disables it. # max-udp-size: 4096 # 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 # the amount of memory to use for the message cache. # plain value in bytes or you can append k, m or G. default is "4Mb". # msg-cache-size: 4m # the number of slabs to use for the message cache. # the number of slabs must be a power of 2. # more slabs reduce lock contention, but fragment memory usage. # msg-cache-slabs: 4 # the number of queries that a thread gets to service. # num-queries-per-thread: 1024 # if very busy, 50% queries run to completion, 50% get timeout in msec # jostle-timeout: 200 # msec to wait before close of port on timeout UDP. 0 disables. # delay-close: 0 # 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 # the number of slabs to use for the RRset cache. # the number of slabs must be a power of 2. # more slabs reduce lock contention, but fragment memory usage. # rrset-cache-slabs: 4 # the time to live (TTL) value lower bound, in seconds. Default 0. # If more than an hour could easily give trouble due to stale data. # cache-min-ttl: 0 # the time to live (TTL) value cap for RRsets and messages in the # cache. Items are not cached for longer. In seconds. # cache-max-ttl: 86400 # the time to live (TTL) value cap for negative responses in the cache # cache-max-negative-ttl: 3600 # the time to live (TTL) value for cached roundtrip times, lameness and # EDNS version information for hosts. In seconds. # infra-host-ttl: 900 # minimum wait time for responses, increase if uplink is long. In msec. # infra-cache-min-rtt: 50 # the number of slabs to use for the Infrastructure cache. # the number of slabs must be a power of 2. # more slabs reduce lock contention, but fragment memory usage. # infra-cache-slabs: 4 # the maximum number of hosts that are cached (roundtrip, EDNS, lame). # infra-cache-numhosts: 10000 # Enable IPv4, "yes" or "no". # do-ip4: yes # Enable IPv6, "yes" or "no". # do-ip6: yes # Enable UDP, "yes" or "no". # do-udp: yes # Enable TCP, "yes" or "no". # do-tcp: yes # upstream connections use TCP only (and no UDP), "yes" or "no" # useful for tunneling scenarios, default no. # tcp-upstream: no # Detach from the terminal, run in background, "yes" or "no". # do-daemonize: yes # control which clients are allowed to make (recursive) queries # 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) # 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 # access-control: 127.0.0.0/8 allow # access-control: ::0/0 refuse # access-control: ::1 allow # access-control: ::ffff:127.0.0.1 allow # 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. # # 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. # # All other file paths (working dir, logfile, roothints, and # key files) can be specified in several ways: # o as an absolute path relative to the new root. # o as a relative path to the working directory. # o as an absolute path relative to the original root. # In the last case the path is adjusted to remove the unused portion. # # 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). # How to do this is specific to your OS. # # If you give "" no chroot is performed. The path must not end in a /. # chroot: "@UNBOUND_CHROOT_DIR@" # if given, user privileges are dropped (after binding port), # and the given username is assumed. Default is user "unbound". # If you give "" no privileges are dropped. # username: "@UNBOUND_USERNAME@" # the working directory. The relative files in this config are # relative to this directory. If you give "" the working directory # is not changed. # directory: "@UNBOUND_RUN_DIR@" # the log file, "" means log to stderr. # Use of this option sets use-syslog to "no". # 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. # use-syslog: yes # print UTC timestamp in ascii to logfile, default is epoch in seconds. # log-time-ascii: no # print one line with time, IP, name, type, class for every query. # log-queries: no # the pid file. Can be an absolute path outside of chroot/work dir. # pidfile: "@UNBOUND_PIDFILE@" # file to read root hints from. # get one from https://www.internic.net/domain/named.cache # root-hints: "" # enable to not answer id.server and hostname.bind queries. # hide-identity: no # enable to not answer version.server and version.bind queries. # hide-version: no # the identity to report. Leave "" or default to return hostname. # identity: "" # the version to report. Leave "" or default to return package version. # version: "" # the target fetch policy. # series of integers describing the policy per dependency depth. # The number of values in the list determines the maximum dependency # depth the recursor will pursue before giving up. Each integer means: # -1 : fetch all targets opportunistically, # 0: fetch on demand, # positive value: fetch that many targets opportunistically. # Enclose the list of numbers between quotes (""). # target-fetch-policy: "3 2 1 0 0" # Harden against very small EDNS buffer sizes. # harden-short-bufsize: no # Harden against unseemly large queries. # harden-large-queries: no # Harden against out of zone rrsets, to avoid spoofing attempts. # harden-glue: yes # Harden against receiving dnssec-stripped data. If you turn it # off, failing to validate dnskey data for a trustanchor will # trigger insecure mode for that zone (like without a trustanchor). # Default on, which insists on dnssec data for trust-anchored zones. # harden-dnssec-stripped: yes # Harden against queries that fall under dnssec-signed nxdomain names. # harden-below-nxdomain: no # 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. # harden-referral-path: no # Harden against algorithm downgrade when multiple algorithms are # advertised in the DS record. If no, allows the weakest algorithm # to validate the zone. # harden-algo-downgrade: no # 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 # 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 # Domains (and domains in them) without support for dns-0x20 and # the fallback fails because they keep sending different answers. # caps-whitelist: "licdn.com" # Enforce privacy of these addresses. Strips them away from answers. # It may cause DNSSEC validation to additionally mark it as bogus. # Protects against 'DNS Rebinding' (uses browser as network proxy). # Only 'private-domain' and 'local-data' names are allowed to have # these private addresses. No default. # private-address: 10.0.0.0/8 # private-address: 172.16.0.0/12 # private-address: 192.168.0.0/16 # private-address: 169.254.0.0/16 # private-address: fd00::/8 # private-address: fe80::/10 # private-address: ::ffff:0:0/96 # Allow the domain (and its subdomains) to contain private addresses. # local-data statements are allowed to contain private addresses too. # private-domain: "example.com" # If nonzero, unwanted replies are not only reported in statistics, # but also a running total is kept per thread. If it reaches the # threshold, a warning is printed and a defensive action is taken, # the cache is cleared to flush potential poison out of it. # A suggested value is 10000000, the default is 0 (turned off). # unwanted-reply-threshold: 0 # Do not query the following addresses. No DNS queries are sent there. # List one address per entry. List classless netblocks with /size, # do-not-query-address: 127.0.0.1/8 # do-not-query-address: ::1 # if yes, the above default do-not-query-address entries are present. # if no, localhost can be queried (for testing and debugging). # do-not-query-localhost: yes # if yes, perform prefetching of almost expired message cache entries. # prefetch: no # if yes, perform key lookups adjacent to normal lookups. # prefetch-key: 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 # module configuration of the server. A string with identifiers # separated by spaces. Syntax: "[dns64] [validator] iterator" # module-config: "validator iterator" # File with trusted keys, kept uptodate using RFC5011 probes, # initial file like trust-anchor-file, then it stores metadata. # Use several entries, one per domain name, to track multiple zones. # # If you want to perform DNSSEC validation, run unbound-anchor before # you start unbound (i.e. in the system boot scripts). And enable: # Please note usage of unbound-anchor root anchor is at your own risk # and under the terms of our LICENSE (see that file in the source). # auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@" # 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. # dlv-anchor-file: "dlv.isc.org.key" # File with trusted keys for validation. Specify more than one file # with several entries, one file per entry. # Zone file format, with DS and DNSKEY entries. # Note this gets out of date, use auto-trust-anchor-file please. # trust-anchor-file: "" # Trusted key for validation. DS or DNSKEY. specify the RR on a # single line, surrounded by "". TTL is ignored. class is IN default. # Note this gets out of date, use auto-trust-anchor-file please. # (These examples are from August 2007 and may not be valid anymore). # trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ==" # trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A" # File with trusted keys for validation. Specify more than one file # with several entries, one file per entry. Like trust-anchor-file # but has a different file format. Format is BIND-9 style format, # the trusted-keys { name flag proto algo "key"; }; clauses are read. # you need external update procedures to track changes in keys. # trusted-keys-file: "" # Ignore chain of trust. Domain is treated as insecure. # domain-insecure: "example.com" # Override the date for validation with a specific fixed date. # Do not set this unless you are debugging signature inception # and expiration. "" or "0" turns the feature off. -1 ignores date. # val-override-date: "" # The time to live for bogus data, rrsets and messages. This avoids # some of the revalidation, until the time interval expires. in secs. # val-bogus-ttl: 60 # The signature inception and expiration dates are allowed to be off # by 10% of the signature lifetime (expir-incep) from our local clock. # This leeway is capped with a minimum and a maximum. In seconds. # val-sig-skew-min: 3600 # val-sig-skew-max: 86400 # Should additional section of secure message also be kept clean of # unsecure data. Useful to shield the users of this validator from # potential bogus data in the additional section. All unsigned data # in the additional section is removed from secure messages. # val-clean-additional: yes # Turn permissive mode on to permit bogus messages. Thus, messages # for which security checks failed will be returned to clients, # instead of SERVFAIL. It still performs the security checks, which # result in interesting log files and possibly the AD bit in # replies if the message is found secure. The default is off. # val-permissive-mode: no # Ignore the CD flag in incoming queries and refuse them bogus data. # Enable it if the only clients of unbound are legacy servers (w2008) # that set CD but cannot validate themselves. # ignore-cd-flag: 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 # It is possible to configure NSEC3 maximum iteration counts per # keysize. Keep this table very short, as linear search is done. # A message with an NSEC3 with larger count is marked insecure. # List in ascending order the keysize and count values. # val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500" # instruct the auto-trust-anchor-file probing to add anchors after ttl. # add-holddown: 2592000 # 30 days # instruct the auto-trust-anchor-file probing to del anchors after ttl. # del-holddown: 2592000 # 30 days # auto-trust-anchor-file probing removes missing anchors after ttl. # If the value 0 is given, missing anchors are not removed. # keep-missing: 31622400 # 366 days # debug option that allows very small holddown times for key rollover # permit-small-holddown: no # the amount of memory to use for the key cache. # plain value in bytes or you can append k, m or G. default is "4Mb". # key-cache-size: 4m # the number of slabs to use for the key cache. # the number of slabs must be a power of 2. # more slabs reduce lock contention, but fragment memory usage. # key-cache-slabs: 4 # the amount of memory to use for the negative cache (used for DLV). # plain value in bytes or you can append k, m or G. default is "1Mb". # neg-cache-size: 1m # By default, for a number of zones a small default 'nothing here' # reply is built-in. Query traffic is thus blocked. If you # wish to serve such zone you can unblock them by uncommenting one # of the nodefault statements below. # You may also have to use domain-insecure: zone to make DNSSEC work, # unless you have your own trust anchors for this zone. # local-zone: "localhost." nodefault # 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: "10.in-addr.arpa." nodefault # local-zone: "16.172.in-addr.arpa." nodefault # local-zone: "17.172.in-addr.arpa." nodefault # local-zone: "18.172.in-addr.arpa." nodefault # local-zone: "19.172.in-addr.arpa." nodefault # local-zone: "20.172.in-addr.arpa." nodefault # local-zone: "21.172.in-addr.arpa." nodefault # local-zone: "22.172.in-addr.arpa." nodefault # local-zone: "23.172.in-addr.arpa." nodefault # local-zone: "24.172.in-addr.arpa." nodefault # local-zone: "25.172.in-addr.arpa." nodefault # local-zone: "26.172.in-addr.arpa." nodefault # local-zone: "27.172.in-addr.arpa." nodefault # local-zone: "28.172.in-addr.arpa." nodefault # local-zone: "29.172.in-addr.arpa." nodefault # local-zone: "30.172.in-addr.arpa." nodefault # local-zone: "31.172.in-addr.arpa." nodefault # local-zone: "168.192.in-addr.arpa." nodefault # local-zone: "0.in-addr.arpa." nodefault # local-zone: "254.169.in-addr.arpa." nodefault # local-zone: "2.0.192.in-addr.arpa." nodefault # local-zone: "100.51.198.in-addr.arpa." nodefault # local-zone: "113.0.203.in-addr.arpa." nodefault # local-zone: "255.255.255.255.in-addr.arpa." nodefault # local-zone: "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." nodefault # local-zone: "d.f.ip6.arpa." nodefault # local-zone: "8.e.f.ip6.arpa." nodefault # local-zone: "9.e.f.ip6.arpa." nodefault # local-zone: "a.e.f.ip6.arpa." nodefault # local-zone: "b.e.f.ip6.arpa." nodefault # 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. - # if unbound is running service for the local host then it is useful + # 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 # for a network of computers, disabled is better and stops information # leakage of local lan information. # unblock-lan-zones: no + + # The insecure-lan-zones option disables validation for + # these zones, as if they were all listed as domain-insecure. + # insecure-lan-zones: no # a number of locally served zones can be configured. # local-zone: # local-data: "" # o deny serves local data (if any), else, drops queries. # o refuse serves local data (if any), else, replies with error. # o static serves local data, else, nxdomain or nodata answer. # o transparent gives local data, but resolves normally for other names # 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_deny drops queries and logs client IP address # # defaults are localhost address, reverse for 127.0.0.1 and ::1 # and nxdomain for AS112 zones. If you configure one of these zones # the default content is omitted, or you can omit it with 'nodefault'. # # If you configure local-data without specifying local-zone, by # default a transparent local-zone is created for the data. # # You can add locally served data with # local-zone: "local." static # local-data: "mycomputer.local. IN A 192.0.2.51" # local-data: 'mytext.local TXT "content of text record"' # # You can override certain queries with # local-data: "adserver.example.com A 127.0.0.1" # # You can redirect a domain to a fixed address with # (this makes example.com, www.example.com, etc, all go to 192.0.2.3) # local-zone: "example.com" redirect # local-data: "example.com A 192.0.2.3" # # Shorthand to make PTR records, "IPv4 name" or "IPv6 name". # You can also add PTR records using local-data directly, but then # you need to do the reverse notation yourself. # local-data-ptr: "192.0.2.3 www.example.com" # service clients over SSL (on the TCP sockets), with plain DNS inside # the SSL 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 # request upstream over SSL (with plain DNS inside the SSL stream). # Default is no. Can be turned on and off with unbound-control. # ssl-upstream: no # 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 # 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. # ratelimit: 0 # ratelimits are tracked in a cache, size in bytes of cache (or k,m). # ratelimit-size: 4m # ratelimit cache slabs, reduces lock contention if equal to cpucount. # ratelimit-slabs: 4 # 0 blocks when ratelimited, otherwise let 1/xth traffic through # ratelimit-factor: 10 # override the ratelimit for a specific domain name. # give this setting multiple times to have multiple overrides. # ratelimit-for-domain: example.com 1000 # override the ratelimits for all domains below a domain name # can give this multiple times, the name closest to the zone is used. # ratelimit-below-domain: example 1000 # Python config section. To enable: # o use --with-pythonmodule to configure before compiling. # o list python in the module-config string (above) to enable. # o and give a python-script to run. python: # Script file to load # python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py" # Remote control config section. remote-control: # Enable remote control with unbound-control(8) here. # 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. # control-interface: 127.0.0.1 # control-interface: ::1 # port number for remote control operations. # control-port: 8953 # unbound server key file. # server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key" # unbound server certificate file. # server-cert-file: "@UNBOUND_RUN_DIR@/unbound_server.pem" # unbound-control key file. # control-key-file: "@UNBOUND_RUN_DIR@/unbound_control.key" # unbound-control certificate file. # control-cert-file: "@UNBOUND_RUN_DIR@/unbound_control.pem" # Stub zones. # Create entries like below, to make all queries for 'example.com' and # 'example.org' go to the given list of nameservers. list zero or more # nameservers by hostname or by ipaddress. If you set stub-prime to yes, # the list is treated as priming hints (default is no). # With stub-first yes, it attempts without the stub if it fails. # Consider adding domain-insecure: name and local-zone: name nodefault # to the server: section if the stub is a locally served zone. # stub-zone: # name: "example.com" # stub-addr: 192.0.2.68 # stub-prime: no # stub-first: no # stub-zone: # name: "example.org" # stub-host: ns.example.com. # Forward zones # Create entries like below, to make all queries for 'example.com' and # 'example.org' go to the given list of servers. These servers have to handle # recursion to other nameservers. List zero or more nameservers by hostname # or by ipaddress. Use an entry with name "." to forward all queries. # If you enable forward-first, it attempts without the forward if it fails. # forward-zone: # name: "example.com" # forward-addr: 192.0.2.68 # forward-addr: 192.0.2.73@5355 # forward to port 5355. # forward-first: no # forward-zone: # name: "example.org" # forward-host: fwd.example.com Index: vendor/unbound/dist/doc/unbound.conf.5.in =================================================================== --- vendor/unbound/dist/doc/unbound.conf.5.in (revision 295529) +++ vendor/unbound/dist/doc/unbound.conf.5.in (revision 295530) @@ -1,1281 +1,1286 @@ .TH "unbound.conf" "5" "Dec 10, 2015" "NLnet Labs" "unbound 1.5.7" .\" .\" unbound.conf.5 -- unbound.conf manual .\" .\" Copyright (c) 2007, NLnet Labs. All rights reserved. .\" .\" See LICENSE for the license. .\" .\" .SH "NAME" .B unbound.conf \- Unbound configuration file. .SH "SYNOPSIS" .B unbound.conf .SH "DESCRIPTION" .B unbound.conf is used to configure \fIunbound\fR(8). 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 \fIunbound\-checkconf\fR(8) can be used to check unbound.conf prior to usage. .SH "EXAMPLE" An example config file is shown below. Copy this to /etc/unbound/unbound.conf and start the server with: .P .nf $ unbound \-c /etc/unbound/unbound.conf .fi .P Most settings are the defaults. Stop the server with: .P .nf $ kill `cat /etc/unbound/unbound.pid` .fi .P Below is a minimal config file. The source distribution contains an extensive example.conf file with all the options. .P .nf # unbound.conf(5) config file for unbound(8). server: directory: "/etc/unbound" username: unbound # make sure unbound can access entropy from inside the chroot. # e.g. on linux the use these commands (on BSD, devfs(8) is used): # mount \-\-bind \-n /dev/random /etc/unbound/dev/random # and mount \-\-bind \-n /dev/log /etc/unbound/dev/log chroot: "/etc/unbound" # logfile: "/etc/unbound/unbound.log" #uncomment to use logfile. pidfile: "/etc/unbound/unbound.pid" # verbosity: 1 # uncomment and increase to get more logging. # listen on all interfaces, answer queries from the local subnet. interface: 0.0.0.0 interface: ::0 access\-control: 10.0.0.0/8 allow 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. .P Files can be included using the .B include: directive. It can appear anywhere, it accepts a single file name as argument. 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 directory. Wildcards can be used to include multiple files, see \fIglob\fR(7). .SS "Server Options" These options are part of the .B server: clause. .TP .B verbosity: \fI 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. 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, requestlist statistics are printed for every interval (but can be 0). This is because the median calculation requires data to be present. .TP .B statistics\-cumulative: \fI If enabled, statistics are cumulative since starting unbound, without clearing 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). Default is off, because keeping track of more statistics takes time. The counters are listed in \fIunbound\-control\fR(8). .TP .B num\-threads: \fI The number of threads to create to serve clients. Use 1 for no threading. .TP .B port: \fI The port number, default 53, on which the server responds to queries. .TP .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 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 interface and port number), if not specified the default port (from \fBport\fR) is used. .TP .B ip\-address: \fI Same as interface: (for easy of compatibility with nsd.conf). .TP .B interface\-automatic: \fI 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 .B interface: and .B outgoing\-interface: lines, the interfaces are then used for both purposes. Outgoing queries are sent via a random outgoing interface to counter spoofing. .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 numbers need extra resources from the operating system. For performance a a very large value is best, use libevent to make this possible. .TP .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. 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 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 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. Give a port number or a range of the form "low\-high", without spaces. .TP .B outgoing\-num\-tcp: \fI Number of outgoing TCP buffers to allocate per thread. Default is 10. If set to 0, or if do\-tcp is "no", no TCP queries to authoritative servers are done. For larger installations increasing this value is a good idea. .TP .B incoming\-num\-tcp: \fI Number of incoming TCP buffers to allocate per thread. Default is 10. If set to 0, or if do\-tcp is "no", no TCP queries from clients are accepted. For larger installations increasing this value is a good idea. .TP .B edns\-buffer\-size: \fI Number of bytes size to advertise as the EDNS reassembly buffer size. This is the value put into datagrams over UDP towards peers. The actual 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 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). .TP .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. .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 reply to the client. .TP .B msg\-cache\-size: \fI Number of bytes size of the message cache. 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). .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 reasonable guess. .TP .B num\-queries\-per\-thread: \fI The number of queries that every thread will service simultaneously. If more queries arrive that need servicing, and no queries can be jostled out (see \fIjostle\-timeout\fR), then the queries are dropped. This forces the client to resend after a timeout; allowing the server time to work on the existing queries. Default depends on compile options, 512 or 1024. .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 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 service by slow queries or high query rates. Default 200 milliseconds. 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 qps by default. .TP .B delay\-close: \fI Extra delay for timeouted UDP ports before they are closed, in msec. Default is 0, and that disables it. This prevents very delayed answer packets from the upstream (recursive) servers from bouncing against closed ports and setting off all sort of close-port counters, with eg. 1500 msec. When timeouts happen you need extra sockets, it checks the ID and remote IP of packets, and unwanted packets are added to the unwanted packet counter. .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 servers do not drop packets (see counter in netstat \-su). Default is 0 (use system value). Otherwise, the number of bytes to ask for, try "4m" on a busy server. The OS caps it at a maximum, on linux unbound needs root permission to bypass the limit, or the admin can use sysctl net.core.rmem_max. On BSD change kern.ipc.maxsockbuf in /etc/sysctl.conf. On OpenBSD change header and recompile kernel. On Solaris ndd \-set /dev/udp udp_max_buf 8388608. .TP .B so\-sndbuf: \fI If not 0, then set the SO_SNDBUF socket option to get more buffer space on UDP port 53 outgoing queries. This for very busy servers handles spikes in answer traffic, otherwise 'send: resource temporarily unavailable' can get logged, the buffer overrun is also visible by netstat \-su. Default is 0 (use system value). Specify the number of bytes to ask for, try "4m" on a very busy server. The OS caps it at a maximum, on linux unbound needs root permission to bypass the limit, or the admin can use sysctl net.core.wmem_max. On BSD, Solaris changes are similar to so\-rcvbuf. .TP .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), 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. .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 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. .TP .B rrset\-cache\-size: \fI Number of bytes size of the RRset cache. 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). .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. .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. Can be set lower to force the resolver to query for data often, and not trust (very large) TTL values. .TP .B cache\-min\-ttl: \fI Time to live minimum for RRsets and messages in the cache. Default is 0. 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 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. .TP .B infra\-host\-ttl: \fI 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. .TP .B infra\-cache\-numhosts: \fI Number of hosts for which information is cached. Default is 10000. .TP .B infra\-cache\-min\-rtt: \fI Lower limit for dynamic retransmit timeout calculation in infrastructure cache. Default is 50 milliseconds. Increase this value if using forwarders needing more time to do recursive name resolution. .TP .B do\-ip4: \fI Enable or disable whether ip4 queries are answered or issued. Default is yes. .TP .B do\-ip6: \fI Enable or disable whether ip6 queries are answered or issued. Default is yes. If disabled, queries are not answered on IPv6, and queries are not sent on IPv6 to the internet nameservers. With this option you can disable the ipv6 transport for sending DNS traffic, it does not impact the contents of the DNS traffic, which may have ip4 and ip6 addresses in it. .TP .B do\-udp: \fI Enable or disable whether UDP queries are answered or issued. Default is yes. .TP .B do\-tcp: \fI Enable or disable whether TCP queries are answered or issued. Default is yes. .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 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). .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. .TP .B ssl\-service\-pem: \fI The public key certificate pem file for the ssl service. Default is "", turned off. .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. .TP .B do\-daemonize: \fI Enable or disable whether the unbound server forks into the background as a daemon. Default is yes. .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 most specific netblock match is used, if none match \fIdeny\fR is used. .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 error message back. .IP 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 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 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 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 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 dropping may result in (possibly excessive) retried queries. .IP The deny_non_local and refuse_non_local settings are for hosts that are only allowed to query for the authoritative local\-data, they are not allowed full recursion but only the static data. With deny_non_local, messages that are disallowed are dropped, with refuse_non_local they receive error code REFUSED. .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. .IP All other file paths (working dir, logfile, roothints, and key files) can be specified in several ways: as an absolute path relative to the new root, as a relative path to the working directory, or as an absolute path relative to the original root. In the last case the path is adjusted to remove the unused portion. .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 /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 "@UNBOUND_CHROOT_DIR@". 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_USERNAME@". 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 requires privileges, then a reload will fail; a restart is needed. .TP .B directory: \fI Sets the working directory for the program. Default is "@UNBOUND_RUN_DIR@". On Windows the string "%EXECUTABLE%" tries to change to the directory that unbound.exe resides in. .TP .B logfile: \fI If "" is given, logging goes to stderr, or nowhere once daemonized. The logfile is appended to, in the following format: .nf [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 SIGHUP. .TP .B use\-syslog: \fI 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\-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 that case syslog formats the timestamp printed into the log files. .TP .B log\-queries: \fI Prints one line per query to the log, with the log timestamp and IP address, name, type and class. 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 pidfile: \fI The process id is written to the file. Default is "@UNBOUND_PIDFILE@". So, .nf kill \-HUP `cat @UNBOUND_PIDFILE@` .fi triggers a reload, .nf kill \-TERM `cat @UNBOUND_PIDFILE@` .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 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 .B hide\-identity: \fI If enabled id.server and hostname.bind queries are refused. .TP .B identity: \fI Set the identity to report. If set to "", the default, then the hostname of the server is returned. .TP .B hide\-version: \fI If enabled version.server and version.bind queries are refused. .TP .B version: \fI Set the version to report. If set to "", the default, then the package version is returned. .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. .IP The number of values determines the maximum dependency depth 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. .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 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 small answers to these queries, where possible. .TP .B harden\-large\-queries: \fI Very large queries are ignored. Default is off, since it is legal protocol wise to send these, and could be necessary for operation if TSIG or EDNS payload is very large. .TP .B harden\-glue: \fI Will trust glue only if it is within the servers authority. Default is on. .TP .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 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 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. .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 path to the answer. Default off, 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 to increase the max depth that is checked to. .TP .B harden\-algo\-downgrade: \fI Harden against algorithm downgrade when multiple algorithms are advertised in the DS record. If no, allows the weakest algorithm to validate the zone. Default is no. Zone signers must produce zones that allow this feature to work, but sometimes they do not, and turning this option off avoids that validation failure. .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 feature is an experimental implementation of draft dns\-0x20. .TP .B caps\-whitelist: \fI Whitelist the domain so that it does not receive caps\-for\-id perturbed queries. For domains that do not support 0x20 and also fail with fallback because they keep sending different answers, like some load balancers. Can be given multiple times, for different domains. .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. .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 public internet names. Any occurrence of such addresses are removed from DNS answers. Additionally, the DNSSEC validator may mark the answers bogus. This protects against so\-called DNS Rebinding, where a user browser is turned into a network proxy, allowing remote access through the browser to other parts of your private network. Some names can be allowed to contain your private addresses, by default all the \fBlocal\-data\fR that you configured is allowed to, and you can specify additional names using \fBprivate\-domain\fR. No private addresses are enabled by default. We consider to enable this for the RFC1918 private IP address space by default in later releases. That would enable private addresses for 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 fd00::/8 and fe80::/10, since the RFC standards say these addresses should not be visible on the public internet. Turning on 127.0.0.0/8 would hinder many spamblocklists as they use that. Adding ::ffff:0:0/96 stops IPv4-mapped IPv6 addresses from bypassing the filter. .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 addresses. Default is none. .TP .B unwanted\-reply\-threshold: \fI If set, a total number of unwanted replies is kept track of in every thread. When it reaches the threshold, a defensive action is taken and a warning is printed to the log. The defensive action is to clear the rrset and message caches, hopefully flushing away any poison. A value of 10 million 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 indicate a classless delegation netblock, for example like 10.2.3.4/24 or 2001::11/64. .TP .B do\-not\-query\-localhost: \fI If yes, localhost is added to the do\-not\-query\-address entries, both IP6 ::1 and IP4 127.0.0.1/8. If no, then localhost can be used to send queries to. Default is yes. .TP .B prefetch: \fI If yes, message cache elements are prefetched before they expire to keep the cache up to date. Default is no. Turning it on gives about 10 percent more traffic and load on the machine, but popular items do not expire from the cache. .TP .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 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 .B minimal-responses: \fI 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 protocol RFCs mandate these sections, and the additional content could be of use and save roundtrips for clients. .TP .B module\-config: \fI<"module names"> Module configuration, a list of module names separated by spaces, surround the string with quotes (""). The modules can be validator, iterator. Setting this to "iterator" will result in a non\-validating server. 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. .TP .B trust\-anchor\-file: \fI File with trusted keys for validation. Both DS and DNSKEY entries can appear in the file. The format of the file is the standard DNS Zone file format. Default is "", or no trust anchor file. .TP .B auto\-trust\-anchor\-file: \fI File with trust anchor for one zone, which is tracked with RFC5011 probes. The probes are several times per month, thus the machine must be online frequently. The initial file can be one with contents as described in \fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated, so the unbound user must have write permission. .TP .B trust\-anchor: \fI<"Resource Record"> A DS or DNSKEY RR for a key to use for validation. Multiple entries can be 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. 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, 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 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 DS records registered with the parent zone (many top level zones are signed). 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. .TP .B dlv\-anchor: \fI<"Resource Record"> Much like trust\-anchor, this is a DLV anchor with the DS or DNSKEY inline. DLV is going to be decommissioned. Please do not use it any more. .TP .B domain\-insecure: \fI Sets domain name to be insecure, DNSSEC chain of trust is ignored towards the domain name. So a trust anchor above the domain name can not make the 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 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 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 you are debugging signature inception and expiration. The value \-1 ignores the date altogether, useful for some special applications. .TP .B val\-sig\-skew\-min: \fI Minimum number of seconds of clock skew to apply to validated signatures. A value of 10% of the signature lifetime (expiration \- inception) is used, capped by this setting. Default is 3600 (1 hour) which allows for daylight savings differences. Lower this value for more strict checking of short lived signatures. .TP .B val\-sig\-skew\-max: \fI Maximum number of seconds of clock skew to apply to validated signatures. A value of 10% of the signature lifetime (expiration \- inception) is used, capped by this setting. Default is 86400 (24 hours) which allows for timezone setting problems in stable domains. Setting both min and max very low disables the clock skew allowances. Setting both min and max very high makes the validator check the signature timestamps less strictly. .TP .B val\-bogus\-ttl: \fI The time to live for bogus data. This is data that has failed validation; due to invalid signatures or other checks. The TTL from that data cannot be trusted, and this value is used instead. The value is in seconds, default 60. The time interval prevents repeated revalidation of bogus data. .TP .B val\-clean\-additional: \fI 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 potentially bad data in the additional section. .TP .B val\-log\-level: \fI Have the validator print validation failures to the log. Regardless of the verbosity setting. Default is 0, off. At 1, for every user query that fails a line is printed to the logs. This way you can monitor what happens with validation. Use a diagnosis tool, such as dig or drill, to find out why validation is failing for these queries. At 2, not only the query that failed is printed but also the reason why unbound thought it was wrong and which server sent the faulty data. .TP .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 is set in replies. Also logging is performed as for full validation. The default value is "no". .TP .B ignore\-cd\-flag: \fI Instruct unbound to ignore the CD flag from clients and refuse to return bogus answers to them. Thus, the CD (Checking Disabled) flag does not disable checking any more. This is useful if legacy (w2008) servers that set the CD flag but cannot validate DNSSEC themselves are the clients, and then unbound provides them with DNSSEC protection. The default value 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 "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 .B add\-holddown: \fI Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011 autotrust updates to add new trust anchors only after they have been visible for this time. Default is 30 days as per the RFC. .TP .B del\-holddown: \fI Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011 autotrust updates to remove revoked trust anchors after they have been kept in the revoked list for this long. Default is 30 days as per the RFC. .TP .B keep\-missing: \fI Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011 autotrust updates to remove missing trust anchors after they have been unseen for this long. This cleans up the state file if the target zone does not perform trust anchor revocation, so this makes the auto probe mechanism work with zones that perform regular (non\-5011) rollovers. The default is 366 days. The value 0 does not remove missing anchors, as per the RFC. .TP .B permit\-small\-holddown: \fI Debug option that allows the autotrust 5011 rollover timers to assume very small values. Default is no. .TP .B key\-cache\-size: \fI Number of bytes size of the key cache. 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). .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 reasonable guess. .TP .B neg\-cache\-size: \fI Number of bytes size of the aggressive negative cache. Default is 1 megabyte. 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 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, to put out all of the queries for the 'lan' upstream. When enabled, only localhost, 127.0.0.1 reverse and ::1 reverse zones are configured with default local zones. Disable the option when unbound is running as a (DHCP-) DNS network resolver for a group of machines, where such 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 +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. +.TP .B local\-zone: \fI 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, 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. .IP If you need more complicated authoritative data, with referrals, wildcards, CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for it as detailed in the stub zone section below. .TP 10 \h'5'\fIdeny\fR Do not send an answer, drop the query. If there is a match from local data, the query is answered. .TP 10 \h'5'\fIrefuse\fR Send an error message reply, with rcode REFUSED. If there is a match from local data, the query is answered. .TP 10 \h'5'\fIstatic\fR If there is a match from local data, the query is answered. Otherwise, the query is answered with nodata or nxdomain. 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 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 given in localdata, then a noerror nodata answer is returned. If no local\-zone is given local\-data causes a transparent zone to be created by default. .TP 10 \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 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 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 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. .TP 10 \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'\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 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, 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 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\-data: "localhost. 10800 IN NS localhost." 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 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 SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" local\-data: "1.0.0.127.in\-addr.arpa. 10800 IN PTR localhost." .fi .TP 10 \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 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 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 PTR localhost." .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 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, 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 .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. .fi .TP 10 \h'5'\fIreverse RFC4193 IPv6 Locally Assigned Local Addresses\fR Reverse data for zone D.F.ip6.arpa. .TP 10 \h'5'\fIreverse RFC4291 IPv6 Link Local Addresses\fR Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa. .TP 10 \h'5'\fIreverse IPv6 Example Prefix\fR Reverse data for zone 8.B.D.0.1.0.0.2.ip6.arpa. This zone is used for tutorials and examples. You can remove the block on this zone with: .nf local\-zone: 8.B.D.0.1.0.0.2.ip6.arpa. nodefault .fi You can also selectively unblock a part of the zone by making that part transparent with a local\-zone statement. This also works with the other default zones. .\" End of local-zone listing. .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 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 local\-data: 'example. TXT "text"'. .IP If you need more complicated authoritative data, with referrals, wildcards, CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for it as detailed in the stub zone section below. .TP 5 .B local\-data\-ptr: \fI"IPaddr name" Configure local data shorthand for a PTR record with the reversed IPv4 or IPv6 address and the host name. For example "192.0.2.4 www.example.com". TTL can be inserted like this: "2001:DB8::4 7200 www.example.com" .TP 5 .B ratelimit: \fI Enable ratelimiting of queries sent to nameserver for performing recursion. 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 turned away with an error (servfail). This stops recursive floods, eg. random query names, but not spoofed reflection floods. Cached responses are not ratelimited by this setting. The zone of the query is determined by examining the nameservers for it, the zone name is used to keep track of the rate. For example, 1000 may be a suitable value to stop the server from being overloaded with random names, and keeps unbound from sending traffic to the nameservers for those zones. .TP 5 .B 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 ratelimit structure is small, so this data structure likely does not need to be large. .TP 5 .B ratelimit\-slabs: \fI Give power of 2 number of slabs, this is used to reduce lock contention in the ratelimit tracking data structure. Close to the number of cpus is a fairly good setting. .TP 5 .B 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 domains 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 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. .TP 5 .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 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. .SS "Remote Control Options" In the .B remote\-control: 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 \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. .TP 5 .B control\-enable: \fI The option is used to enable remote control, default is "no". If turned off, the server does not listen for control commands. .TP 5 .B control\-interface: \fI Give IPv4 or IPv6 addresses or local socket path to listen on for control commands. By default localhost (127.0.0.1 and ::1) is listened to. 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. .TP 5 .B control\-port: \fI The port number to listen on for IPv4 or IPv6 control interfaces, default is 8953. If you change this and permissions have been dropped, you must restart 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. .TP 5 .B server\-key\-file: \fI Path to the server private key, by default unbound_server.key. This file is generated by the \fIunbound\-control\-setup\fR utility. This file is used by the unbound server, but not by \fIunbound\-control\fR. .TP 5 .B server\-cert\-file: \fI Path to the server self signed certificate, by default unbound_server.pem. This file is generated by the \fIunbound\-control\-setup\fR utility. This file is used by the unbound server, and also by \fIunbound\-control\fR. .TP 5 .B control\-key\-file: \fI Path to the control client private key, by default unbound_control.key. This file is generated by the \fIunbound\-control\-setup\fR utility. This file is used by \fIunbound\-control\fR. .TP 5 .B control\-cert\-file: \fI Path to the control client certificate, by default unbound_control.pem. This certificate has to be signed with the server certificate. This file is generated by the \fIunbound\-control\-setup\fR utility. This file is used by \fIunbound\-control\fR. .SS "Stub Zone Options" .LP There may be multiple .B stub\-zone: clauses. Each with a name: and zero or more hostnames or IP addresses. For the stub zone this list of nameservers is used. Class IN is assumed. The servers should be authority servers, not recursors; unbound performs the recursive processing itself for stub zones. .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 .B stub\-addr: . 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 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. .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 served zone. The insecure clause stops DNSSEC from invalidating the zone. The local zone nodefault (or \fItransparent\fR) clause makes the (reverse\-) zone bypass unbound's filtering of RFC1918 zones. .TP .B name: \fI Name of the stub zone. .TP .B stub\-host: \fI Name of stub zone nameserver. Is itself resolved before it is used. .TP .B stub\-addr: \fI IP address of stub zone nameserver. Can be IP 4 or IP 6. 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 currently published by the zone. Thus, if the hint list is slightly outdated, the resolver picks up a correct list online. .TP .B stub\-first: \fI If enabled, a query is attempted without the stub 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. The default is no. .SS "Forward Zone Options" .LP There may be multiple .B forward\-zone: clauses. Each with a \fBname:\fR and zero or more hostnames or IP addresses. For the forward zone this list of nameservers is used to forward the queries to. The servers listed as \fBforward\-host:\fR and \fBforward\-addr:\fR have to handle further recursion for the query. Thus, 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. 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). .TP .B name: \fI Name of the forward zone. .TP .B forward\-host: \fI Name of server to forward to. Is itself resolved before it is used. .TP .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. .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. The default is no. .SS "Python Module Options" .LP The .B python: clause gives the settings for the \fIpython\fR(1) script module. This module acts like the iterator and validator modules do, on queries and answers. To enable the script module it has to be compiled into the daemon, and the word "python" has to be put in the \fBmodule\-config:\fR option (usually first, or between the validator and iterator). .TP .B python\-script: \fI\fR The script file to load. .SS "DNS64 Module Options" .LP The dns64 module must be configured in the \fBmodule\-config:\fR "dns64 validator iterator" directive and be compiled into the daemon to be enabled. These settings go in the \fBserver:\fR section. .TP .B dns64\-prefix: \fI\fR This sets the DNS64 prefix to use to synthesize AAAA records with. It must be /96 or shorter. The default prefix is 64:ff9b::/96. .TP .B dns64\-synthall: \fI\fR Debug option, default no. If enabled, synthesize all AAAA records despite the presence of actual AAAA records. .SH "MEMORY CONTROL EXAMPLE" In the example config settings below memory usage is reduced. Some service levels are lower, notable very large data and a high TCP load are no longer supported. Very large data and high TCP loads are exceptional for the DNS. DNSSEC validation is enabled, just add trust anchors. If you do not have to worry about programs using more than 3 Mb of memory, the below example is not for you. Use the defaults to receive full service, which on BSD\-32bit tops out at 30\-40 Mb after heavy usage. .P .nf # example settings that reduce memory usage server: num\-threads: 1 outgoing\-num\-tcp: 1 # this limits TCP service, uses less buffers. incoming\-num\-tcp: 1 outgoing\-range: 60 # uses less memory, but less performance. msg\-buffer\-size: 8192 # note this limits service, 'no huge stuff'. msg\-cache\-size: 100k msg\-cache\-slabs: 1 rrset\-cache\-size: 100k rrset\-cache\-slabs: 1 infra\-cache\-numhosts: 200 infra\-cache\-slabs: 1 key\-cache\-size: 100k key\-cache\-slabs: 1 neg\-cache\-size: 10k num\-queries\-per\-thread: 30 target\-fetch\-policy: "2 1 0 0 0 0" harden\-large\-queries: "yes" harden\-short\-bufsize: "yes" .fi .SH "FILES" .TP .I @UNBOUND_RUN_DIR@ default unbound working directory. .TP .I @UNBOUND_CHROOT_DIR@ default \fIchroot\fR(2) location. .TP .I @ub_conf_file@ unbound configuration file. .TP .I @UNBOUND_PIDFILE@ default unbound pidfile with process ID of the running daemon. .TP .I unbound.log unbound log file. default is to log to \fIsyslog\fR(3). .SH "SEE ALSO" \fIunbound\fR(8), \fIunbound\-checkconf\fR(8). .SH "AUTHORS" .B Unbound was written by NLnet Labs. Please see CREDITS file in the distribution for further details. Index: vendor/unbound/dist/services/localzone.c =================================================================== --- vendor/unbound/dist/services/localzone.c (revision 295529) +++ vendor/unbound/dist/services/localzone.c (revision 295530) @@ -1,1435 +1,1341 @@ /* * services/localzone.c - local zones authority service. * * Copyright (c) 2007, 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 functions to enable local zone authority service. */ #include "config.h" #include "services/localzone.h" #include "sldns/str2wire.h" #include "sldns/sbuffer.h" #include "util/regional.h" #include "util/config_file.h" #include "util/data/dname.h" #include "util/data/packed_rrset.h" #include "util/data/msgencode.h" #include "util/net_help.h" #include "util/netevent.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" +#include "util/as112.h" struct local_zones* local_zones_create(void) { struct local_zones* zones = (struct local_zones*)calloc(1, sizeof(*zones)); if(!zones) return NULL; rbtree_init(&zones->ztree, &local_zone_cmp); lock_rw_init(&zones->lock); lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree)); /* also lock protects the rbnode's in struct local_zone */ return zones; } /** helper traverse to delete zones */ static void lzdel(rbnode_t* n, void* ATTR_UNUSED(arg)) { struct local_zone* z = (struct local_zone*)n->key; local_zone_delete(z); } void local_zones_delete(struct local_zones* zones) { if(!zones) return; lock_rw_destroy(&zones->lock); /* walk through zones and delete them all */ traverse_postorder(&zones->ztree, lzdel, NULL); free(zones); } void local_zone_delete(struct local_zone* z) { if(!z) return; lock_rw_destroy(&z->lock); regional_destroy(z->region); free(z->name); free(z); } int local_zone_cmp(const void* z1, const void* z2) { /* first sort on class, so that hierarchy can be maintained within * a class */ struct local_zone* a = (struct local_zone*)z1; struct local_zone* b = (struct local_zone*)z2; int m; if(a->dclass != b->dclass) { if(a->dclass < b->dclass) return -1; return 1; } return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m); } int local_data_cmp(const void* d1, const void* d2) { struct local_data* a = (struct local_data*)d1; struct local_data* b = (struct local_data*)d2; int m; return dname_canon_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m); } /* form wireformat from text format domain name */ int parse_dname(const char* str, uint8_t** res, size_t* len, int* labs) { *res = sldns_str2wire_dname(str, len); *labs = 0; if(!*res) { log_err("cannot parse name %s", str); return 0; } *labs = dname_count_size_labels(*res, len); return 1; } /** create a new localzone */ static struct local_zone* local_zone_create(uint8_t* nm, size_t len, int labs, enum localzone_type t, uint16_t dclass) { struct local_zone* z = (struct local_zone*)calloc(1, sizeof(*z)); if(!z) { return NULL; } z->node.key = z; z->dclass = dclass; z->type = t; z->name = nm; z->namelen = len; z->namelabs = labs; lock_rw_init(&z->lock); z->region = regional_create(); if(!z->region) { free(z); return NULL; } rbtree_init(&z->data, &local_data_cmp); lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_t)); /* also the zones->lock protects node, parent, name*, class */ return z; } /** enter a new zone with allocated dname returns with WRlock */ static struct local_zone* lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, int labs, enum localzone_type t, uint16_t c) { struct local_zone* z = local_zone_create(nm, len, labs, t, c); if(!z) { log_err("out of memory"); return NULL; } /* add to rbtree */ lock_rw_wrlock(&zones->lock); lock_rw_wrlock(&z->lock); if(!rbtree_insert(&zones->ztree, &z->node)) { log_warn("duplicate local-zone"); lock_rw_unlock(&z->lock); local_zone_delete(z); lock_rw_unlock(&zones->lock); return NULL; } lock_rw_unlock(&zones->lock); return z; } /** enter a new zone */ static struct local_zone* lz_enter_zone(struct local_zones* zones, const char* name, const char* type, uint16_t dclass) { struct local_zone* z; enum localzone_type t; uint8_t* nm; size_t len; int labs; if(!parse_dname(name, &nm, &len, &labs)) { log_err("bad zone name %s %s", name, type); return NULL; } if(!local_zone_str2type(type, &t)) { log_err("bad lz_enter_zone type %s %s", name, type); free(nm); return NULL; } if(!(z=lz_enter_zone_dname(zones, nm, len, labs, t, dclass))) { log_err("could not enter zone %s %s", name, type); return NULL; } return z; } /** return name and class and rdata of rr; parses string */ static int get_rr_content(const char* str, uint8_t** nm, uint16_t* type, uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len, uint8_t** rdata, size_t* rdata_len) { size_t dname_len = 0; int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, NULL, 0, NULL, 0); if(e) { log_err("error parsing local-data at %d: '%s': %s", LDNS_WIREPARSE_OFFSET(e), str, sldns_get_errorstr_parse(e)); return 0; } *nm = memdup(rr, dname_len); if(!*nm) { log_err("out of memory"); return 0; } *dclass = sldns_wirerr_get_class(rr, len, dname_len); *type = sldns_wirerr_get_type(rr, len, dname_len); *ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len); *rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len); *rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2; return 1; } /** return name and class of rr; parses string */ static int get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass) { uint8_t rr[LDNS_RR_BUF_SIZE]; size_t len = sizeof(rr), dname_len = 0; int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, NULL, 0, NULL, 0); if(s != 0) { log_err("error parsing local-data at %d '%s': %s", LDNS_WIREPARSE_OFFSET(s), str, sldns_get_errorstr_parse(s)); return 0; } *nm = memdup(rr, dname_len); *dclass = sldns_wirerr_get_class(rr, len, dname_len); if(!*nm) { log_err("out of memory"); return 0; } return 1; } /** * Find an rrset in local data structure. * @param data: local data domain name structure. * @param type: type to look for (host order). * @return rrset pointer or NULL if not found. */ static struct local_rrset* local_data_find_type(struct local_data* data, uint16_t type) { struct local_rrset* p; type = htons(type); for(p = data->rrsets; p; p = p->next) { if(p->rrset->rk.type == type) return p; } return NULL; } /** check for RR duplicates */ static int rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len) { size_t i; for(i=0; icount; i++) { if(pd->rr_len[i] == rdata_len && memcmp(pd->rr_data[i], rdata, rdata_len) == 0) return 1; } return 0; } /** new local_rrset */ static struct local_rrset* new_local_rrset(struct regional* region, struct local_data* node, uint16_t rrtype, uint16_t rrclass) { struct packed_rrset_data* pd; struct local_rrset* rrset = (struct local_rrset*) regional_alloc_zero(region, sizeof(*rrset)); if(!rrset) { log_err("out of memory"); return NULL; } rrset->next = node->rrsets; node->rrsets = rrset; rrset->rrset = (struct ub_packed_rrset_key*) regional_alloc_zero(region, sizeof(*rrset->rrset)); if(!rrset->rrset) { log_err("out of memory"); return NULL; } rrset->rrset->entry.key = rrset->rrset; pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd)); if(!pd) { log_err("out of memory"); return NULL; } pd->trust = rrset_trust_prim_noglue; pd->security = sec_status_insecure; rrset->rrset->entry.data = pd; rrset->rrset->rk.dname = node->name; rrset->rrset->rk.dname_len = node->namelen; rrset->rrset->rk.type = htons(rrtype); rrset->rrset->rk.rrset_class = htons(rrclass); return rrset; } /** insert RR into RRset data structure; Wastes a couple of bytes */ static int insert_rr(struct regional* region, struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len, time_t ttl) { size_t* oldlen = pd->rr_len; time_t* oldttl = pd->rr_ttl; uint8_t** olddata = pd->rr_data; /* add RR to rrset */ pd->count++; pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count); pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count); pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count); if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) { log_err("out of memory"); return 0; } if(pd->count > 1) { memcpy(pd->rr_len+1, oldlen, sizeof(*pd->rr_len)*(pd->count-1)); memcpy(pd->rr_ttl+1, oldttl, sizeof(*pd->rr_ttl)*(pd->count-1)); memcpy(pd->rr_data+1, olddata, sizeof(*pd->rr_data)*(pd->count-1)); } pd->rr_len[0] = rdata_len; pd->rr_ttl[0] = ttl; pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len); if(!pd->rr_data[0]) { log_err("out of memory"); return 0; } return 1; } /** find a data node by exact name */ static struct local_data* lz_find_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs) { struct local_data key; key.node.key = &key; key.name = nm; key.namelen = nmlen; key.namelabs = nmlabs; return (struct local_data*)rbtree_search(&z->data, &key.node); } /** find a node, create it if not and all its empty nonterminal parents */ static int lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs, struct local_data** res) { struct local_data* ld = lz_find_node(z, nm, nmlen, nmlabs); if(!ld) { /* create a domain name to store rr. */ ld = (struct local_data*)regional_alloc_zero(z->region, sizeof(*ld)); if(!ld) { log_err("out of memory adding local data"); return 0; } ld->node.key = ld; ld->name = regional_alloc_init(z->region, nm, nmlen); if(!ld->name) { log_err("out of memory"); return 0; } ld->namelen = nmlen; ld->namelabs = nmlabs; if(!rbtree_insert(&z->data, &ld->node)) { log_assert(0); /* duplicate name */ } /* see if empty nonterminals need to be created */ if(nmlabs > z->namelabs) { dname_remove_label(&nm, &nmlen); if(!lz_find_create_node(z, nm, nmlen, nmlabs-1, res)) return 0; } } *res = ld; return 1; } /** enter data RR into auth zone */ static int lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) { uint8_t* nm; size_t nmlen; int nmlabs; struct local_data* node; struct local_rrset* rrset; struct packed_rrset_data* pd; uint16_t rrtype = 0, rrclass = 0; time_t ttl = 0; uint8_t rr[LDNS_RR_BUF_SIZE]; uint8_t* rdata; size_t rdata_len; if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr), &rdata, &rdata_len)) { log_err("bad local-data: %s", rrstr); return 0; } log_assert(z->dclass == rrclass); if(z->type == local_zone_redirect && query_dname_compare(z->name, nm) != 0) { log_err("local-data in redirect zone must reside at top of zone" ", not at %s", rrstr); free(nm); return 0; } nmlabs = dname_count_size_labels(nm, &nmlen); if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) { free(nm); return 0; } log_assert(node); free(nm); rrset = local_data_find_type(node, rrtype); if(!rrset) { rrset = new_local_rrset(z->region, node, rrtype, rrclass); if(!rrset) return 0; if(query_dname_compare(node->name, z->name) == 0) { if(rrtype == LDNS_RR_TYPE_NSEC) rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX; if(rrtype == LDNS_RR_TYPE_SOA) z->soa = rrset->rrset; } } pd = (struct packed_rrset_data*)rrset->rrset->entry.data; log_assert(rrset && pd); /* check for duplicate RR */ if(rr_is_duplicate(pd, rdata, rdata_len)) { verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr); return 1; } return insert_rr(z->region, pd, rdata, rdata_len, ttl); } /** enter a data RR into auth data; a zone for it must exist */ static int lz_enter_rr_str(struct local_zones* zones, const char* rr) { uint8_t* rr_name; uint16_t rr_class; size_t len; int labs; struct local_zone* z; int r; if(!get_rr_nameclass(rr, &rr_name, &rr_class)) { log_err("bad rr %s", rr); return 0; } labs = dname_count_size_labels(rr_name, &len); lock_rw_rdlock(&zones->lock); z = local_zones_lookup(zones, rr_name, len, labs, rr_class); if(!z) { lock_rw_unlock(&zones->lock); fatal_exit("internal error: no zone for rr %s", rr); } lock_rw_wrlock(&z->lock); lock_rw_unlock(&zones->lock); free(rr_name); r = lz_enter_rr_into_zone(z, rr); lock_rw_unlock(&z->lock); return r; } /** parse local-zone: statements */ static int lz_enter_zones(struct local_zones* zones, struct config_file* cfg) { struct config_str2list* p; struct local_zone* z; for(p = cfg->local_zones; p; p = p->next) { if(!(z=lz_enter_zone(zones, p->str, p->str2, LDNS_RR_CLASS_IN))) return 0; lock_rw_unlock(&z->lock); } return 1; } /** lookup a zone in rbtree; exact match only; SLOW due to parse */ static int lz_exists(struct local_zones* zones, const char* name) { struct local_zone z; z.node.key = &z; z.dclass = LDNS_RR_CLASS_IN; if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) { log_err("bad name %s", name); return 0; } lock_rw_rdlock(&zones->lock); if(rbtree_search(&zones->ztree, &z.node)) { lock_rw_unlock(&zones->lock); free(z.name); return 1; } lock_rw_unlock(&zones->lock); free(z.name); return 0; } /** lookup a zone in cfg->nodefault list */ static int lz_nodefault(struct config_file* cfg, const char* name) { struct config_strlist* p; size_t len = strlen(name); if(len == 0) return 0; if(name[len-1] == '.') len--; for(p = cfg->local_zones_nodefault; p; p = p->next) { /* compare zone name, lowercase, compare without ending . */ if(strncasecmp(p->str, name, len) == 0 && (strlen(p->str) == len || (strlen(p->str)==len+1 && p->str[len] == '.'))) return 1; } return 0; } /** enter AS112 default zone */ static int add_as112_default(struct local_zones* zones, struct config_file* cfg, const char* name) { struct local_zone* z; char str[1024]; /* known long enough */ if(lz_exists(zones, name) || lz_nodefault(cfg, name)) return 1; /* do not enter default content */ if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN))) return 0; snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. " "nobody.invalid. 1 3600 1200 604800 10800", name); if(!lz_enter_rr_into_zone(z, str)) { lock_rw_unlock(&z->lock); return 0; } snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name); if(!lz_enter_rr_into_zone(z, str)) { lock_rw_unlock(&z->lock); return 0; } lock_rw_unlock(&z->lock); return 1; } /** enter default zones */ static int lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) { struct local_zone* z; + const char** zstr; /* this list of zones is from RFC 6303 */ /* block localhost level zones, first, later the LAN zones */ /* localhost. zone */ if(!lz_exists(zones, "localhost.") && !lz_nodefault(cfg, "localhost.")) { if(!(z=lz_enter_zone(zones, "localhost.", "static", LDNS_RR_CLASS_IN)) || !lz_enter_rr_into_zone(z, "localhost. 10800 IN NS localhost.") || !lz_enter_rr_into_zone(z, "localhost. 10800 IN SOA localhost. nobody.invalid. " "1 3600 1200 604800 10800") || !lz_enter_rr_into_zone(z, "localhost. 10800 IN A 127.0.0.1") || !lz_enter_rr_into_zone(z, "localhost. 10800 IN AAAA ::1")) { log_err("out of memory adding default zone"); if(z) { lock_rw_unlock(&z->lock); } return 0; } lock_rw_unlock(&z->lock); } /* reverse ip4 zone */ if(!lz_exists(zones, "127.in-addr.arpa.") && !lz_nodefault(cfg, "127.in-addr.arpa.")) { if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static", LDNS_RR_CLASS_IN)) || !lz_enter_rr_into_zone(z, "127.in-addr.arpa. 10800 IN NS localhost.") || !lz_enter_rr_into_zone(z, "127.in-addr.arpa. 10800 IN SOA localhost. " "nobody.invalid. 1 3600 1200 604800 10800") || !lz_enter_rr_into_zone(z, "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { log_err("out of memory adding default zone"); if(z) { lock_rw_unlock(&z->lock); } return 0; } lock_rw_unlock(&z->lock); } /* reverse ip6 zone */ if(!lz_exists(zones, "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.") && !lz_nodefault(cfg, "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.")) { if(!(z=lz_enter_zone(zones, "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", LDNS_RR_CLASS_IN)) || !lz_enter_rr_into_zone(z, "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 NS localhost.") || !lz_enter_rr_into_zone(z, "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 SOA localhost. " "nobody.invalid. 1 3600 1200 604800 10800") || !lz_enter_rr_into_zone(z, "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 PTR localhost.")) { log_err("out of memory adding default zone"); if(z) { lock_rw_unlock(&z->lock); } return 0; } lock_rw_unlock(&z->lock); } - /* if unblock lan-zones, then do not add the zones below. - * we do add the zones above, about 127.0.0.1, because localhost is - * not on the lan. */ - if(cfg->unblock_lan_zones) - return 1; - - /* block LAN level zones */ - if ( !add_as112_default(zones, cfg, "10.in-addr.arpa.") || - !add_as112_default(zones, cfg, "16.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "17.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "18.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "19.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "20.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "21.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "22.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "23.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "24.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "25.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "26.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "27.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "28.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "29.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "30.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "31.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "168.192.in-addr.arpa.") || - !add_as112_default(zones, cfg, "0.in-addr.arpa.") || - !add_as112_default(zones, cfg, "64.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "65.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "66.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "67.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "68.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "69.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "70.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "71.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "72.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "73.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "74.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "75.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "76.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "77.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "78.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "79.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "80.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "81.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "82.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "83.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "84.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "85.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "86.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "87.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "88.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "89.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "90.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "91.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "92.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "93.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "94.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "95.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "96.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "97.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "98.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "99.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "100.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "101.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "102.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "103.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "104.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "105.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "106.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "107.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "108.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "109.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "110.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "111.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "112.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "113.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "114.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "115.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "116.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "117.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "118.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "119.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "120.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "121.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "122.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "123.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "124.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "125.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "126.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "127.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "254.169.in-addr.arpa.") || - !add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") || - !add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") || - !add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") || - !add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") || - !add_as112_default(zones, cfg, "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.") || - !add_as112_default(zones, cfg, "d.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) { - log_err("out of memory adding default zone"); - return 0; + /* block AS112 zones, unless asked not to */ + if(!cfg->unblock_lan_zones) { + for(zstr = as112_zones; *zstr; zstr++) { + if(!add_as112_default(zones, cfg, *zstr)) { + log_err("out of memory adding default zone"); + return 0; + } + } } return 1; } /** setup parent pointers, so that a lookup can be done for closest match */ static void init_parents(struct local_zones* zones) { struct local_zone* node, *prev = NULL, *p; int m; lock_rw_wrlock(&zones->lock); RBTREE_FOR(node, struct local_zone*, &zones->ztree) { lock_rw_wrlock(&node->lock); node->parent = NULL; if(!prev || prev->dclass != node->dclass) { prev = node; lock_rw_unlock(&node->lock); continue; } (void)dname_lab_cmp(prev->name, prev->namelabs, node->name, node->namelabs, &m); /* we know prev is smaller */ /* sort order like: . com. bla.com. zwb.com. net. */ /* find the previous, or parent-parent-parent */ for(p = prev; p; p = p->parent) /* looking for name with few labels, a parent */ if(p->namelabs <= m) { /* ==: since prev matched m, this is closest*/ /* <: prev matches more, but is not a parent, * this one is a (grand)parent */ node->parent = p; break; } prev = node; lock_rw_unlock(&node->lock); } lock_rw_unlock(&zones->lock); } /** enter implicit transparent zone for local-data: without local-zone: */ static int lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) { /* walk over all items that have no parent zone and find * the name that covers them all (could be the root) and * add that as a transparent zone */ struct config_strlist* p; int have_name = 0; int have_other_classes = 0; uint16_t dclass = 0; uint8_t* nm = 0; size_t nmlen = 0; int nmlabs = 0; int match = 0; /* number of labels match count */ init_parents(zones); /* to enable local_zones_lookup() */ for(p = cfg->local_data; p; p = p->next) { uint8_t* rr_name; uint16_t rr_class; size_t len; int labs; if(!get_rr_nameclass(p->str, &rr_name, &rr_class)) { log_err("Bad local-data RR %s", p->str); return 0; } labs = dname_count_size_labels(rr_name, &len); lock_rw_rdlock(&zones->lock); if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) { if(!have_name) { dclass = rr_class; nm = rr_name; nmlen = len; nmlabs = labs; match = labs; have_name = 1; } else { int m; if(rr_class != dclass) { /* process other classes later */ free(rr_name); have_other_classes = 1; lock_rw_unlock(&zones->lock); continue; } /* find smallest shared topdomain */ (void)dname_lab_cmp(nm, nmlabs, rr_name, labs, &m); free(rr_name); if(m < match) match = m; } } else free(rr_name); lock_rw_unlock(&zones->lock); } if(have_name) { uint8_t* n2; struct local_zone* z; /* allocate zone of smallest shared topdomain to contain em */ n2 = nm; dname_remove_labels(&n2, &nmlen, nmlabs - match); n2 = memdup(n2, nmlen); free(nm); if(!n2) { log_err("out of memory"); return 0; } log_nametypeclass(VERB_ALGO, "implicit transparent local-zone", n2, 0, dclass); if(!(z=lz_enter_zone_dname(zones, n2, nmlen, match, local_zone_transparent, dclass))) { return 0; } lock_rw_unlock(&z->lock); } if(have_other_classes) { /* restart to setup other class */ return lz_setup_implicit(zones, cfg); } return 1; } /** enter auth data */ static int lz_enter_data(struct local_zones* zones, struct config_file* cfg) { struct config_strlist* p; for(p = cfg->local_data; p; p = p->next) { if(!lz_enter_rr_str(zones, p->str)) return 0; } return 1; } /** free memory from config */ static void lz_freeup_cfg(struct config_file* cfg) { config_deldblstrlist(cfg->local_zones); cfg->local_zones = NULL; config_delstrlist(cfg->local_zones_nodefault); cfg->local_zones_nodefault = NULL; config_delstrlist(cfg->local_data); cfg->local_data = NULL; } int local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg) { /* create zones from zone statements. */ if(!lz_enter_zones(zones, cfg)) { return 0; } /* apply default zones+content (unless disabled, or overridden) */ if(!lz_enter_defaults(zones, cfg)) { return 0; } /* create implicit transparent zone from data. */ if(!lz_setup_implicit(zones, cfg)) { return 0; } /* setup parent ptrs for lookup during data entry */ init_parents(zones); /* insert local data */ if(!lz_enter_data(zones, cfg)) { return 0; } /* freeup memory from cfg struct. */ lz_freeup_cfg(cfg); return 1; } struct local_zone* local_zones_lookup(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass) { rbnode_t* res = NULL; struct local_zone *result; struct local_zone key; key.node.key = &key; key.dclass = dclass; key.name = name; key.namelen = len; key.namelabs = labs; if(rbtree_find_less_equal(&zones->ztree, &key, &res)) { /* exact */ return (struct local_zone*)res; } else { /* smaller element (or no element) */ int m; result = (struct local_zone*)res; if(!result || result->dclass != dclass) return NULL; /* count number of labels matched */ (void)dname_lab_cmp(result->name, result->namelabs, key.name, key.namelabs, &m); while(result) { /* go up until qname is subdomain of zone */ if(result->namelabs <= m) break; result = result->parent; } return result; } } struct local_zone* local_zones_find(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass) { struct local_zone key; key.node.key = &key; key.dclass = dclass; key.name = name; key.namelen = len; key.namelabs = labs; /* exact */ return (struct local_zone*)rbtree_search(&zones->ztree, &key); } /** print all RRsets in local zone */ static void local_zone_out(struct local_zone* z) { struct local_data* d; struct local_rrset* p; RBTREE_FOR(d, struct local_data*, &z->data) { for(p = d->rrsets; p; p = p->next) { log_nametypeclass(0, "rrset", d->name, ntohs(p->rrset->rk.type), ntohs(p->rrset->rk.rrset_class)); } } } void local_zones_print(struct local_zones* zones) { struct local_zone* z; lock_rw_rdlock(&zones->lock); log_info("number of auth zones %u", (unsigned)zones->ztree.count); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); switch(z->type) { case local_zone_deny: log_nametypeclass(0, "deny zone", z->name, 0, z->dclass); break; case local_zone_refuse: log_nametypeclass(0, "refuse zone", z->name, 0, z->dclass); break; case local_zone_redirect: log_nametypeclass(0, "redirect zone", z->name, 0, z->dclass); break; case local_zone_transparent: log_nametypeclass(0, "transparent zone", z->name, 0, z->dclass); break; case local_zone_typetransparent: log_nametypeclass(0, "typetransparent zone", z->name, 0, z->dclass); break; case local_zone_static: log_nametypeclass(0, "static zone", z->name, 0, z->dclass); break; case local_zone_inform: log_nametypeclass(0, "inform zone", z->name, 0, z->dclass); break; case local_zone_inform_deny: log_nametypeclass(0, "inform_deny zone", z->name, 0, z->dclass); break; default: log_nametypeclass(0, "badtyped zone", z->name, 0, z->dclass); break; } local_zone_out(z); lock_rw_unlock(&z->lock); } lock_rw_unlock(&zones->lock); } /** encode answer consisting of 1 rrset */ static int local_encode(struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, int rcode) { struct reply_info rep; uint16_t udpsize; /* make answer with time=0 for fixed TTL values */ memset(&rep, 0, sizeof(rep)); rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); rep.qdcount = 1; if(ansec) rep.an_numrrsets = 1; else rep.ns_numrrsets = 1; rep.rrset_count = 1; rep.rrsets = &rrset; udpsize = edns->udp_size; edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; edns->ext_rcode = 0; edns->bits &= EDNS_DO; if(!reply_info_answer_encode(qinfo, &rep, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), edns); return 1; } /** answer local data match */ static int local_data_answer(struct local_zone* z, struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, struct regional* temp, int labs, struct local_data** ldp) { struct local_data key; struct local_data* ld; struct local_rrset* lr; key.node.key = &key; key.name = qinfo->qname; key.namelen = qinfo->qname_len; key.namelabs = labs; if(z->type == local_zone_redirect) { key.name = z->name; key.namelen = z->namelen; key.namelabs = z->namelabs; } ld = (struct local_data*)rbtree_search(&z->data, &key.node); *ldp = ld; if(!ld) { return 0; } lr = local_data_find_type(ld, qinfo->qtype); if(!lr) return 0; if(z->type == local_zone_redirect) { /* convert rrset name to query name; like a wildcard */ struct ub_packed_rrset_key r = *lr->rrset; r.rk.dname = qinfo->qname; r.rk.dname_len = qinfo->qname_len; return local_encode(qinfo, edns, buf, temp, &r, 1, LDNS_RCODE_NOERROR); } return local_encode(qinfo, edns, buf, temp, lr->rrset, 1, LDNS_RCODE_NOERROR); } /** * answer in case where no exact match is found * @param z: zone for query * @param qinfo: query * @param edns: edns from query * @param buf: buffer for answer. * @param temp: temp region for encoding * @param ld: local data, if NULL, no such name exists in localdata. * @return 1 if a reply is to be sent, 0 if not. */ static int lz_zone_answer(struct local_zone* z, struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, struct regional* temp, struct local_data* ld) { if(z->type == local_zone_deny || z->type == local_zone_inform_deny) { /** no reply at all, signal caller by clearing buffer. */ sldns_buffer_clear(buf); sldns_buffer_flip(buf); return 1; } else if(z->type == local_zone_refuse) { error_encode(buf, (LDNS_RCODE_REFUSED|BIT_AA), qinfo, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), edns); return 1; } else if(z->type == local_zone_static || z->type == local_zone_redirect) { /* for static, reply nodata or nxdomain * for redirect, reply nodata */ /* no additional section processing, * cname, dname or wildcard processing, * or using closest match for NSEC. * or using closest match for returning delegation downwards */ int rcode = ld?LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; if(z->soa) return local_encode(qinfo, edns, buf, temp, z->soa, 0, rcode); error_encode(buf, (rcode|BIT_AA), qinfo, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), edns); return 1; } else if(z->type == local_zone_typetransparent) { /* no NODATA or NXDOMAINS for this zone type */ return 0; } /* else z->type == local_zone_transparent */ /* if the zone is transparent and the name exists, but the type * does not, then we should make this noerror/nodata */ if(ld && ld->rrsets) { int rcode = LDNS_RCODE_NOERROR; if(z->soa) return local_encode(qinfo, edns, buf, temp, z->soa, 0, rcode); error_encode(buf, (rcode|BIT_AA), qinfo, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), edns); return 1; } /* stop here, and resolve further on */ return 0; } /** print log information for an inform zone query */ static void lz_inform_print(struct local_zone* z, struct query_info* qinfo, struct comm_reply* repinfo) { char ip[128], txt[512]; char zname[LDNS_MAX_DOMAINLEN+1]; uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); dname_str(z->name, zname); addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip, (unsigned)port); log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); } int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, struct regional* temp, struct comm_reply* repinfo) { /* see if query is covered by a zone, * if so: - try to match (exact) local data * - look at zone type for negative response. */ int labs = dname_count_labels(qinfo->qname); struct local_data* ld; struct local_zone* z; int r; lock_rw_rdlock(&zones->lock); z = local_zones_lookup(zones, qinfo->qname, qinfo->qname_len, labs, qinfo->qclass); if(!z) { lock_rw_unlock(&zones->lock); return 0; } lock_rw_rdlock(&z->lock); lock_rw_unlock(&zones->lock); if((z->type == local_zone_inform || z->type == local_zone_inform_deny) && repinfo) lz_inform_print(z, qinfo, repinfo); if(local_data_answer(z, qinfo, edns, buf, temp, labs, &ld)) { lock_rw_unlock(&z->lock); return 1; } r = lz_zone_answer(z, qinfo, edns, buf, temp, ld); lock_rw_unlock(&z->lock); return r; } const char* local_zone_type2str(enum localzone_type t) { switch(t) { case local_zone_deny: return "deny"; case local_zone_refuse: return "refuse"; case local_zone_redirect: return "redirect"; case local_zone_transparent: return "transparent"; case local_zone_typetransparent: return "typetransparent"; case local_zone_static: return "static"; case local_zone_nodefault: return "nodefault"; case local_zone_inform: return "inform"; case local_zone_inform_deny: return "inform_deny"; } return "badtyped"; } int local_zone_str2type(const char* type, enum localzone_type* t) { if(strcmp(type, "deny") == 0) *t = local_zone_deny; else if(strcmp(type, "refuse") == 0) *t = local_zone_refuse; else if(strcmp(type, "static") == 0) *t = local_zone_static; else if(strcmp(type, "transparent") == 0) *t = local_zone_transparent; else if(strcmp(type, "typetransparent") == 0) *t = local_zone_typetransparent; else if(strcmp(type, "redirect") == 0) *t = local_zone_redirect; else if(strcmp(type, "inform") == 0) *t = local_zone_inform; else if(strcmp(type, "inform_deny") == 0) *t = local_zone_inform_deny; else return 0; return 1; } /** iterate over the kiddies of the given name and set their parent ptr */ static void set_kiddo_parents(struct local_zone* z, struct local_zone* match, struct local_zone* newp) { /* both zones and z are locked already */ /* in the sorted rbtree, the kiddies of z are located after z */ /* z must be present in the tree */ struct local_zone* p = z; p = (struct local_zone*)rbtree_next(&p->node); while(p!=(struct local_zone*)RBTREE_NULL && p->dclass == z->dclass && dname_strict_subdomain(p->name, p->namelabs, z->name, z->namelabs)) { /* update parent ptr */ /* only when matches with existing parent pointer, so that * deeper child structures are not touched, i.e. * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y * gets to update a.x, b.x and c.x */ lock_rw_wrlock(&p->lock); if(p->parent == match) p->parent = newp; lock_rw_unlock(&p->lock); p = (struct local_zone*)rbtree_next(&p->node); } } struct local_zone* local_zones_add_zone(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass, enum localzone_type tp) { /* create */ struct local_zone* z = local_zone_create(name, len, labs, tp, dclass); if(!z) return NULL; lock_rw_wrlock(&z->lock); /* find the closest parent */ z->parent = local_zones_find(zones, name, len, labs, dclass); /* insert into the tree */ if(!rbtree_insert(&zones->ztree, &z->node)) { /* duplicate entry! */ lock_rw_unlock(&z->lock); local_zone_delete(z); log_err("internal: duplicate entry in local_zones_add_zone"); return NULL; } /* set parent pointers right */ set_kiddo_parents(z, z->parent, z); lock_rw_unlock(&z->lock); return z; } void local_zones_del_zone(struct local_zones* zones, struct local_zone* z) { /* fix up parents in tree */ lock_rw_wrlock(&z->lock); set_kiddo_parents(z, z, z->parent); /* remove from tree */ (void)rbtree_delete(&zones->ztree, z); /* delete the zone */ lock_rw_unlock(&z->lock); local_zone_delete(z); } int local_zones_add_RR(struct local_zones* zones, const char* rr) { uint8_t* rr_name; uint16_t rr_class; size_t len; int labs; struct local_zone* z; int r; if(!get_rr_nameclass(rr, &rr_name, &rr_class)) { return 0; } labs = dname_count_size_labels(rr_name, &len); /* could first try readlock then get writelock if zone does not exist, * but we do not add enough RRs (from multiple threads) to optimize */ lock_rw_wrlock(&zones->lock); z = local_zones_lookup(zones, rr_name, len, labs, rr_class); if(!z) { z = local_zones_add_zone(zones, rr_name, len, labs, rr_class, local_zone_transparent); if(!z) { lock_rw_unlock(&zones->lock); return 0; } } else { free(rr_name); } lock_rw_wrlock(&z->lock); lock_rw_unlock(&zones->lock); r = lz_enter_rr_into_zone(z, rr); lock_rw_unlock(&z->lock); return r; } /** returns true if the node is terminal so no deeper domain names exist */ static int is_terminal(struct local_data* d) { /* for empty nonterminals, the deeper domain names are sorted * right after them, so simply check the next name in the tree */ struct local_data* n = (struct local_data*)rbtree_next(&d->node); if(n == (struct local_data*)RBTREE_NULL) return 1; /* last in tree, no deeper node */ if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs)) return 0; /* there is a deeper node */ return 1; } /** delete empty terminals from tree when final data is deleted */ static void del_empty_term(struct local_zone* z, struct local_data* d, uint8_t* name, size_t len, int labs) { while(d && d->rrsets == NULL && is_terminal(d)) { /* is this empty nonterminal? delete */ /* note, no memory recycling in zone region */ (void)rbtree_delete(&z->data, d); /* go up and to the next label */ if(dname_is_root(name)) return; dname_remove_label(&name, &len); labs--; d = lz_find_node(z, name, len, labs); } } void local_zones_del_data(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass) { /* find zone */ struct local_zone* z; struct local_data* d; lock_rw_rdlock(&zones->lock); z = local_zones_lookup(zones, name, len, labs, dclass); if(!z) { /* no such zone, we're done */ lock_rw_unlock(&zones->lock); return; } lock_rw_wrlock(&z->lock); lock_rw_unlock(&zones->lock); /* find the domain */ d = lz_find_node(z, name, len, labs); if(d) { /* no memory recycling for zone deletions ... */ d->rrsets = NULL; /* did we delete the soa record ? */ if(query_dname_compare(d->name, z->name) == 0) z->soa = NULL; /* cleanup the empty nonterminals for this name */ del_empty_term(z, d, name, len, labs); } lock_rw_unlock(&z->lock); } Index: vendor/unbound/dist/util/as112.c =================================================================== --- vendor/unbound/dist/util/as112.c (nonexistent) +++ vendor/unbound/dist/util/as112.c (revision 295530) @@ -0,0 +1,143 @@ +/* + * util/as112.c - list of local zones. + * + * Copyright (c) 2007, 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 provides a list of lan zones. + */ + +#include "util/as112.h" + +static const char* as112_zone_array[] = { + "10.in-addr.arpa.", + "16.172.in-addr.arpa.", + "17.172.in-addr.arpa.", + "18.172.in-addr.arpa.", + "19.172.in-addr.arpa.", + "20.172.in-addr.arpa.", + "21.172.in-addr.arpa.", + "22.172.in-addr.arpa.", + "23.172.in-addr.arpa.", + "24.172.in-addr.arpa.", + "25.172.in-addr.arpa.", + "26.172.in-addr.arpa.", + "27.172.in-addr.arpa.", + "28.172.in-addr.arpa.", + "29.172.in-addr.arpa.", + "30.172.in-addr.arpa.", + "31.172.in-addr.arpa.", + "168.192.in-addr.arpa.", + "0.in-addr.arpa.", + "64.100.in-addr.arpa.", + "65.100.in-addr.arpa.", + "66.100.in-addr.arpa.", + "67.100.in-addr.arpa.", + "68.100.in-addr.arpa.", + "69.100.in-addr.arpa.", + "70.100.in-addr.arpa.", + "71.100.in-addr.arpa.", + "72.100.in-addr.arpa.", + "73.100.in-addr.arpa.", + "74.100.in-addr.arpa.", + "75.100.in-addr.arpa.", + "76.100.in-addr.arpa.", + "77.100.in-addr.arpa.", + "78.100.in-addr.arpa.", + "79.100.in-addr.arpa.", + "80.100.in-addr.arpa.", + "81.100.in-addr.arpa.", + "82.100.in-addr.arpa.", + "83.100.in-addr.arpa.", + "84.100.in-addr.arpa.", + "85.100.in-addr.arpa.", + "86.100.in-addr.arpa.", + "87.100.in-addr.arpa.", + "88.100.in-addr.arpa.", + "89.100.in-addr.arpa.", + "90.100.in-addr.arpa.", + "91.100.in-addr.arpa.", + "92.100.in-addr.arpa.", + "93.100.in-addr.arpa.", + "94.100.in-addr.arpa.", + "95.100.in-addr.arpa.", + "96.100.in-addr.arpa.", + "97.100.in-addr.arpa.", + "98.100.in-addr.arpa.", + "99.100.in-addr.arpa.", + "100.100.in-addr.arpa.", + "101.100.in-addr.arpa.", + "102.100.in-addr.arpa.", + "103.100.in-addr.arpa.", + "104.100.in-addr.arpa.", + "105.100.in-addr.arpa.", + "106.100.in-addr.arpa.", + "107.100.in-addr.arpa.", + "108.100.in-addr.arpa.", + "109.100.in-addr.arpa.", + "110.100.in-addr.arpa.", + "111.100.in-addr.arpa.", + "112.100.in-addr.arpa.", + "113.100.in-addr.arpa.", + "114.100.in-addr.arpa.", + "115.100.in-addr.arpa.", + "116.100.in-addr.arpa.", + "117.100.in-addr.arpa.", + "118.100.in-addr.arpa.", + "119.100.in-addr.arpa.", + "120.100.in-addr.arpa.", + "121.100.in-addr.arpa.", + "122.100.in-addr.arpa.", + "123.100.in-addr.arpa.", + "124.100.in-addr.arpa.", + "125.100.in-addr.arpa.", + "126.100.in-addr.arpa.", + "127.100.in-addr.arpa.", + "254.169.in-addr.arpa.", + "2.0.192.in-addr.arpa.", + "100.51.198.in-addr.arpa.", + "113.0.203.in-addr.arpa.", + "255.255.255.255.in-addr.arpa.", + "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.", + "d.f.ip6.arpa.", + "8.e.f.ip6.arpa.", + "9.e.f.ip6.arpa.", + "a.e.f.ip6.arpa.", + "b.e.f.ip6.arpa.", + "8.b.d.0.1.0.0.2.ip6.arpa.", + 0 +}; + +const char** as112_zones = as112_zone_array; Index: vendor/unbound/dist/util/as112.h =================================================================== --- vendor/unbound/dist/util/as112.h (nonexistent) +++ vendor/unbound/dist/util/as112.h (revision 295530) @@ -0,0 +1,57 @@ +/* + * util/as112.c - list of local zones. + * + * Copyright (c) 2007, 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 provides a list of lan zones + */ + +#ifndef UTIL_AS112_H +#define UTIL_AS112_H + +/** + * Array of text-format domain names of the AS112 zones. + * The array ends with NULL. "AS112" is a service on the internet that + * that this array is named after. The names in this list (or some of them) + * are null-routed by this service to avoid load on central servers caused by + * mistaken lookups for local content on the global internet. + * + * This is the list of names that unbound should not normally be sending + * on towards the internet, because they are local-use. + */ +extern const char** as112_zones; + +#endif Index: vendor/unbound/dist/util/config_file.c =================================================================== --- vendor/unbound/dist/util/config_file.c (revision 295529) +++ vendor/unbound/dist/util/config_file.c (revision 295530) @@ -1,1678 +1,1681 @@ /* * util/config_file.c - reads and stores the config file for unbound. * * Copyright (c) 2007, 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 functions for the config file. */ #include "config.h" #include #include #ifdef HAVE_TIME_H #include #endif #include "util/log.h" #include "util/configyyrename.h" #include "util/config_file.h" #include "util/configparser.h" #include "util/net_help.h" #include "util/data/msgparse.h" #include "util/module.h" #include "util/regional.h" #include "util/fptr_wlist.h" #include "util/data/dname.h" #include "util/rtt.h" #include "services/cache/infra.h" #include "sldns/wire2str.h" #include "sldns/parseutil.h" #ifdef HAVE_GLOB_H # include #endif #ifdef HAVE_PWD_H #include #endif /** from cfg username, after daemonise setup performed */ uid_t cfg_uid = (uid_t)-1; /** from cfg username, after daemonise setup performed */ gid_t cfg_gid = (gid_t)-1; /** for debug allow small timeout values for fast rollovers */ int autr_permit_small_holddown = 0; /** global config during parsing */ struct config_parser_state* cfg_parser = 0; /** init ports possible for use */ static void init_outgoing_availports(int* array, int num); struct config_file* config_create(void) { struct config_file* cfg; cfg = (struct config_file*)calloc(1, sizeof(struct config_file)); if(!cfg) return NULL; /* the defaults if no config is present */ cfg->verbosity = 1; cfg->stat_interval = 0; cfg->stat_cumulative = 0; cfg->stat_extended = 0; cfg->num_threads = 1; cfg->port = UNBOUND_DNS_PORT; cfg->do_ip4 = 1; cfg->do_ip6 = 1; cfg->do_udp = 1; cfg->do_tcp = 1; cfg->tcp_upstream = 0; cfg->ssl_service_key = NULL; cfg->ssl_service_pem = NULL; cfg->ssl_port = 853; cfg->ssl_upstream = 0; cfg->use_syslog = 1; cfg->log_time_ascii = 0; cfg->log_queries = 0; #ifndef USE_WINSOCK # ifdef USE_MINI_EVENT /* select max 1024 sockets */ cfg->outgoing_num_ports = 960; cfg->num_queries_per_thread = 512; # else /* libevent can use many sockets */ cfg->outgoing_num_ports = 4096; cfg->num_queries_per_thread = 1024; # endif cfg->outgoing_num_tcp = 10; cfg->incoming_num_tcp = 10; #else cfg->outgoing_num_ports = 48; /* windows is limited in num fds */ cfg->num_queries_per_thread = 24; cfg->outgoing_num_tcp = 2; /* leaves 64-52=12 for: 4if,1stop,thread4 */ cfg->incoming_num_tcp = 2; #endif cfg->edns_buffer_size = 4096; /* 4k from rfc recommendation */ cfg->msg_buffer_size = 65552; /* 64 k + a small margin */ cfg->msg_cache_size = 4 * 1024 * 1024; cfg->msg_cache_slabs = 4; cfg->jostle_time = 200; cfg->rrset_cache_size = 4 * 1024 * 1024; cfg->rrset_cache_slabs = 4; cfg->host_ttl = 900; cfg->bogus_ttl = 60; cfg->min_ttl = 0; cfg->max_ttl = 3600 * 24; cfg->max_negative_ttl = 3600; cfg->prefetch = 0; cfg->prefetch_key = 0; cfg->infra_cache_slabs = 4; cfg->infra_cache_numhosts = 10000; cfg->infra_cache_min_rtt = 50; cfg->delay_close = 0; if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int)))) goto error_exit; init_outgoing_availports(cfg->outgoing_avail_ports, 65536); if(!(cfg->username = strdup(UB_USERNAME))) goto error_exit; #ifdef HAVE_CHROOT if(!(cfg->chrootdir = strdup(CHROOT_DIR))) goto error_exit; #endif if(!(cfg->directory = strdup(RUN_DIR))) goto error_exit; if(!(cfg->logfile = strdup(""))) goto error_exit; if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit; if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit; cfg->donotqueryaddrs = NULL; cfg->donotquery_localhost = 1; cfg->root_hints = NULL; cfg->do_daemonize = 1; cfg->if_automatic = 0; cfg->so_rcvbuf = 0; cfg->so_sndbuf = 0; cfg->so_reuseport = 0; cfg->ip_transparent = 0; cfg->num_ifs = 0; cfg->ifs = NULL; cfg->num_out_ifs = 0; cfg->out_ifs = NULL; cfg->stubs = NULL; cfg->forwards = NULL; cfg->acls = NULL; cfg->harden_short_bufsize = 0; cfg->harden_large_queries = 0; cfg->harden_glue = 1; cfg->harden_dnssec_stripped = 1; cfg->harden_below_nxdomain = 0; cfg->harden_referral_path = 0; cfg->harden_algo_downgrade = 0; cfg->use_caps_bits_for_id = 0; cfg->caps_whitelist = NULL; cfg->private_address = NULL; cfg->private_domain = NULL; cfg->unwanted_threshold = 0; cfg->hide_identity = 0; cfg->hide_version = 0; cfg->identity = NULL; cfg->version = NULL; cfg->auto_trust_anchor_file_list = NULL; cfg->trust_anchor_file_list = NULL; cfg->trust_anchor_list = NULL; cfg->trusted_keys_file_list = NULL; cfg->dlv_anchor_file = NULL; cfg->dlv_anchor_list = NULL; cfg->domain_insecure = NULL; cfg->val_date_override = 0; cfg->val_sig_skew_min = 3600; /* at least daylight savings trouble */ cfg->val_sig_skew_max = 86400; /* at most timezone settings trouble */ cfg->val_clean_additional = 1; cfg->val_log_level = 0; cfg->val_log_squelch = 0; cfg->val_permissive_mode = 0; cfg->ignore_cd = 0; cfg->add_holddown = 30*24*3600; cfg->del_holddown = 30*24*3600; cfg->keep_missing = 366*24*3600; /* one year plus a little leeway */ cfg->permit_small_holddown = 0; cfg->key_cache_size = 4 * 1024 * 1024; cfg->key_cache_slabs = 4; cfg->neg_cache_size = 1 * 1024 * 1024; cfg->local_zones = NULL; cfg->local_zones_nodefault = NULL; cfg->local_data = NULL; cfg->unblock_lan_zones = 0; + cfg->insecure_lan_zones = 0; cfg->python_script = NULL; cfg->remote_control_enable = 0; cfg->control_ifs = NULL; cfg->control_port = UNBOUND_CONTROL_PORT; cfg->remote_control_use_cert = 1; cfg->minimal_responses = 0; cfg->rrset_roundrobin = 0; cfg->max_udp_size = 4096; if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key"))) goto error_exit; if(!(cfg->server_cert_file = strdup(RUN_DIR"/unbound_server.pem"))) goto error_exit; if(!(cfg->control_key_file = strdup(RUN_DIR"/unbound_control.key"))) goto error_exit; if(!(cfg->control_cert_file = strdup(RUN_DIR"/unbound_control.pem"))) goto error_exit; if(!(cfg->module_conf = strdup("validator iterator"))) goto error_exit; if(!(cfg->val_nsec3_key_iterations = strdup("1024 150 2048 500 4096 2500"))) goto error_exit; #if defined(DNSTAP_SOCKET_PATH) if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH))) goto error_exit; #endif cfg->ratelimit = 0; cfg->ratelimit_slabs = 4; cfg->ratelimit_size = 4*1024*1024; cfg->ratelimit_for_domain = NULL; cfg->ratelimit_below_domain = NULL; cfg->ratelimit_factor = 10; cfg->qname_minimisation = 0; return cfg; error_exit: config_delete(cfg); return NULL; } struct config_file* config_create_forlib(void) { struct config_file* cfg = config_create(); if(!cfg) return NULL; /* modifications for library use, less verbose, less memory */ free(cfg->chrootdir); cfg->chrootdir = NULL; cfg->verbosity = 0; cfg->outgoing_num_ports = 16; /* in library use, this is 'reasonable' and probably within the ulimit(maxfds) of the user */ cfg->outgoing_num_tcp = 2; cfg->msg_cache_size = 1024*1024; cfg->msg_cache_slabs = 1; cfg->rrset_cache_size = 1024*1024; cfg->rrset_cache_slabs = 1; cfg->infra_cache_slabs = 1; cfg->use_syslog = 0; cfg->key_cache_size = 1024*1024; cfg->key_cache_slabs = 1; cfg->neg_cache_size = 100 * 1024; cfg->donotquery_localhost = 0; /* allow, so that you can ask a forward nameserver running on localhost */ cfg->val_log_level = 2; /* to fill why_bogus with */ cfg->val_log_squelch = 1; return cfg; } /** check that the value passed is >= 0 */ #define IS_NUMBER_OR_ZERO \ if(atoi(val) == 0 && strcmp(val, "0") != 0) return 0 /** check that the value passed is > 0 */ #define IS_NONZERO_NUMBER \ if(atoi(val) == 0) return 0 /** check that the value passed is not 0 and a power of 2 */ #define IS_POW2_NUMBER \ if(atoi(val) == 0 || !is_pow2((size_t)atoi(val))) return 0 /** check that the value passed is yes or no */ #define IS_YES_OR_NO \ if(strcmp(val, "yes") != 0 && strcmp(val, "no") != 0) return 0 /** put integer_or_zero into variable */ #define S_NUMBER_OR_ZERO(str, var) if(strcmp(opt, str) == 0) \ { IS_NUMBER_OR_ZERO; cfg->var = atoi(val); } /** put integer_nonzero into variable */ #define S_NUMBER_NONZERO(str, var) if(strcmp(opt, str) == 0) \ { IS_NONZERO_NUMBER; cfg->var = atoi(val); } /** put integer_or_zero into unsigned */ #define S_UNSIGNED_OR_ZERO(str, var) if(strcmp(opt, str) == 0) \ { IS_NUMBER_OR_ZERO; cfg->var = (unsigned)atoi(val); } /** put integer_or_zero into size_t */ #define S_SIZET_OR_ZERO(str, var) if(strcmp(opt, str) == 0) \ { IS_NUMBER_OR_ZERO; cfg->var = (size_t)atoi(val); } /** put integer_nonzero into size_t */ #define S_SIZET_NONZERO(str, var) if(strcmp(opt, str) == 0) \ { IS_NONZERO_NUMBER; cfg->var = (size_t)atoi(val); } /** put yesno into variable */ #define S_YNO(str, var) if(strcmp(opt, str) == 0) \ { IS_YES_OR_NO; cfg->var = (strcmp(val, "yes") == 0); } /** put memsize into variable */ #define S_MEMSIZE(str, var) if(strcmp(opt, str)==0) \ { return cfg_parse_memsize(val, &cfg->var); } /** put pow2 number into variable */ #define S_POW2(str, var) if(strcmp(opt, str)==0) \ { IS_POW2_NUMBER; cfg->var = (size_t)atoi(val); } /** put string into variable */ #define S_STR(str, var) if(strcmp(opt, str)==0) \ { free(cfg->var); return (cfg->var = strdup(val)) != NULL; } /** put string into strlist */ #define S_STRLIST(str, var) if(strcmp(opt, str)==0) \ { return cfg_strlist_insert(&cfg->var, strdup(val)); } int config_set_option(struct config_file* cfg, const char* opt, const char* val) { S_NUMBER_OR_ZERO("verbosity:", verbosity) else if(strcmp(opt, "statistics-interval:") == 0) { if(strcmp(val, "0") == 0 || strcmp(val, "") == 0) cfg->stat_interval = 0; else if(atoi(val) == 0) return 0; else cfg->stat_interval = atoi(val); } else if(strcmp(opt, "num_threads:") == 0) { /* not supported, library must have 1 thread in bgworker */ return 0; } else if(strcmp(opt, "outgoing-port-permit:") == 0) { return cfg_mark_ports(val, 1, cfg->outgoing_avail_ports, 65536); } else if(strcmp(opt, "outgoing-port-avoid:") == 0) { return cfg_mark_ports(val, 0, cfg->outgoing_avail_ports, 65536); } else if(strcmp(opt, "local-zone:") == 0) { return cfg_parse_local_zone(cfg, val); } else if(strcmp(opt, "val-override-date:") == 0) { if(strcmp(val, "") == 0 || strcmp(val, "0") == 0) { cfg->val_date_override = 0; } else if(strlen(val) == 14) { cfg->val_date_override = cfg_convert_timeval(val); return cfg->val_date_override != 0; } else { if(atoi(val) == 0) return 0; cfg->val_date_override = (uint32_t)atoi(val); } } else if(strcmp(opt, "local-data-ptr:") == 0) { char* ptr = cfg_ptr_reverse((char*)opt); return cfg_strlist_insert(&cfg->local_data, ptr); } else if(strcmp(opt, "logfile:") == 0) { cfg->use_syslog = 0; free(cfg->logfile); return (cfg->logfile = strdup(val)) != NULL; } else if(strcmp(opt, "log-time-ascii:") == 0) { IS_YES_OR_NO; cfg->log_time_ascii = (strcmp(val, "yes") == 0); log_set_time_asc(cfg->log_time_ascii); } else S_SIZET_NONZERO("max-udp-size:", max_udp_size) else S_YNO("use-syslog:", use_syslog) else S_YNO("extended-statistics:", stat_extended) else S_YNO("statistics-cumulative:", stat_cumulative) else S_YNO("do-ip4:", do_ip4) else S_YNO("do-ip6:", do_ip6) else S_YNO("do-udp:", do_udp) else S_YNO("do-tcp:", do_tcp) else S_YNO("tcp-upstream:", tcp_upstream) else S_YNO("ssl-upstream:", ssl_upstream) else S_STR("ssl-service-key:", ssl_service_key) else S_STR("ssl-service-pem:", ssl_service_pem) else S_NUMBER_NONZERO("ssl-port:", ssl_port) else S_YNO("interface-automatic:", if_automatic) else S_YNO("do-daemonize:", do_daemonize) else S_NUMBER_NONZERO("port:", port) else S_NUMBER_NONZERO("outgoing-range:", outgoing_num_ports) else S_SIZET_OR_ZERO("outgoing-num-tcp:", outgoing_num_tcp) else S_SIZET_OR_ZERO("incoming-num-tcp:", incoming_num_tcp) else S_SIZET_NONZERO("edns-buffer-size:", edns_buffer_size) else S_SIZET_NONZERO("msg-buffer-size:", msg_buffer_size) else S_MEMSIZE("msg-cache-size:", msg_cache_size) else S_POW2("msg-cache-slabs:", msg_cache_slabs) else S_SIZET_NONZERO("num-queries-per-thread:",num_queries_per_thread) else S_SIZET_OR_ZERO("jostle-timeout:", jostle_time) else S_MEMSIZE("so-rcvbuf:", so_rcvbuf) else S_MEMSIZE("so-sndbuf:", so_sndbuf) else S_YNO("so-reuseport:", so_reuseport) else S_YNO("ip-transparent:", ip_transparent) else S_MEMSIZE("rrset-cache-size:", rrset_cache_size) else S_POW2("rrset-cache-slabs:", rrset_cache_slabs) else S_YNO("prefetch:", prefetch) else S_YNO("prefetch-key:", prefetch_key) else if(strcmp(opt, "cache-max-ttl:") == 0) { IS_NUMBER_OR_ZERO; cfg->max_ttl = atoi(val); MAX_TTL=(time_t)cfg->max_ttl;} else if(strcmp(opt, "cache-max-negative-ttl:") == 0) { IS_NUMBER_OR_ZERO; cfg->max_negative_ttl = atoi(val); MAX_NEG_TTL=(time_t)cfg->max_negative_ttl;} else if(strcmp(opt, "cache-min-ttl:") == 0) { IS_NUMBER_OR_ZERO; cfg->min_ttl = atoi(val); MIN_TTL=(time_t)cfg->min_ttl;} else if(strcmp(opt, "infra-cache-min-rtt:") == 0) { IS_NUMBER_OR_ZERO; cfg->infra_cache_min_rtt = atoi(val); RTT_MIN_TIMEOUT=cfg->infra_cache_min_rtt; } else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl) else S_POW2("infra-cache-slabs:", infra_cache_slabs) else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts) else S_NUMBER_OR_ZERO("delay-close:", delay_close) else S_STR("chroot:", chrootdir) else S_STR("username:", username) else S_STR("directory:", directory) else S_STR("pidfile:", pidfile) else S_YNO("hide-identity:", hide_identity) else S_YNO("hide-version:", hide_version) else S_STR("identity:", identity) else S_STR("version:", version) else S_STRLIST("root-hints:", root_hints) else S_STR("target-fetch-policy:", target_fetch_policy) else S_YNO("harden-glue:", harden_glue) else S_YNO("harden-short-bufsize:", harden_short_bufsize) else S_YNO("harden-large-queries:", harden_large_queries) else S_YNO("harden-dnssec-stripped:", harden_dnssec_stripped) else S_YNO("harden-below-nxdomain:", harden_below_nxdomain) else S_YNO("harden-referral-path:", harden_referral_path) else S_YNO("harden-algo-downgrade:", harden_algo_downgrade) else S_YNO("use-caps-for-id", use_caps_bits_for_id) else S_STRLIST("caps-whitelist:", caps_whitelist) else S_SIZET_OR_ZERO("unwanted-reply-threshold:", unwanted_threshold) else S_STRLIST("private-address:", private_address) else S_STRLIST("private-domain:", private_domain) else S_YNO("do-not-query-localhost:", donotquery_localhost) else S_STRLIST("do-not-query-address:", donotqueryaddrs) else S_STRLIST("auto-trust-anchor-file:", auto_trust_anchor_file_list) else S_STRLIST("trust-anchor-file:", trust_anchor_file_list) else S_STRLIST("trust-anchor:", trust_anchor_list) else S_STRLIST("trusted-keys-file:", trusted_keys_file_list) else S_STR("dlv-anchor-file:", dlv_anchor_file) else S_STRLIST("dlv-anchor:", dlv_anchor_list) else S_STRLIST("domain-insecure:", domain_insecure) else S_NUMBER_OR_ZERO("val-bogus-ttl:", bogus_ttl) else S_YNO("val-clean-additional:", val_clean_additional) else S_NUMBER_OR_ZERO("val-log-level:", val_log_level) else S_YNO("val-log-squelch:", val_log_squelch) else S_YNO("log-queries:", log_queries) else S_YNO("val-permissive-mode:", val_permissive_mode) else S_YNO("ignore-cd-flag:", ignore_cd) else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations) else S_UNSIGNED_OR_ZERO("add-holddown:", add_holddown) else S_UNSIGNED_OR_ZERO("del-holddown:", del_holddown) else S_UNSIGNED_OR_ZERO("keep-missing:", keep_missing) else if(strcmp(opt, "permit-small-holddown:") == 0) { IS_YES_OR_NO; cfg->permit_small_holddown = (strcmp(val, "yes") == 0); autr_permit_small_holddown = cfg->permit_small_holddown; } else S_MEMSIZE("key-cache-size:", key_cache_size) else S_POW2("key-cache-slabs:", key_cache_slabs) else S_MEMSIZE("neg-cache-size:", neg_cache_size) else S_YNO("minimal-responses:", minimal_responses) else S_YNO("rrset-roundrobin:", rrset_roundrobin) else S_STRLIST("local-data:", local_data) else S_YNO("unblock-lan-zones:", unblock_lan_zones) + else S_YNO("insecure-lan-zones:", insecure_lan_zones) else S_YNO("control-enable:", remote_control_enable) else S_STRLIST("control-interface:", control_ifs) else S_NUMBER_NONZERO("control-port:", control_port) else S_STR("server-key-file:", server_key_file) else S_STR("server-cert-file:", server_cert_file) else S_STR("control-key-file:", control_key_file) else S_STR("control-cert-file:", control_cert_file) else S_STR("module-config:", module_conf) else S_STR("python-script:", python_script) else if(strcmp(opt, "ratelimit:") == 0) { IS_NUMBER_OR_ZERO; cfg->ratelimit = atoi(val); infra_dp_ratelimit=cfg->ratelimit; } else S_MEMSIZE("ratelimit-size:", ratelimit_size) else S_POW2("ratelimit-slabs:", ratelimit_slabs) else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor) else S_YNO("qname-minimisation:", qname_minimisation) /* val_sig_skew_min and max are copied into val_env during init, * so this does not update val_env with set_option */ else if(strcmp(opt, "val-sig-skew-min:") == 0) { IS_NUMBER_OR_ZERO; cfg->val_sig_skew_min = (int32_t)atoi(val); } else if(strcmp(opt, "val-sig-skew-max:") == 0) { IS_NUMBER_OR_ZERO; cfg->val_sig_skew_max = (int32_t)atoi(val); } else if (strcmp(opt, "outgoing-interface:") == 0) { char* d = strdup(val); char** oi = (char**)reallocarray(NULL, (size_t)cfg->num_out_ifs+1, sizeof(char*)); if(!d || !oi) { free(d); free(oi); return -1; } if(cfg->out_ifs && cfg->num_out_ifs) { memmove(oi, cfg->out_ifs, cfg->num_out_ifs*sizeof(char*)); free(cfg->out_ifs); } oi[cfg->num_out_ifs++] = d; cfg->out_ifs = oi; } else { /* unknown or unsupported (from the set_option interface): * interface, outgoing-interface, access-control, * stub-zone, name, stub-addr, stub-host, stub-prime * forward-first, stub-first, * forward-zone, name, forward-addr, forward-host, * ratelimit-for-domain, ratelimit-below-domain */ return 0; } return 1; } void config_print_func(char* line, void* arg) { FILE* f = (FILE*)arg; (void)fprintf(f, "%s\n", line); } /** collate func arg */ struct config_collate_arg { /** list of result items */ struct config_strlist_head list; /** if a malloc error occurred, 0 is OK */ int status; }; void config_collate_func(char* line, void* arg) { struct config_collate_arg* m = (struct config_collate_arg*)arg; if(m->status) return; if(!cfg_strlist_append(&m->list, strdup(line))) m->status = 1; } int config_get_option_list(struct config_file* cfg, const char* opt, struct config_strlist** list) { struct config_collate_arg m; memset(&m, 0, sizeof(m)); *list = NULL; if(!config_get_option(cfg, opt, config_collate_func, &m)) return 1; if(m.status) { config_delstrlist(m.list.first); return 2; } *list = m.list.first; return 0; } int config_get_option_collate(struct config_file* cfg, const char* opt, char** str) { struct config_strlist* list = NULL; int r; *str = NULL; if((r = config_get_option_list(cfg, opt, &list)) != 0) return r; *str = config_collate_cat(list); config_delstrlist(list); if(!*str) return 2; return 0; } char* config_collate_cat(struct config_strlist* list) { size_t total = 0, left; struct config_strlist* s; char *r, *w; if(!list) /* no elements */ return strdup(""); if(list->next == NULL) /* one element , no newline at end. */ return strdup(list->str); /* count total length */ for(s=list; s; s=s->next) total += strlen(s->str) + 1; /* len + newline */ left = total+1; /* one extra for nul at end */ r = malloc(left); if(!r) return NULL; w = r; for(s=list; s; s=s->next) { size_t this = strlen(s->str); if(this+2 > left) { /* sanity check */ free(r); return NULL; } snprintf(w, left, "%s\n", s->str); this = strlen(w); w += this; left -= this; } return r; } /** compare and print decimal option */ #define O_DEC(opt, str, var) if(strcmp(opt, str)==0) \ {snprintf(buf, len, "%d", (int)cfg->var); \ func(buf, arg);} /** compare and print unsigned option */ #define O_UNS(opt, str, var) if(strcmp(opt, str)==0) \ {snprintf(buf, len, "%u", (unsigned)cfg->var); \ func(buf, arg);} /** compare and print yesno option */ #define O_YNO(opt, str, var) if(strcmp(opt, str)==0) \ {func(cfg->var?"yes":"no", arg);} /** compare and print string option */ #define O_STR(opt, str, var) if(strcmp(opt, str)==0) \ {func(cfg->var?cfg->var:"", arg);} /** compare and print array option */ #define O_IFC(opt, str, num, arr) if(strcmp(opt, str)==0) \ {int i; for(i=0; inum; i++) func(cfg->arr[i], arg);} /** compare and print memorysize option */ #define O_MEM(opt, str, var) if(strcmp(opt, str)==0) { \ if(cfg->var > 1024*1024*1024) { \ size_t f=cfg->var/(size_t)1000000, b=cfg->var%(size_t)1000000; \ snprintf(buf, len, "%u%6.6u", (unsigned)f, (unsigned)b); \ } else snprintf(buf, len, "%u", (unsigned)cfg->var); \ func(buf, arg);} /** compare and print list option */ #define O_LST(opt, name, lst) if(strcmp(opt, name)==0) { \ struct config_strlist* p = cfg->lst; \ for(p = cfg->lst; p; p = p->next) \ func(p->str, arg); \ } /** compare and print list option */ #define O_LS2(opt, name, lst) if(strcmp(opt, name)==0) { \ struct config_str2list* p = cfg->lst; \ for(p = cfg->lst; p; p = p->next) \ snprintf(buf, len, "%s %s\n", p->str, p->str2); \ func(buf, arg); \ } int config_get_option(struct config_file* cfg, const char* opt, void (*func)(char*,void*), void* arg) { char buf[1024]; size_t len = sizeof(buf); fptr_ok(fptr_whitelist_print_func(func)); O_DEC(opt, "verbosity", verbosity) else O_DEC(opt, "statistics-interval", stat_interval) else O_YNO(opt, "statistics-cumulative", stat_cumulative) else O_YNO(opt, "extended-statistics", stat_extended) else O_YNO(opt, "use-syslog", use_syslog) else O_YNO(opt, "log-time-ascii", log_time_ascii) else O_DEC(opt, "num-threads", num_threads) else O_IFC(opt, "interface", num_ifs, ifs) else O_IFC(opt, "outgoing-interface", num_out_ifs, out_ifs) else O_YNO(opt, "interface-automatic", if_automatic) else O_DEC(opt, "port", port) else O_DEC(opt, "outgoing-range", outgoing_num_ports) else O_DEC(opt, "outgoing-num-tcp", outgoing_num_tcp) else O_DEC(opt, "incoming-num-tcp", incoming_num_tcp) else O_DEC(opt, "edns-buffer-size", edns_buffer_size) else O_DEC(opt, "msg-buffer-size", msg_buffer_size) else O_MEM(opt, "msg-cache-size", msg_cache_size) else O_DEC(opt, "msg-cache-slabs", msg_cache_slabs) else O_DEC(opt, "num-queries-per-thread", num_queries_per_thread) else O_UNS(opt, "jostle-timeout", jostle_time) else O_MEM(opt, "so-rcvbuf", so_rcvbuf) else O_MEM(opt, "so-sndbuf", so_sndbuf) else O_YNO(opt, "so-reuseport", so_reuseport) else O_YNO(opt, "ip-transparent", ip_transparent) else O_MEM(opt, "rrset-cache-size", rrset_cache_size) else O_DEC(opt, "rrset-cache-slabs", rrset_cache_slabs) else O_YNO(opt, "prefetch-key", prefetch_key) else O_YNO(opt, "prefetch", prefetch) else O_DEC(opt, "cache-max-ttl", max_ttl) else O_DEC(opt, "cache-max-negative-ttl", max_negative_ttl) else O_DEC(opt, "cache-min-ttl", min_ttl) else O_DEC(opt, "infra-host-ttl", host_ttl) else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs) else O_DEC(opt, "infra-cache-min-rtt", infra_cache_min_rtt) else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts) else O_UNS(opt, "delay-close", delay_close) else O_YNO(opt, "do-ip4", do_ip4) else O_YNO(opt, "do-ip6", do_ip6) else O_YNO(opt, "do-udp", do_udp) else O_YNO(opt, "do-tcp", do_tcp) else O_YNO(opt, "tcp-upstream", tcp_upstream) else O_YNO(opt, "ssl-upstream", ssl_upstream) else O_STR(opt, "ssl-service-key", ssl_service_key) else O_STR(opt, "ssl-service-pem", ssl_service_pem) else O_DEC(opt, "ssl-port", ssl_port) else O_YNO(opt, "do-daemonize", do_daemonize) else O_STR(opt, "chroot", chrootdir) else O_STR(opt, "username", username) else O_STR(opt, "directory", directory) else O_STR(opt, "logfile", logfile) else O_YNO(opt, "log-queries", log_queries) else O_STR(opt, "pidfile", pidfile) else O_YNO(opt, "hide-identity", hide_identity) else O_YNO(opt, "hide-version", hide_version) else O_STR(opt, "identity", identity) else O_STR(opt, "version", version) else O_STR(opt, "target-fetch-policy", target_fetch_policy) else O_YNO(opt, "harden-short-bufsize", harden_short_bufsize) else O_YNO(opt, "harden-large-queries", harden_large_queries) else O_YNO(opt, "harden-glue", harden_glue) else O_YNO(opt, "harden-dnssec-stripped", harden_dnssec_stripped) else O_YNO(opt, "harden-below-nxdomain", harden_below_nxdomain) else O_YNO(opt, "harden-referral-path", harden_referral_path) else O_YNO(opt, "harden-algo-downgrade", harden_algo_downgrade) else O_YNO(opt, "use-caps-for-id", use_caps_bits_for_id) else O_LST(opt, "caps-whitelist", caps_whitelist) else O_DEC(opt, "unwanted-reply-threshold", unwanted_threshold) else O_YNO(opt, "do-not-query-localhost", donotquery_localhost) else O_STR(opt, "module-config", module_conf) else O_STR(opt, "dlv-anchor-file", dlv_anchor_file) else O_DEC(opt, "val-bogus-ttl", bogus_ttl) else O_YNO(opt, "val-clean-additional", val_clean_additional) else O_DEC(opt, "val-log-level", val_log_level) else O_YNO(opt, "val-permissive-mode", val_permissive_mode) else O_YNO(opt, "ignore-cd-flag", ignore_cd) else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations) else O_UNS(opt, "add-holddown", add_holddown) else O_UNS(opt, "del-holddown", del_holddown) else O_UNS(opt, "keep-missing", keep_missing) else O_YNO(opt, "permit-small-holddown", permit_small_holddown) else O_MEM(opt, "key-cache-size", key_cache_size) else O_DEC(opt, "key-cache-slabs", key_cache_slabs) else O_MEM(opt, "neg-cache-size", neg_cache_size) else O_YNO(opt, "control-enable", remote_control_enable) else O_DEC(opt, "control-port", control_port) else O_STR(opt, "server-key-file", server_key_file) else O_STR(opt, "server-cert-file", server_cert_file) else O_STR(opt, "control-key-file", control_key_file) else O_STR(opt, "control-cert-file", control_cert_file) else O_LST(opt, "root-hints", root_hints) else O_LS2(opt, "access-control", acls) else O_LST(opt, "do-not-query-address", donotqueryaddrs) else O_LST(opt, "private-address", private_address) else O_LST(opt, "private-domain", private_domain) else O_LST(opt, "auto-trust-anchor-file", auto_trust_anchor_file_list) else O_LST(opt, "trust-anchor-file", trust_anchor_file_list) else O_LST(opt, "trust-anchor", trust_anchor_list) else O_LST(opt, "trusted-keys-file", trusted_keys_file_list) else O_LST(opt, "dlv-anchor", dlv_anchor_list) else O_LST(opt, "control-interface", control_ifs) else O_LST(opt, "domain-insecure", domain_insecure) else O_UNS(opt, "val-override-date", val_date_override) else O_YNO(opt, "minimal-responses", minimal_responses) else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin) else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones) + else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones) else O_DEC(opt, "max-udp-size", max_udp_size) else O_STR(opt, "python-script", python_script) else O_DEC(opt, "ratelimit", ratelimit) else O_MEM(opt, "ratelimit-size", ratelimit_size) else O_DEC(opt, "ratelimit-slabs", ratelimit_slabs) else O_LS2(opt, "ratelimit-for-domain", ratelimit_for_domain) else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain) else O_DEC(opt, "ratelimit-factor", ratelimit_factor) else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min) else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max) else O_YNO(opt, "qname-minimisation", qname_minimisation) /* not here: * outgoing-permit, outgoing-avoid - have list of ports * local-zone - zones and nodefault variables * local-data - see below * local-data-ptr - converted to local-data entries * stub-zone, name, stub-addr, stub-host, stub-prime * forward-zone, name, forward-addr, forward-host */ else return 0; return 1; } /** initialize the global cfg_parser object */ static void create_cfg_parser(struct config_file* cfg, char* filename, const char* chroot) { static struct config_parser_state st; cfg_parser = &st; cfg_parser->filename = filename; cfg_parser->line = 1; cfg_parser->errors = 0; cfg_parser->cfg = cfg; cfg_parser->chroot = chroot; init_cfg_parse(); } int config_read(struct config_file* cfg, const char* filename, const char* chroot) { FILE *in; char *fname = (char*)filename; #ifdef HAVE_GLOB glob_t g; size_t i; int r, flags; #endif if(!fname) return 1; /* check for wildcards */ #ifdef HAVE_GLOB if(!(!strchr(fname, '*') && !strchr(fname, '?') && !strchr(fname, '[') && !strchr(fname, '{') && !strchr(fname, '~'))) { verbose(VERB_QUERY, "wildcard found, processing %s", fname); flags = 0 #ifdef GLOB_ERR | GLOB_ERR #endif #ifdef GLOB_NOSORT | GLOB_NOSORT #endif #ifdef GLOB_BRACE | GLOB_BRACE #endif #ifdef GLOB_TILDE | GLOB_TILDE #endif ; memset(&g, 0, sizeof(g)); r = glob(fname, flags, NULL, &g); if(r) { /* some error */ globfree(&g); if(r == GLOB_NOMATCH) { verbose(VERB_QUERY, "include: " "no matches for %s", fname); return 1; } else if(r == GLOB_NOSPACE) { log_err("include: %s: " "fnametern out of memory", fname); } else if(r == GLOB_ABORTED) { log_err("wildcard include: %s: expansion " "aborted (%s)", fname, strerror(errno)); } else { log_err("wildcard include: %s: expansion " "failed (%s)", fname, strerror(errno)); } /* ignore globs that yield no files */ return 1; } /* process files found, if any */ for(i=0; i<(size_t)g.gl_pathc; i++) { if(!config_read(cfg, g.gl_pathv[i], chroot)) { log_err("error reading wildcard " "include: %s", g.gl_pathv[i]); globfree(&g); return 0; } } globfree(&g); return 1; } #endif /* HAVE_GLOB */ in = fopen(fname, "r"); if(!in) { log_err("Could not open %s: %s", fname, strerror(errno)); return 0; } create_cfg_parser(cfg, fname, chroot); ub_c_in = in; ub_c_parse(); fclose(in); if(cfg_parser->errors != 0) { fprintf(stderr, "read %s failed: %d errors in configuration file\n", fname, cfg_parser->errors); errno=EINVAL; return 0; } return 1; } void config_delstrlist(struct config_strlist* p) { struct config_strlist *np; while(p) { np = p->next; free(p->str); free(p); p = np; } } void config_deldblstrlist(struct config_str2list* p) { struct config_str2list *np; while(p) { np = p->next; free(p->str); free(p->str2); free(p); p = np; } } void config_delstubs(struct config_stub* p) { struct config_stub* np; while(p) { np = p->next; free(p->name); config_delstrlist(p->hosts); config_delstrlist(p->addrs); free(p); p = np; } } void config_delete(struct config_file* cfg) { if(!cfg) return; free(cfg->username); free(cfg->chrootdir); free(cfg->directory); free(cfg->logfile); free(cfg->pidfile); free(cfg->target_fetch_policy); free(cfg->ssl_service_key); free(cfg->ssl_service_pem); if(cfg->ifs) { int i; for(i=0; inum_ifs; i++) free(cfg->ifs[i]); free(cfg->ifs); } if(cfg->out_ifs) { int i; for(i=0; inum_out_ifs; i++) free(cfg->out_ifs[i]); free(cfg->out_ifs); } config_delstubs(cfg->stubs); config_delstubs(cfg->forwards); config_delstrlist(cfg->donotqueryaddrs); config_delstrlist(cfg->root_hints); free(cfg->identity); free(cfg->version); free(cfg->module_conf); free(cfg->outgoing_avail_ports); config_delstrlist(cfg->caps_whitelist); config_delstrlist(cfg->private_address); config_delstrlist(cfg->private_domain); config_delstrlist(cfg->auto_trust_anchor_file_list); config_delstrlist(cfg->trust_anchor_file_list); config_delstrlist(cfg->trusted_keys_file_list); config_delstrlist(cfg->trust_anchor_list); config_delstrlist(cfg->domain_insecure); free(cfg->dlv_anchor_file); config_delstrlist(cfg->dlv_anchor_list); config_deldblstrlist(cfg->acls); free(cfg->val_nsec3_key_iterations); config_deldblstrlist(cfg->local_zones); config_delstrlist(cfg->local_zones_nodefault); config_delstrlist(cfg->local_data); config_delstrlist(cfg->control_ifs); free(cfg->server_key_file); free(cfg->server_cert_file); free(cfg->control_key_file); free(cfg->control_cert_file); free(cfg->dns64_prefix); free(cfg->dnstap_socket_path); free(cfg->dnstap_identity); free(cfg->dnstap_version); config_deldblstrlist(cfg->ratelimit_for_domain); config_deldblstrlist(cfg->ratelimit_below_domain); free(cfg); } static void init_outgoing_availports(int* a, int num) { /* generated with make iana_update */ const int iana_assigned[] = { #include "util/iana_ports.inc" -1 }; /* end marker to put behind trailing comma */ int i; /* do not use <1024, that could be trouble with the system, privs */ for(i=1024; i= (int)sizeof(buf) ) { log_err("cannot parse port number '%s'", str); return 0; } if(mid > str) memcpy(buf, str, (size_t)(mid-str)); buf[mid-str] = 0; low = atoi(buf); if(low == 0 && strcmp(buf, "0") != 0) { log_err("cannot parse port number '%s'", buf); return 0; } for(i=low; i<=high; i++) { if(i < num) avail[i] = (allow?i:0); } return 1; } return 1; } int cfg_scan_ports(int* avail, int num) { int i; int count = 0; for(i=0; ioutgoing_avail_ports, 65536); int i, at = 0; *avail = NULL; if(num == 0) return 0; *avail = (int*)reallocarray(NULL, (size_t)num, sizeof(int)); if(!*avail) return 0; for(i=0; i<65536; i++) { if(cfg->outgoing_avail_ports[i]) (*avail)[at++] = cfg->outgoing_avail_ports[i]; } log_assert(at == num); return num; } /** print error with file and line number */ static void ub_c_error_va_list(const char *fmt, va_list args) { cfg_parser->errors++; fprintf(stderr, "%s:%d: error: ", cfg_parser->filename, cfg_parser->line); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } /** print error with file and line number */ void ub_c_error_msg(const char* fmt, ...) { va_list args; va_start(args, fmt); ub_c_error_va_list(fmt, args); va_end(args); } void ub_c_error(const char *str) { cfg_parser->errors++; fprintf(stderr, "%s:%d: error: %s\n", cfg_parser->filename, cfg_parser->line, str); } int ub_c_wrap(void) { return 1; } int cfg_strlist_append(struct config_strlist_head* list, char* item) { struct config_strlist *s; if(!item || !list) return 0; s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist)); if(!s) return 0; s->str = item; s->next = NULL; if(list->last) list->last->next = s; else list->first = s; list->last = s; return 1; } int cfg_strlist_insert(struct config_strlist** head, char* item) { struct config_strlist *s; if(!item || !head) return 0; s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist)); if(!s) return 0; s->str = item; s->next = *head; *head = s; return 1; } int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2) { struct config_str2list *s; if(!item || !i2 || !head) return 0; s = (struct config_str2list*)calloc(1, sizeof(struct config_str2list)); if(!s) return 0; s->str = item; s->str2 = i2; s->next = *head; *head = s; return 1; } time_t cfg_convert_timeval(const char* str) { time_t t; struct tm tm; memset(&tm, 0, sizeof(tm)); if(strlen(str) < 14) return 0; if(sscanf(str, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) return 0; tm.tm_year -= 1900; tm.tm_mon--; /* Check values */ if (tm.tm_year < 70) return 0; if (tm.tm_mon < 0 || tm.tm_mon > 11) return 0; if (tm.tm_mday < 1 || tm.tm_mday > 31) return 0; if (tm.tm_hour < 0 || tm.tm_hour > 23) return 0; if (tm.tm_min < 0 || tm.tm_min > 59) return 0; if (tm.tm_sec < 0 || tm.tm_sec > 59) return 0; /* call ldns conversion function */ t = sldns_mktime_from_utc(&tm); return t; } int cfg_count_numbers(const char* s) { /* format ::= (sp num)+ sp */ /* num ::= [-](0-9)+ */ /* sp ::= (space|tab)* */ int num = 0; while(*s) { while(*s && isspace((unsigned char)*s)) s++; if(!*s) /* end of string */ break; if(*s == '-') s++; if(!*s) /* only - not allowed */ return 0; if(!isdigit((unsigned char)*s)) /* bad character */ return 0; while(*s && isdigit((unsigned char)*s)) s++; num++; } return num; } /** all digit number */ static int isalldigit(const char* str, size_t l) { size_t i; for(i=0; i0 && str[len-1]==' ') len--; if(len > 1 && str[len-1] == 'b') len--; else if(len > 1 && str[len-1] == 'B') len--; if(len > 1 && tolower((unsigned char)str[len-1]) == 'g') mult = 1024*1024*1024; else if(len > 1 && tolower((unsigned char)str[len-1]) == 'm') mult = 1024*1024; else if(len > 1 && tolower((unsigned char)str[len-1]) == 'k') mult = 1024; else if(len > 0 && isdigit((unsigned char)str[len-1])) mult = 1; else { log_err("unknown size specifier: '%s'", str); return 0; } while(len>1 && str[len-2]==' ') len--; if(!isalldigit(str, len-1)) { log_err("unknown size specifier: '%s'", str); return 0; } *res = ((size_t)atol(str)) * mult; return 1; } void config_apply(struct config_file* config) { MAX_TTL = (time_t)config->max_ttl; MIN_TTL = (time_t)config->min_ttl; MAX_NEG_TTL = (time_t)config->max_negative_ttl; RTT_MIN_TIMEOUT = config->infra_cache_min_rtt; EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size; MINIMAL_RESPONSES = config->minimal_responses; RRSET_ROUNDROBIN = config->rrset_roundrobin; log_set_time_asc(config->log_time_ascii); autr_permit_small_holddown = config->permit_small_holddown; } void config_lookup_uid(struct config_file* cfg) { #ifdef HAVE_GETPWNAM /* translate username into uid and gid */ if(cfg->username && cfg->username[0]) { struct passwd *pwd; if((pwd = getpwnam(cfg->username)) != NULL) { cfg_uid = pwd->pw_uid; cfg_gid = pwd->pw_gid; } } #else (void)cfg; #endif } /** * Calculate string length of full pathname in original filesys * @param fname: the path name to convert. * Must not be null or empty. * @param cfg: config struct for chroot and chdir (if set). * @param use_chdir: if false, only chroot is applied. * @return length of string. * remember to allocate one more for 0 at end in mallocs. */ static size_t strlen_after_chroot(const char* fname, struct config_file* cfg, int use_chdir) { size_t len = 0; int slashit = 0; if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(cfg->chrootdir, fname, strlen(cfg->chrootdir)) == 0) { /* already full pathname, return it */ return strlen(fname); } /* chroot */ if(cfg->chrootdir && cfg->chrootdir[0]) { /* start with chrootdir */ len += strlen(cfg->chrootdir); slashit = 1; } /* chdir */ #ifdef UB_ON_WINDOWS if(fname[0] != 0 && fname[1] == ':') { /* full path, no chdir */ } else #endif if(fname[0] == '/' || !use_chdir) { /* full path, no chdir */ } else if(cfg->directory && cfg->directory[0]) { /* prepend chdir */ if(slashit && cfg->directory[0] != '/') len++; if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(cfg->chrootdir, cfg->directory, strlen(cfg->chrootdir)) == 0) len += strlen(cfg->directory)-strlen(cfg->chrootdir); else len += strlen(cfg->directory); slashit = 1; } /* fname */ if(slashit && fname[0] != '/') len++; len += strlen(fname); return len; } char* fname_after_chroot(const char* fname, struct config_file* cfg, int use_chdir) { size_t len = strlen_after_chroot(fname, cfg, use_chdir)+1; int slashit = 0; char* buf = (char*)malloc(len); if(!buf) return NULL; buf[0] = 0; /* is fname already in chroot ? */ if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(cfg->chrootdir, fname, strlen(cfg->chrootdir)) == 0) { /* already full pathname, return it */ (void)strlcpy(buf, fname, len); buf[len-1] = 0; return buf; } /* chroot */ if(cfg->chrootdir && cfg->chrootdir[0]) { /* start with chrootdir */ (void)strlcpy(buf, cfg->chrootdir, len); slashit = 1; } #ifdef UB_ON_WINDOWS if(fname[0] != 0 && fname[1] == ':') { /* full path, no chdir */ } else #endif /* chdir */ if(fname[0] == '/' || !use_chdir) { /* full path, no chdir */ } else if(cfg->directory && cfg->directory[0]) { /* prepend chdir */ if(slashit && cfg->directory[0] != '/') (void)strlcat(buf, "/", len); /* is the directory already in the chroot? */ if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(cfg->chrootdir, cfg->directory, strlen(cfg->chrootdir)) == 0) (void)strlcat(buf, cfg->directory+strlen(cfg->chrootdir), len); else (void)strlcat(buf, cfg->directory, len); slashit = 1; } /* fname */ if(slashit && fname[0] != '/') (void)strlcat(buf, "/", len); (void)strlcat(buf, fname, len); buf[len-1] = 0; return buf; } /** return next space character in string */ static char* next_space_pos(const char* str) { char* sp = strchr(str, ' '); char* tab = strchr(str, '\t'); if(!tab && !sp) return NULL; if(!sp) return tab; if(!tab) return sp; return (sptab)?sp:tab; } int cfg_parse_local_zone(struct config_file* cfg, const char* val) { const char *type, *name_end, *name; char buf[256]; /* parse it as: [zone_name] [between stuff] [zone_type] */ name = val; while(*name && isspace((unsigned char)*name)) name++; if(!*name) { log_err("syntax error: too short: %s", val); return 0; } name_end = next_space_pos(name); if(!name_end || !*name_end) { log_err("syntax error: expected zone type: %s", val); return 0; } if (name_end - name > 255) { log_err("syntax error: bad zone name: %s", val); return 0; } (void)strlcpy(buf, name, sizeof(buf)); buf[name_end-name] = '\0'; type = last_space_pos(name_end); while(type && *type && isspace((unsigned char)*type)) type++; if(!type || !*type) { log_err("syntax error: expected zone type: %s", val); return 0; } if(strcmp(type, "nodefault")==0) { return cfg_strlist_insert(&cfg->local_zones_nodefault, strdup(name)); } else { return cfg_str2list_insert(&cfg->local_zones, strdup(buf), strdup(type)); } } char* cfg_ptr_reverse(char* str) { char* ip, *ip_end; char* name; char* result; char buf[1024]; struct sockaddr_storage addr; socklen_t addrlen; /* parse it as: [IP] [between stuff] [name] */ ip = str; while(*ip && isspace((unsigned char)*ip)) ip++; if(!*ip) { log_err("syntax error: too short: %s", str); return NULL; } ip_end = next_space_pos(ip); if(!ip_end || !*ip_end) { log_err("syntax error: expected name: %s", str); return NULL; } name = last_space_pos(ip_end); if(!name || !*name) { log_err("syntax error: expected name: %s", str); return NULL; } sscanf(ip, "%100s", buf); buf[sizeof(buf)-1]=0; if(!ipstrtoaddr(buf, UNBOUND_DNS_PORT, &addr, &addrlen)) { log_err("syntax error: cannot parse address: %s", str); return NULL; } /* reverse IPv4: * ddd.ddd.ddd.ddd.in-addr-arpa. * IPv6: (h.){32}.ip6.arpa. */ if(addr_is_ip6(&addr, addrlen)) { uint8_t ad[16]; const char* hex = "0123456789abcdef"; char *p = buf; int i; memmove(ad, &((struct sockaddr_in6*)&addr)->sin6_addr, sizeof(ad)); for(i=15; i>=0; i--) { uint8_t b = ad[i]; *p++ = hex[ (b&0x0f) ]; *p++ = '.'; *p++ = hex[ (b&0xf0) >> 4 ]; *p++ = '.'; } snprintf(buf+16*4, sizeof(buf)-16*4, "ip6.arpa. "); } else { uint8_t ad[4]; memmove(ad, &((struct sockaddr_in*)&addr)->sin_addr, sizeof(ad)); snprintf(buf, sizeof(buf), "%u.%u.%u.%u.in-addr.arpa. ", (unsigned)ad[3], (unsigned)ad[2], (unsigned)ad[1], (unsigned)ad[0]); } /* printed the reverse address, now the between goop and name on end */ while(*ip_end && isspace((unsigned char)*ip_end)) ip_end++; if(name>ip_end) { snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%.*s", (int)(name-ip_end), ip_end); } snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), " PTR %s", name); result = strdup(buf); if(!result) { log_err("out of memory parsing %s", str); return NULL; } return result; } #ifdef UB_ON_WINDOWS char* w_lookup_reg_str(const char* key, const char* name) { HKEY hk = NULL; DWORD type = 0; BYTE buf[1024]; DWORD len = (DWORD)sizeof(buf); LONG ret; char* result = NULL; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* key does not exist */ else if(ret != ERROR_SUCCESS) { log_err("RegOpenKeyEx failed"); return NULL; } ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len); if(RegCloseKey(hk)) log_err("RegCloseKey"); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* name does not exist */ else if(ret != ERROR_SUCCESS) { log_err("RegQueryValueEx failed"); return NULL; } if(type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ) { buf[sizeof(buf)-1] = 0; buf[sizeof(buf)-2] = 0; /* for multi_sz */ result = strdup((char*)buf); if(!result) log_err("out of memory"); } return result; } void w_config_adjust_directory(struct config_file* cfg) { if(cfg->directory && cfg->directory[0]) { TCHAR dirbuf[2*MAX_PATH+4]; if(strcmp(cfg->directory, "%EXECUTABLE%") == 0) { /* get executable path, and if that contains * directories, snip off the filename part */ dirbuf[0] = 0; if(!GetModuleFileName(NULL, dirbuf, MAX_PATH)) log_err("could not GetModuleFileName"); if(strrchr(dirbuf, '\\')) { (strrchr(dirbuf, '\\'))[0] = 0; } else log_err("GetModuleFileName had no path"); if(dirbuf[0]) { /* adjust directory for later lookups to work*/ free(cfg->directory); cfg->directory = memdup(dirbuf, strlen(dirbuf)+1); } } } } #endif /* UB_ON_WINDOWS */ void errinf(struct module_qstate* qstate, const char* str) { struct config_strlist* p; if(qstate->env->cfg->val_log_level < 2 || !str) return; p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p)); if(!p) { log_err("malloc failure in validator-error-info string"); return; } p->next = NULL; p->str = regional_strdup(qstate->region, str); if(!p->str) { log_err("malloc failure in validator-error-info string"); return; } /* add at end */ if(qstate->errinf) { struct config_strlist* q = qstate->errinf; while(q->next) q = q->next; q->next = p; } else qstate->errinf = p; } void errinf_origin(struct module_qstate* qstate, struct sock_list *origin) { struct sock_list* p; if(qstate->env->cfg->val_log_level < 2) return; for(p=origin; p; p=p->next) { char buf[256]; if(p == origin) snprintf(buf, sizeof(buf), "from "); else snprintf(buf, sizeof(buf), "and "); if(p->len == 0) snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "cache"); else addr_to_str(&p->addr, p->len, buf+strlen(buf), sizeof(buf)-strlen(buf)); errinf(qstate, buf); } } char* errinf_to_str(struct module_qstate* qstate) { char buf[20480]; char* p = buf; size_t left = sizeof(buf); struct config_strlist* s; char dname[LDNS_MAX_DOMAINLEN+1]; char t[16], c[16]; sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); dname_str(qstate->qinfo.qname, dname); snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c); left -= strlen(p); p += strlen(p); if(!qstate->errinf) snprintf(p, left, " misc failure"); else for(s=qstate->errinf; s; s=s->next) { snprintf(p, left, " %s", s->str); left -= strlen(p); p += strlen(p); } p = strdup(buf); if(!p) log_err("malloc failure in errinf_to_str"); return p; } void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) { char buf[1024]; char dname[LDNS_MAX_DOMAINLEN+1]; char t[16], c[16]; if(qstate->env->cfg->val_log_level < 2 || !rr) return; sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t)); sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c)); dname_str(rr->rk.dname, dname); snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c); errinf(qstate, buf); } void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname) { char b[1024]; char buf[LDNS_MAX_DOMAINLEN+1]; if(qstate->env->cfg->val_log_level < 2 || !str || !dname) return; dname_str(dname, buf); snprintf(b, sizeof(b), "%s %s", str, buf); errinf(qstate, b); } Index: vendor/unbound/dist/util/config_file.h =================================================================== --- vendor/unbound/dist/util/config_file.h (revision 295529) +++ vendor/unbound/dist/util/config_file.h (revision 295530) @@ -1,749 +1,751 @@ /* * util/config_file.h - reads and stores the config file for unbound. * * Copyright (c) 2007, 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 functions for the config file. */ #ifndef UTIL_CONFIG_FILE_H #define UTIL_CONFIG_FILE_H struct config_stub; struct config_strlist; struct config_str2list; struct module_qstate; struct sock_list; struct ub_packed_rrset_key; /** * The configuration options. * Strings are malloced. */ struct config_file { /** verbosity level as specified in the config file */ int verbosity; /** statistics interval (in seconds) */ int stat_interval; /** if false, statistics values are reset after printing them */ int stat_cumulative; /** if true, the statistics are kept in greater detail */ int stat_extended; /** number of threads to create */ int num_threads; /** port on which queries are answered. */ int port; /** do ip4 query support. */ int do_ip4; /** do ip6 query support. */ int do_ip6; /** do udp query support. */ int do_udp; /** do tcp query support. */ int do_tcp; /** tcp upstream queries (no UDP upstream queries) */ int tcp_upstream; /** private key file for dnstcp-ssl service (enabled if not NULL) */ char* ssl_service_key; /** public key file for dnstcp-ssl service */ char* ssl_service_pem; /** port on which to provide ssl service */ int ssl_port; /** if outgoing tcp connections use SSL */ int ssl_upstream; /** outgoing port range number of ports (per thread) */ int outgoing_num_ports; /** number of outgoing tcp buffers per (per thread) */ size_t outgoing_num_tcp; /** number of incoming tcp buffers per (per thread) */ size_t incoming_num_tcp; /** allowed udp port numbers, array with 0 if not allowed */ int* outgoing_avail_ports; /** EDNS buffer size to use */ size_t edns_buffer_size; /** number of bytes buffer size for DNS messages */ size_t msg_buffer_size; /** size of the message cache */ size_t msg_cache_size; /** slabs in the message cache. */ size_t msg_cache_slabs; /** number of queries every thread can service */ size_t num_queries_per_thread; /** number of msec to wait before items can be jostled out */ size_t jostle_time; /** size of the rrset cache */ size_t rrset_cache_size; /** slabs in the rrset cache */ size_t rrset_cache_slabs; /** host cache ttl in seconds */ int host_ttl; /** number of slabs in the infra host cache */ size_t infra_cache_slabs; /** max number of hosts in the infra cache */ size_t infra_cache_numhosts; /** min value for infra cache rtt */ int infra_cache_min_rtt; /** delay close of udp-timeouted ports, if 0 no delayclose. in msec */ int delay_close; /** the target fetch policy for the iterator */ char* target_fetch_policy; /** automatic interface for incoming messages. Uses ipv6 remapping, * and recvmsg/sendmsg ancillary data to detect interfaces, boolean */ int if_automatic; /** SO_RCVBUF size to set on port 53 UDP socket */ size_t so_rcvbuf; /** SO_SNDBUF size to set on port 53 UDP socket */ size_t so_sndbuf; /** SO_REUSEPORT requested on port 53 sockets */ int so_reuseport; /** IP_TRANSPARENT socket option requested on port 53 sockets */ int ip_transparent; /** number of interfaces to open. If 0 default all interfaces. */ int num_ifs; /** interface description strings (IP addresses) */ char **ifs; /** number of outgoing interfaces to open. * If 0 default all interfaces. */ int num_out_ifs; /** outgoing interface description strings (IP addresses) */ char **out_ifs; /** the root hints */ struct config_strlist* root_hints; /** the stub definitions, linked list */ struct config_stub* stubs; /** the forward zone definitions, linked list */ struct config_stub* forwards; /** list of donotquery addresses, linked list */ struct config_strlist* donotqueryaddrs; /** list of access control entries, linked list */ struct config_str2list* acls; /** use default localhost donotqueryaddr entries */ int donotquery_localhost; /** harden against very small edns buffer sizes */ int harden_short_bufsize; /** harden against very large query sizes */ int harden_large_queries; /** harden against spoofed glue (out of zone data) */ int harden_glue; /** harden against receiving no DNSSEC data for trust anchor */ int harden_dnssec_stripped; /** harden against queries that fall under known nxdomain names */ int harden_below_nxdomain; /** harden the referral path, query for NS,A,AAAA and validate */ int harden_referral_path; /** harden against algorithm downgrade */ int harden_algo_downgrade; /** use 0x20 bits in query as random ID bits */ int use_caps_bits_for_id; /** 0x20 whitelist, domains that do not use capsforid */ struct config_strlist* caps_whitelist; /** strip away these private addrs from answers, no DNS Rebinding */ struct config_strlist* private_address; /** allow domain (and subdomains) to use private address space */ struct config_strlist* private_domain; /** what threshold for unwanted action. */ size_t unwanted_threshold; /** the number of seconds maximal TTL used for RRsets and messages */ int max_ttl; /** the number of seconds minimum TTL used for RRsets and messages */ int min_ttl; /** the number of seconds maximal negative TTL for SOA in auth */ int max_negative_ttl; /** if prefetching of messages should be performed. */ int prefetch; /** if prefetching of DNSKEYs should be performed. */ int prefetch_key; /** chrootdir, if not "" or chroot will be done */ char* chrootdir; /** username to change to, if not "". */ char* username; /** working directory */ char* directory; /** filename to log to. */ char* logfile; /** pidfile to write pid to. */ char* pidfile; /** should log messages be sent to syslogd */ int use_syslog; /** log timestamp in ascii UTC */ int log_time_ascii; /** log queries with one line per query */ int log_queries; /** do not report identity (id.server, hostname.bind) */ int hide_identity; /** do not report version (version.server, version.bind) */ int hide_version; /** identity, hostname is returned if "". */ char* identity; /** version, package version returned if "". */ char* version; /** the module configuration string */ char* module_conf; /** files with trusted DS and DNSKEYs in zonefile format, list */ struct config_strlist* trust_anchor_file_list; /** list of trustanchor keys, linked list */ struct config_strlist* trust_anchor_list; /** files with 5011 autotrust tracked keys */ struct config_strlist* auto_trust_anchor_file_list; /** files with trusted DNSKEYs in named.conf format, list */ struct config_strlist* trusted_keys_file_list; /** DLV anchor file */ char* dlv_anchor_file; /** DLV anchor inline */ struct config_strlist* dlv_anchor_list; /** insecure domain list */ struct config_strlist* domain_insecure; /** if not 0, this value is the validation date for RRSIGs */ int32_t val_date_override; /** the minimum for signature clock skew */ int32_t val_sig_skew_min; /** the maximum for signature clock skew */ int32_t val_sig_skew_max; /** this value sets the number of seconds before revalidating bogus */ int bogus_ttl; /** should validator clean additional section for secure msgs */ int val_clean_additional; /** log bogus messages by the validator */ int val_log_level; /** squelch val_log_level to log - this is library goes to callback */ int val_log_squelch; /** should validator allow bogus messages to go through */ int val_permissive_mode; /** ignore the CD flag in incoming queries and refuse them bogus data */ int ignore_cd; /** nsec3 maximum iterations per key size, string */ char* val_nsec3_key_iterations; /** autotrust add holddown time, in seconds */ unsigned int add_holddown; /** autotrust del holddown time, in seconds */ unsigned int del_holddown; /** autotrust keep_missing time, in seconds. 0 is forever. */ unsigned int keep_missing; /** permit small holddown values, allowing 5011 rollover very fast */ int permit_small_holddown; /** size of the key cache */ size_t key_cache_size; /** slabs in the key cache. */ size_t key_cache_slabs; /** size of the neg cache */ size_t neg_cache_size; /** local zones config */ struct config_str2list* local_zones; /** local zones nodefault list */ struct config_strlist* local_zones_nodefault; /** local data RRs configured */ struct config_strlist* local_data; - /** unblock lan zones (reverse lookups for 10/8 and so on) */ + /** unblock lan zones (reverse lookups for AS112 zones) */ int unblock_lan_zones; + /** insecure lan zones (don't validate AS112 zones) */ + int insecure_lan_zones; /** remote control section. enable toggle. */ int remote_control_enable; /** the interfaces the remote control should listen on */ struct config_strlist* control_ifs; /** port number for the control port */ int control_port; /** use certificates for remote control */ int remote_control_use_cert; /** private key file for server */ char* server_key_file; /** certificate file for server */ char* server_cert_file; /** private key file for unbound-control */ char* control_key_file; /** certificate file for unbound-control */ char* control_cert_file; /** Python script file */ char* python_script; /** daemonize, i.e. fork into the background. */ int do_daemonize; /* minimal response when positive answer */ int minimal_responses; /* RRSet roundrobin */ int rrset_roundrobin; /* maximum UDP response size */ size_t max_udp_size; /* DNS64 prefix */ char* dns64_prefix; /* Synthetize all AAAA record despite the presence of an authoritative one */ int dns64_synthall; /** true to enable dnstap support */ int dnstap; /** dnstap socket path */ char* dnstap_socket_path; /** true to send "identity" via dnstap */ int dnstap_send_identity; /** true to send "version" via dnstap */ int dnstap_send_version; /** dnstap "identity", hostname is used if "". */ char* dnstap_identity; /** dnstap "version", package version is used if "". */ char* dnstap_version; /** true to log dnstap RESOLVER_QUERY message events */ int dnstap_log_resolver_query_messages; /** true to log dnstap RESOLVER_RESPONSE message events */ int dnstap_log_resolver_response_messages; /** true to log dnstap CLIENT_QUERY message events */ int dnstap_log_client_query_messages; /** true to log dnstap CLIENT_RESPONSE message events */ int dnstap_log_client_response_messages; /** true to log dnstap FORWARDER_QUERY message events */ int dnstap_log_forwarder_query_messages; /** true to log dnstap FORWARDER_RESPONSE message events */ int dnstap_log_forwarder_response_messages; /** ratelimit 0 is off, otherwise qps (unless overridden) */ int ratelimit; /** number of slabs for ratelimit cache */ size_t ratelimit_slabs; /** memory size in bytes for ratelimit cache */ size_t ratelimit_size; /** ratelimits for domain (exact match) */ struct config_str2list* ratelimit_for_domain; /** ratelimits below domain */ struct config_str2list* ratelimit_below_domain; /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */ int ratelimit_factor; /** minimise outgoing QNAME and hide original QTYPE if possible */ int qname_minimisation; }; /** from cfg username, after daemonise setup performed */ extern uid_t cfg_uid; /** from cfg username, after daemonise setup performed */ extern gid_t cfg_gid; /** debug and enable small timeouts */ extern int autr_permit_small_holddown; /** * Stub config options */ struct config_stub { /** next in list */ struct config_stub* next; /** domain name (in text) of the stub apex domain */ char* name; /** list of stub nameserver hosts (domain name) */ struct config_strlist* hosts; /** list of stub nameserver addresses (IP address) */ struct config_strlist* addrs; /** if stub-prime is set */ int isprime; /** if forward-first is set (failover to without if fails) */ int isfirst; }; /** * List of strings for config options */ struct config_strlist { /** next item in list */ struct config_strlist* next; /** config option string */ char* str; }; /** * List of two strings for config options */ struct config_str2list { /** next item in list */ struct config_str2list* next; /** first string */ char* str; /** second string */ char* str2; }; /** List head for strlist processing, used for append operation. */ struct config_strlist_head { /** first in list of text items */ struct config_strlist* first; /** last in list of text items */ struct config_strlist* last; }; /** * Create config file structure. Filled with default values. * @return: the new structure or NULL on memory error. */ struct config_file* config_create(void); /** * Create config file structure for library use. Filled with default values. * @return: the new structure or NULL on memory error. */ struct config_file* config_create_forlib(void); /** * Read the config file from the specified filename. * @param config: where options are stored into, must be freshly created. * @param filename: name of configfile. If NULL nothing is done. * @param chroot: if not NULL, the chroot dir currently in use (for include). * @return: false on error. In that case errno is set, ENOENT means * file not found. */ int config_read(struct config_file* config, const char* filename, const char* chroot); /** * Destroy the config file structure. * @param config: to delete. */ void config_delete(struct config_file* config); /** * Apply config to global constants; this routine is called in single thread. * @param config: to apply. Side effect: global constants change. */ void config_apply(struct config_file* config); /** * Find username, sets cfg_uid and cfg_gid. * @param config: the config structure. */ void config_lookup_uid(struct config_file* config); /** * Set the given keyword to the given value. * @param config: where to store config * @param option: option name, including the ':' character. * @param value: value, this string is copied if needed, or parsed. * The caller owns the value string. * @return 0 on error (malloc or syntax error). */ int config_set_option(struct config_file* config, const char* option, const char* value); /** * Call print routine for the given option. * @param cfg: config. * @param opt: option name without trailing :. * This is different from config_set_option. * @param func: print func, called as (str, arg) for every data element. * @param arg: user argument for print func. * @return false if the option name is not supported (syntax error). */ int config_get_option(struct config_file* cfg, const char* opt, void (*func)(char*,void*), void* arg); /** * Get an option and return strlist * @param cfg: config file * @param opt: option name. * @param list: list is returned here. malloced, caller must free it. * @return 0=OK, 1=syntax error, 2=malloc failed. */ int config_get_option_list(struct config_file* cfg, const char* opt, struct config_strlist** list); /** * Get an option and collate results into string * @param cfg: config file * @param opt: option name. * @param str: string. malloced, caller must free it. * @return 0=OK, 1=syntax error, 2=malloc failed. */ int config_get_option_collate(struct config_file* cfg, const char* opt, char** str); /** * function to print to a file, use as func with config_get_option. * @param line: text to print. \n appended. * @param arg: pass a FILE*, like stdout. */ void config_print_func(char* line, void* arg); /** * function to collate the text strings into a strlist_head. * @param line: text to append. * @param arg: pass a strlist_head structure. zeroed on start. */ void config_collate_func(char* line, void* arg); /** * take a strlist_head list and return a malloc string. separated with newline. * @param list: strlist first to collate. zeroes return "". * @return NULL on malloc failure. Or if malloc failure happened in strlist. */ char* config_collate_cat(struct config_strlist* list); /** * Append text at end of list. * @param list: list head. zeroed at start. * @param item: new item. malloced by caller. if NULL the insertion fails. * @return true on success. */ int cfg_strlist_append(struct config_strlist_head* list, char* item); /** * Insert string into strlist. * @param head: pointer to strlist head variable. * @param item: new item. malloced by caller. If NULL the insertion fails. * @return: true on success. */ int cfg_strlist_insert(struct config_strlist** head, char* item); /** * Insert string into str2list. * @param head: pointer to str2list head variable. * @param item: new item. malloced by caller. If NULL the insertion fails. * @param i2: 2nd string, malloced by caller. If NULL the insertion fails. * @return: true on success. */ int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2); /** * Delete items in config string list. * @param list: list. */ void config_delstrlist(struct config_strlist* list); /** * Delete items in config double string list. * @param list: list. */ void config_deldblstrlist(struct config_str2list* list); /** * Delete items in config stub list. * @param list: list. */ void config_delstubs(struct config_stub* list); /** * Convert 14digit to time value * @param str: string of 14 digits * @return time value or 0 for error. */ time_t cfg_convert_timeval(const char* str); /** * Count number of values in the string. * format ::= (sp num)+ sp * num ::= [-](0-9)+ * sp ::= (space|tab)* * * @param str: string * @return: 0 on parse error, or empty string, else * number of integer values in the string. */ int cfg_count_numbers(const char* str); /** * Convert a 'nice' memory or file size into a bytecount * From '100k' to 102400. and so on. Understands kKmMgG. * k=1024, m=1024*1024, g=1024*1024*1024. * @param str: string * @param res: result is stored here, size in bytes. * @return: true if parsed correctly, or 0 on a parse error (and an error * is logged). */ int cfg_parse_memsize(const char* str, size_t* res); /** * Parse local-zone directive into two strings and register it in the config. * @param cfg: to put it in. * @param val: argument strings to local-zone, "example.com nodefault". * @return: false on failure */ int cfg_parse_local_zone(struct config_file* cfg, const char* val); /** * Mark "number" or "low-high" as available or not in ports array. * @param str: string in input * @param allow: give true if this range is permitted. * @param avail: the array from cfg. * @param num: size of the array (65536). * @return: true if parsed correctly, or 0 on a parse error (and an error * is logged). */ int cfg_mark_ports(const char* str, int allow, int* avail, int num); /** * Get a condensed list of ports returned. allocated. * @param cfg: config file. * @param avail: the available ports array is returned here. * @return: number of ports in array or 0 on error. */ int cfg_condense_ports(struct config_file* cfg, int** avail); /** * Scan ports available * @param avail: the array from cfg. * @param num: size of the array (65536). * @return the number of ports available for use. */ int cfg_scan_ports(int* avail, int num); /** * Convert a filename to full pathname in original filesys * @param fname: the path name to convert. * Must not be null or empty. * @param cfg: config struct for chroot and chdir (if set). * @param use_chdir: if false, only chroot is applied. * @return pointer to malloced buffer which is: [chroot][chdir]fname * or NULL on malloc failure. */ char* fname_after_chroot(const char* fname, struct config_file* cfg, int use_chdir); /** * Convert a ptr shorthand into a full reverse-notation PTR record. * @param str: input string, "IP name" * @return: malloced string "reversed-ip-name PTR name" */ char* cfg_ptr_reverse(char* str); /** * Append text to the error info for validation. * @param qstate: query state. * @param str: copied into query region and appended. * Failures to allocate are logged. */ void errinf(struct module_qstate* qstate, const char* str); /** * Append text to error info: from 1.2.3.4 * @param qstate: query state. * @param origin: sock list with origin of trouble. * Every element added. * If NULL: nothing is added. * if 0len element: 'from cache' is added. */ void errinf_origin(struct module_qstate* qstate, struct sock_list *origin); /** * Append text to error info: for RRset name type class * @param qstate: query state. * @param rr: rrset_key. */ void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr); /** * Append text to error info: str dname * @param qstate: query state. * @param str: explanation string * @param dname: the dname. */ void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname); /** * Create error info in string * @param qstate: query state. * @return string or NULL on malloc failure (already logged). * This string is malloced and has to be freed by caller. */ char* errinf_to_str(struct module_qstate* qstate); /** * Used during options parsing */ struct config_parser_state { /** name of file being parser */ char* filename; /** line number in the file, starts at 1 */ int line; /** number of errors encountered */ int errors; /** the result of parsing is stored here. */ struct config_file* cfg; /** the current chroot dir (or NULL if none) */ const char* chroot; }; /** global config parser object used during config parsing */ extern struct config_parser_state* cfg_parser; /** init lex state */ void init_cfg_parse(void); /** lex in file */ extern FILE* ub_c_in; /** lex out file */ extern FILE* ub_c_out; /** the yacc lex generated parse function */ int ub_c_parse(void); /** the lexer function */ int ub_c_lex(void); /** wrap function */ int ub_c_wrap(void); /** parsing helpers: print error with file and line numbers */ void ub_c_error(const char* msg); /** parsing helpers: print error with file and line numbers */ void ub_c_error_msg(const char* fmt, ...) ATTR_FORMAT(printf, 1, 2); #ifdef UB_ON_WINDOWS /** * Obtain registry string (if it exists). * @param key: key string * @param name: name of value to fetch. * @return malloced string with the result or NULL if it did not * exist on an error (logged with log_err) was encountered. */ char* w_lookup_reg_str(const char* key, const char* name); /** Modify directory in options for module file name */ void w_config_adjust_directory(struct config_file* cfg); #endif /* UB_ON_WINDOWS */ #endif /* UTIL_CONFIG_FILE_H */ Index: vendor/unbound/dist/util/configlexer.lex =================================================================== --- vendor/unbound/dist/util/configlexer.lex (revision 295529) +++ vendor/unbound/dist/util/configlexer.lex (revision 295530) @@ -1,462 +1,463 @@ %{ /* * configlexer.lex - lexical analyzer for unbound config file * * Copyright (c) 2001-2006, NLnet Labs. All rights reserved * * See LICENSE for the license. * */ #include #include #include #ifdef HAVE_GLOB_H # include #endif #include "util/config_file.h" #include "util/configparser.h" void ub_c_error(const char *message); #if 0 #define LEXOUT(s) printf s /* used ONLY when debugging */ #else #define LEXOUT(s) #endif /** avoid warning in about fwrite return value */ #define ECHO ub_c_error_msg("syntax error at text: %s", yytext) /** A parser variable, this is a statement in the config file which is * of the form variable: value1 value2 ... nargs is the number of values. */ #define YDVAR(nargs, var) \ num_args=(nargs); \ LEXOUT(("v(%s%d) ", yytext, num_args)); \ if(num_args > 0) { BEGIN(val); } \ return (var); struct inc_state { char* filename; int line; YY_BUFFER_STATE buffer; struct inc_state* next; }; static struct inc_state* config_include_stack = NULL; static int inc_depth = 0; static int inc_prev = 0; static int num_args = 0; void init_cfg_parse(void) { config_include_stack = NULL; inc_depth = 0; inc_prev = 0; num_args = 0; } static void config_start_include(const char* filename) { FILE *input; struct inc_state* s; char* nm; if(inc_depth++ > 100000) { ub_c_error_msg("too many include files"); return; } if(strlen(filename) == 0) { ub_c_error_msg("empty include file name"); return; } s = (struct inc_state*)malloc(sizeof(*s)); if(!s) { ub_c_error_msg("include %s: malloc failure", filename); return; } if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot, strlen(cfg_parser->chroot)) == 0) { filename += strlen(cfg_parser->chroot); } nm = strdup(filename); if(!nm) { ub_c_error_msg("include %s: strdup failure", filename); free(s); return; } input = fopen(filename, "r"); if(!input) { ub_c_error_msg("cannot open include file '%s': %s", filename, strerror(errno)); free(s); free(nm); return; } LEXOUT(("switch_to_include_file(%s)\n", filename)); s->filename = cfg_parser->filename; s->line = cfg_parser->line; s->buffer = YY_CURRENT_BUFFER; s->next = config_include_stack; config_include_stack = s; cfg_parser->filename = nm; cfg_parser->line = 1; yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); } static void config_start_include_glob(const char* filename) { /* check for wildcards */ #ifdef HAVE_GLOB glob_t g; size_t i; int r, flags; if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && !strchr(filename, '{') && !strchr(filename, '~'))) { flags = 0 #ifdef GLOB_ERR | GLOB_ERR #endif #ifdef GLOB_NOSORT | GLOB_NOSORT #endif #ifdef GLOB_BRACE | GLOB_BRACE #endif #ifdef GLOB_TILDE | GLOB_TILDE #endif ; memset(&g, 0, sizeof(g)); if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot, strlen(cfg_parser->chroot)) == 0) { filename += strlen(cfg_parser->chroot); } r = glob(filename, flags, NULL, &g); if(r) { /* some error */ globfree(&g); if(r == GLOB_NOMATCH) return; /* no matches for pattern */ config_start_include(filename); /* let original deal with it */ return; } /* process files found, if any */ for(i=0; i<(size_t)g.gl_pathc; i++) { config_start_include(g.gl_pathv[i]); } globfree(&g); return; } #endif /* HAVE_GLOB */ config_start_include(filename); } static void config_end_include(void) { struct inc_state* s = config_include_stack; --inc_depth; if(!s) return; free(cfg_parser->filename); cfg_parser->filename = s->filename; cfg_parser->line = s->line; yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(s->buffer); config_include_stack = s->next; free(s); } #ifndef yy_set_bol /* compat definition, for flex 2.4.6 */ #define yy_set_bol(at_bol) \ { \ if ( ! yy_current_buffer ) \ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ yy_current_buffer->yy_ch_buf[0] = ((at_bol)?'\n':' '); \ } #endif %} %option noinput %option nounput %{ #ifndef YY_NO_UNPUT #define YY_NO_UNPUT 1 #endif #ifndef YY_NO_INPUT #define YY_NO_INPUT 1 #endif %} SPACE [ \t] LETTER [a-zA-Z] UNQUOTEDLETTER [^\'\"\n\r \t\\]|\\. UNQUOTEDLETTER_NOCOLON [^\:\'\"\n\r \t\\]|\\. NEWLINE [\r\n] COMMENT \# COLON \: DQANY [^\"\n\r\\]|\\. SQANY [^\'\n\r\\]|\\. %x quotedstring singlequotedstr include include_quoted val %% {SPACE}* { LEXOUT(("SP ")); /* ignore */ } {SPACE}*{COMMENT}.* { /* note that flex makes the longest match and '.' is any but not nl */ LEXOUT(("comment(%s) ", yytext)); /* ignore */ } server{COLON} { YDVAR(0, VAR_SERVER) } qname-minimisation{COLON} { YDVAR(1, VAR_QNAME_MINIMISATION) } num-threads{COLON} { YDVAR(1, VAR_NUM_THREADS) } verbosity{COLON} { YDVAR(1, VAR_VERBOSITY) } port{COLON} { YDVAR(1, VAR_PORT) } outgoing-range{COLON} { YDVAR(1, VAR_OUTGOING_RANGE) } outgoing-port-permit{COLON} { YDVAR(1, VAR_OUTGOING_PORT_PERMIT) } outgoing-port-avoid{COLON} { YDVAR(1, VAR_OUTGOING_PORT_AVOID) } outgoing-num-tcp{COLON} { YDVAR(1, VAR_OUTGOING_NUM_TCP) } incoming-num-tcp{COLON} { YDVAR(1, VAR_INCOMING_NUM_TCP) } do-ip4{COLON} { YDVAR(1, VAR_DO_IP4) } do-ip6{COLON} { YDVAR(1, VAR_DO_IP6) } do-udp{COLON} { YDVAR(1, VAR_DO_UDP) } do-tcp{COLON} { YDVAR(1, VAR_DO_TCP) } tcp-upstream{COLON} { YDVAR(1, VAR_TCP_UPSTREAM) } ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) } ssl-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) } ssl-service-pem{COLON} { YDVAR(1, VAR_SSL_SERVICE_PEM) } ssl-port{COLON} { YDVAR(1, VAR_SSL_PORT) } do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) } interface{COLON} { YDVAR(1, VAR_INTERFACE) } ip-address{COLON} { YDVAR(1, VAR_INTERFACE) } outgoing-interface{COLON} { YDVAR(1, VAR_OUTGOING_INTERFACE) } interface-automatic{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC) } so-rcvbuf{COLON} { YDVAR(1, VAR_SO_RCVBUF) } so-sndbuf{COLON} { YDVAR(1, VAR_SO_SNDBUF) } so-reuseport{COLON} { YDVAR(1, VAR_SO_REUSEPORT) } ip-transparent{COLON} { YDVAR(1, VAR_IP_TRANSPARENT) } chroot{COLON} { YDVAR(1, VAR_CHROOT) } username{COLON} { YDVAR(1, VAR_USERNAME) } directory{COLON} { YDVAR(1, VAR_DIRECTORY) } logfile{COLON} { YDVAR(1, VAR_LOGFILE) } pidfile{COLON} { YDVAR(1, VAR_PIDFILE) } root-hints{COLON} { YDVAR(1, VAR_ROOT_HINTS) } edns-buffer-size{COLON} { YDVAR(1, VAR_EDNS_BUFFER_SIZE) } msg-buffer-size{COLON} { YDVAR(1, VAR_MSG_BUFFER_SIZE) } msg-cache-size{COLON} { YDVAR(1, VAR_MSG_CACHE_SIZE) } msg-cache-slabs{COLON} { YDVAR(1, VAR_MSG_CACHE_SLABS) } rrset-cache-size{COLON} { YDVAR(1, VAR_RRSET_CACHE_SIZE) } rrset-cache-slabs{COLON} { YDVAR(1, VAR_RRSET_CACHE_SLABS) } cache-max-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_TTL) } cache-max-negative-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_NEGATIVE_TTL) } cache-min-ttl{COLON} { YDVAR(1, VAR_CACHE_MIN_TTL) } infra-host-ttl{COLON} { YDVAR(1, VAR_INFRA_HOST_TTL) } infra-lame-ttl{COLON} { YDVAR(1, VAR_INFRA_LAME_TTL) } infra-cache-slabs{COLON} { YDVAR(1, VAR_INFRA_CACHE_SLABS) } infra-cache-numhosts{COLON} { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) } infra-cache-lame-size{COLON} { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) } infra-cache-min-rtt{COLON} { YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) } num-queries-per-thread{COLON} { YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) } jostle-timeout{COLON} { YDVAR(1, VAR_JOSTLE_TIMEOUT) } delay-close{COLON} { YDVAR(1, VAR_DELAY_CLOSE) } target-fetch-policy{COLON} { YDVAR(1, VAR_TARGET_FETCH_POLICY) } harden-short-bufsize{COLON} { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) } harden-large-queries{COLON} { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) } harden-glue{COLON} { YDVAR(1, VAR_HARDEN_GLUE) } harden-dnssec-stripped{COLON} { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) } harden-below-nxdomain{COLON} { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) } harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) } 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) } private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } prefetch{COLON} { YDVAR(1, VAR_PREFETCH) } stub-zone{COLON} { YDVAR(0, VAR_STUB_ZONE) } name{COLON} { YDVAR(1, VAR_NAME) } stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) } stub-host{COLON} { YDVAR(1, VAR_STUB_HOST) } stub-prime{COLON} { YDVAR(1, VAR_STUB_PRIME) } stub-first{COLON} { YDVAR(1, VAR_STUB_FIRST) } forward-zone{COLON} { YDVAR(0, VAR_FORWARD_ZONE) } forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) } forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) } forward-first{COLON} { YDVAR(1, VAR_FORWARD_FIRST) } do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) } do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) } access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) } hide-identity{COLON} { YDVAR(1, VAR_HIDE_IDENTITY) } hide-version{COLON} { YDVAR(1, VAR_HIDE_VERSION) } identity{COLON} { YDVAR(1, VAR_IDENTITY) } version{COLON} { YDVAR(1, VAR_VERSION) } module-config{COLON} { YDVAR(1, VAR_MODULE_CONF) } dlv-anchor{COLON} { YDVAR(1, VAR_DLV_ANCHOR) } dlv-anchor-file{COLON} { YDVAR(1, VAR_DLV_ANCHOR_FILE) } trust-anchor-file{COLON} { YDVAR(1, VAR_TRUST_ANCHOR_FILE) } auto-trust-anchor-file{COLON} { YDVAR(1, VAR_AUTO_TRUST_ANCHOR_FILE) } trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) } trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) } val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) } val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) } val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) } val-bogus-ttl{COLON} { YDVAR(1, VAR_BOGUS_TTL) } val-clean-additional{COLON} { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) } val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) } ignore-cd-flag{COLON} { YDVAR(1, VAR_IGNORE_CD_FLAG) } val-log-level{COLON} { YDVAR(1, VAR_VAL_LOG_LEVEL) } key-cache-size{COLON} { YDVAR(1, VAR_KEY_CACHE_SIZE) } key-cache-slabs{COLON} { YDVAR(1, VAR_KEY_CACHE_SLABS) } neg-cache-size{COLON} { YDVAR(1, VAR_NEG_CACHE_SIZE) } val-nsec3-keysize-iterations{COLON} { YDVAR(1, VAR_VAL_NSEC3_KEYSIZE_ITERATIONS) } add-holddown{COLON} { YDVAR(1, VAR_ADD_HOLDDOWN) } del-holddown{COLON} { YDVAR(1, VAR_DEL_HOLDDOWN) } keep-missing{COLON} { YDVAR(1, VAR_KEEP_MISSING) } permit-small-holddown{COLON} { YDVAR(1, VAR_PERMIT_SMALL_HOLDDOWN) } use-syslog{COLON} { YDVAR(1, VAR_USE_SYSLOG) } log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) } log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) } local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) } local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) } local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) } unblock-lan-zones{COLON} { YDVAR(1, VAR_UNBLOCK_LAN_ZONES) } +insecure-lan-zones{COLON} { YDVAR(1, VAR_INSECURE_LAN_ZONES) } statistics-interval{COLON} { YDVAR(1, VAR_STATISTICS_INTERVAL) } statistics-cumulative{COLON} { YDVAR(1, VAR_STATISTICS_CUMULATIVE) } extended-statistics{COLON} { YDVAR(1, VAR_EXTENDED_STATISTICS) } remote-control{COLON} { YDVAR(0, VAR_REMOTE_CONTROL) } control-enable{COLON} { YDVAR(1, VAR_CONTROL_ENABLE) } control-interface{COLON} { YDVAR(1, VAR_CONTROL_INTERFACE) } control-port{COLON} { YDVAR(1, VAR_CONTROL_PORT) } control-use-cert{COLON} { YDVAR(1, VAR_CONTROL_USE_CERT) } server-key-file{COLON} { YDVAR(1, VAR_SERVER_KEY_FILE) } server-cert-file{COLON} { YDVAR(1, VAR_SERVER_CERT_FILE) } control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) } control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_FILE) } python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) } python{COLON} { YDVAR(0, VAR_PYTHON) } domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) } minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) } rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) } max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) } dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) } dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) } dnstap{COLON} { YDVAR(0, VAR_DNSTAP) } dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) } dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } dnstap-send-identity{COLON} { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } dnstap-send-version{COLON} { YDVAR(1, VAR_DNSTAP_SEND_VERSION) } dnstap-identity{COLON} { YDVAR(1, VAR_DNSTAP_IDENTITY) } dnstap-version{COLON} { YDVAR(1, VAR_DNSTAP_VERSION) } dnstap-log-resolver-query-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) } dnstap-log-resolver-response-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) } dnstap-log-client-query-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) } dnstap-log-client-response-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) } 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) } ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) } ratelimit-slabs{COLON} { YDVAR(1, VAR_RATELIMIT_SLABS) } ratelimit-size{COLON} { YDVAR(1, VAR_RATELIMIT_SIZE) } ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) } {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } /* Quoted strings. Strip leading and ending quotes */ \" { BEGIN(quotedstring); LEXOUT(("QS ")); } <> { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } {DQANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); } {NEWLINE} { yyerror("newline inside quoted string, no end \""); cfg_parser->line++; BEGIN(INITIAL); } \" { LEXOUT(("QE ")); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } yytext[yyleng - 1] = '\0'; yylval.str = strdup(yytext); if(!yylval.str) yyerror("out of memory"); return STRING_ARG; } /* Single Quoted strings. Strip leading and ending quotes */ \' { BEGIN(singlequotedstr); LEXOUT(("SQS ")); } <> { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } {SQANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); } {NEWLINE} { yyerror("newline inside quoted string, no end '"); cfg_parser->line++; BEGIN(INITIAL); } \' { LEXOUT(("SQE ")); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } yytext[yyleng - 1] = '\0'; yylval.str = strdup(yytext); if(!yylval.str) yyerror("out of memory"); return STRING_ARG; } /* include: directive */ include{COLON} { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include); } <> { yyerror("EOF inside include directive"); BEGIN(inc_prev); } {SPACE}* { LEXOUT(("ISP ")); /* ignore */ } {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} \" { LEXOUT(("IQS ")); BEGIN(include_quoted); } {UNQUOTEDLETTER}* { LEXOUT(("Iunquotedstr(%s) ", yytext)); config_start_include_glob(yytext); BEGIN(inc_prev); } <> { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } {DQANY}* { LEXOUT(("ISTR(%s) ", yytext)); yymore(); } {NEWLINE} { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } \" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; config_start_include_glob(yytext); BEGIN(inc_prev); } <> { LEXOUT(("LEXEOF ")); yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ if (!config_include_stack) { yyterminate(); } else { fclose(yyin); config_end_include(); } } {UNQUOTEDLETTER}* { LEXOUT(("unquotedstr(%s) ", yytext)); if(--num_args == 0) { BEGIN(INITIAL); } yylval.str = strdup(yytext); return STRING_ARG; } {UNQUOTEDLETTER_NOCOLON}* { ub_c_error_msg("unknown keyword '%s'", yytext); } <*>. { ub_c_error_msg("stray '%s'", yytext); } %% Index: vendor/unbound/dist/util/configparser.y =================================================================== --- vendor/unbound/dist/util/configparser.y (revision 295529) +++ vendor/unbound/dist/util/configparser.y (revision 295530) @@ -1,1616 +1,1628 @@ /* * configparser.y -- yacc grammar for unbound configuration files * * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. * * Copyright (c) 2007, 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. */ %{ #include "config.h" #include #include #include #include #include #include "util/configyyrename.h" #include "util/config_file.h" #include "util/net_help.h" int ub_c_lex(void); void ub_c_error(const char *message); /* these need to be global, otherwise they cannot be used inside yacc */ extern struct config_parser_state* cfg_parser; #if 0 #define OUTYY(s) printf s /* used ONLY when debugging */ #else #define OUTYY(s) #endif %} %union { char* str; }; %token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR %token STRING_ARG %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT %token VAR_OUTGOING_RANGE VAR_INTERFACE %token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP %token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE %token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD %token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP %token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS %token VAR_INFRA_CACHE_NUMHOSTS VAR_INFRA_CACHE_LAME_SIZE VAR_NAME %token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY %token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES %token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR %token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION %token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF %token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE %token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE %token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE %token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE %token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG %token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST %token VAR_CACHE_MAX_TTL VAR_HARDEN_DNSSEC_STRIPPED VAR_ACCESS_CONTROL %token VAR_LOCAL_ZONE VAR_LOCAL_DATA VAR_INTERFACE_AUTOMATIC %token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID %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 %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 %token VAR_CONTROL_USE_CERT %token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT %token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII %token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN %token VAR_VAL_SIG_SKEW_MAX VAR_CACHE_MIN_TTL VAR_VAL_LOG_LEVEL %token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN %token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH %token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN %token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST %token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN -%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES +%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE +%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES %token VAR_INFRA_CACHE_MIN_RTT %token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL %token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH %token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION %token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION %token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES %token VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES %token VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT %token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR %token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN %token VAR_QNAME_MINIMISATION %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvar: serverstart contents_server | stubstart contents_stub | forwardstart contents_forward | pythonstart contents_py | rcstart contents_rc | dtstart contents_dt ; /* server: declaration */ serverstart: VAR_SERVER { OUTYY(("\nP(server:)\n")); } ; contents_server: contents_server content_server | ; content_server: server_num_threads | server_verbosity | server_port | server_outgoing_range | server_do_ip4 | server_do_ip6 | server_do_udp | server_do_tcp | server_interface | server_chroot | server_username | server_directory | server_logfile | server_pidfile | server_msg_cache_size | server_msg_cache_slabs | server_num_queries_per_thread | server_rrset_cache_size | server_rrset_cache_slabs | server_outgoing_num_tcp | server_infra_host_ttl | server_infra_lame_ttl | server_infra_cache_slabs | server_infra_cache_numhosts | server_infra_cache_lame_size | server_target_fetch_policy | server_harden_short_bufsize | server_harden_large_queries | server_do_not_query_address | server_hide_identity | server_hide_version | server_identity | server_version | server_harden_glue | server_module_conf | server_trust_anchor_file | server_trust_anchor | server_val_override_date | server_bogus_ttl | server_val_clean_additional | server_val_permissive_mode | server_incoming_num_tcp | server_msg_buffer_size | server_key_cache_size | server_key_cache_slabs | server_trusted_keys_file | server_val_nsec3_keysize_iterations | server_use_syslog | server_outgoing_interface | server_root_hints | server_do_not_query_localhost | server_cache_max_ttl | server_harden_dnssec_stripped | server_access_control | server_local_zone | server_local_data | server_interface_automatic | server_statistics_interval | server_do_daemonize | server_use_caps_for_id | server_statistics_cumulative | server_outgoing_port_permit | server_outgoing_port_avoid | server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size | server_harden_referral_path | server_private_address | server_private_domain | server_extended_statistics | server_local_data_ptr | server_jostle_timeout | server_unwanted_reply_threshold | server_log_time_ascii | server_domain_insecure | server_val_sig_skew_min | server_val_sig_skew_max | server_cache_min_ttl | server_val_log_level | server_auto_trust_anchor_file | server_add_holddown | server_del_holddown | server_keep_missing | server_so_rcvbuf | server_edns_buffer_size | server_prefetch | server_prefetch_key | server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag | server_log_queries | server_tcp_upstream | server_ssl_upstream | server_ssl_service_key | server_ssl_service_pem | server_ssl_port | server_minimal_responses | server_rrset_roundrobin | server_max_udp_size | - server_so_reuseport | server_delay_close | server_unblock_lan_zones | + server_so_reuseport | server_delay_close | + server_unblock_lan_zones | server_insecure_lan_zones | server_dns64_prefix | server_dns64_synthall | server_infra_cache_min_rtt | server_harden_algo_downgrade | server_ip_transparent | server_ratelimit | server_ratelimit_slabs | server_ratelimit_size | server_ratelimit_for_domain | server_ratelimit_below_domain | server_ratelimit_factor | server_caps_whitelist | server_cache_max_negative_ttl | server_permit_small_holddown | server_qname_minimisation ; stubstart: VAR_STUB_ZONE { struct config_stub* s; OUTYY(("\nP(stub_zone:)\n")); s = (struct config_stub*)calloc(1, sizeof(struct config_stub)); if(s) { s->next = cfg_parser->cfg->stubs; cfg_parser->cfg->stubs = s; } else yyerror("out of memory"); } ; contents_stub: contents_stub content_stub | ; content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first ; forwardstart: VAR_FORWARD_ZONE { struct config_stub* s; OUTYY(("\nP(forward_zone:)\n")); s = (struct config_stub*)calloc(1, sizeof(struct config_stub)); if(s) { s->next = cfg_parser->cfg->forwards; cfg_parser->cfg->forwards = s; } else yyerror("out of memory"); } ; contents_forward: contents_forward content_forward | ; content_forward: forward_name | forward_host | forward_addr | forward_first ; server_num_threads: VAR_NUM_THREADS STRING_ARG { OUTYY(("P(server_num_threads:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->num_threads = atoi($2); free($2); } ; server_verbosity: VAR_VERBOSITY STRING_ARG { OUTYY(("P(server_verbosity:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->verbosity = atoi($2); free($2); } ; server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG { OUTYY(("P(server_statistics_interval:%s)\n", $2)); if(strcmp($2, "") == 0 || strcmp($2, "0") == 0) cfg_parser->cfg->stat_interval = 0; else if(atoi($2) == 0) yyerror("number expected"); else cfg_parser->cfg->stat_interval = atoi($2); free($2); } ; server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG { OUTYY(("P(server_statistics_cumulative:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->stat_cumulative = (strcmp($2, "yes")==0); free($2); } ; server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG { OUTYY(("P(server_extended_statistics:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->stat_extended = (strcmp($2, "yes")==0); free($2); } ; server_port: VAR_PORT STRING_ARG { OUTYY(("P(server_port:%s)\n", $2)); if(atoi($2) == 0) yyerror("port number expected"); else cfg_parser->cfg->port = atoi($2); free($2); } ; server_interface: VAR_INTERFACE STRING_ARG { OUTYY(("P(server_interface:%s)\n", $2)); if(cfg_parser->cfg->num_ifs == 0) cfg_parser->cfg->ifs = calloc(1, sizeof(char*)); else cfg_parser->cfg->ifs = realloc(cfg_parser->cfg->ifs, (cfg_parser->cfg->num_ifs+1)*sizeof(char*)); if(!cfg_parser->cfg->ifs) yyerror("out of memory"); else cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2; } ; server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG { OUTYY(("P(server_outgoing_interface:%s)\n", $2)); if(cfg_parser->cfg->num_out_ifs == 0) cfg_parser->cfg->out_ifs = calloc(1, sizeof(char*)); else cfg_parser->cfg->out_ifs = realloc( cfg_parser->cfg->out_ifs, (cfg_parser->cfg->num_out_ifs+1)*sizeof(char*)); if(!cfg_parser->cfg->out_ifs) yyerror("out of memory"); else cfg_parser->cfg->out_ifs[ cfg_parser->cfg->num_out_ifs++] = $2; } ; server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG { OUTYY(("P(server_outgoing_range:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else cfg_parser->cfg->outgoing_num_ports = atoi($2); free($2); } ; server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG { OUTYY(("P(server_outgoing_port_permit:%s)\n", $2)); if(!cfg_mark_ports($2, 1, cfg_parser->cfg->outgoing_avail_ports, 65536)) yyerror("port number or range (\"low-high\") expected"); free($2); } ; server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG { OUTYY(("P(server_outgoing_port_avoid:%s)\n", $2)); if(!cfg_mark_ports($2, 0, cfg_parser->cfg->outgoing_avail_ports, 65536)) yyerror("port number or range (\"low-high\") expected"); free($2); } ; server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG { OUTYY(("P(server_outgoing_num_tcp:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->outgoing_num_tcp = atoi($2); free($2); } ; server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG { OUTYY(("P(server_incoming_num_tcp:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->incoming_num_tcp = atoi($2); free($2); } ; server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG { OUTYY(("P(server_interface_automatic:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->if_automatic = (strcmp($2, "yes")==0); free($2); } ; server_do_ip4: VAR_DO_IP4 STRING_ARG { OUTYY(("P(server_do_ip4:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->do_ip4 = (strcmp($2, "yes")==0); free($2); } ; server_do_ip6: VAR_DO_IP6 STRING_ARG { OUTYY(("P(server_do_ip6:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->do_ip6 = (strcmp($2, "yes")==0); free($2); } ; server_do_udp: VAR_DO_UDP STRING_ARG { OUTYY(("P(server_do_udp:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->do_udp = (strcmp($2, "yes")==0); free($2); } ; server_do_tcp: VAR_DO_TCP STRING_ARG { OUTYY(("P(server_do_tcp:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->do_tcp = (strcmp($2, "yes")==0); free($2); } ; server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG { OUTYY(("P(server_tcp_upstream:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->tcp_upstream = (strcmp($2, "yes")==0); free($2); } ; server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG { OUTYY(("P(server_ssl_upstream:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->ssl_upstream = (strcmp($2, "yes")==0); free($2); } ; server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG { OUTYY(("P(server_ssl_service_key:%s)\n", $2)); free(cfg_parser->cfg->ssl_service_key); cfg_parser->cfg->ssl_service_key = $2; } ; server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG { OUTYY(("P(server_ssl_service_pem:%s)\n", $2)); free(cfg_parser->cfg->ssl_service_pem); cfg_parser->cfg->ssl_service_pem = $2; } ; server_ssl_port: VAR_SSL_PORT STRING_ARG { OUTYY(("P(server_ssl_port:%s)\n", $2)); if(atoi($2) == 0) yyerror("port number expected"); else cfg_parser->cfg->ssl_port = atoi($2); free($2); } ; server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG { OUTYY(("P(server_do_daemonize:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->do_daemonize = (strcmp($2, "yes")==0); free($2); } ; server_use_syslog: VAR_USE_SYSLOG STRING_ARG { OUTYY(("P(server_use_syslog:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0); #if !defined(HAVE_SYSLOG_H) && !defined(UB_ON_WINDOWS) if(strcmp($2, "yes") == 0) yyerror("no syslog services are available. " "(reconfigure and compile to add)"); #endif free($2); } ; server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG { OUTYY(("P(server_log_time_ascii:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->log_time_ascii = (strcmp($2, "yes")==0); free($2); } ; server_log_queries: VAR_LOG_QUERIES STRING_ARG { OUTYY(("P(server_log_queries:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->log_queries = (strcmp($2, "yes")==0); free($2); } ; server_chroot: VAR_CHROOT STRING_ARG { OUTYY(("P(server_chroot:%s)\n", $2)); free(cfg_parser->cfg->chrootdir); cfg_parser->cfg->chrootdir = $2; } ; server_username: VAR_USERNAME STRING_ARG { OUTYY(("P(server_username:%s)\n", $2)); free(cfg_parser->cfg->username); cfg_parser->cfg->username = $2; } ; server_directory: VAR_DIRECTORY STRING_ARG { OUTYY(("P(server_directory:%s)\n", $2)); free(cfg_parser->cfg->directory); cfg_parser->cfg->directory = $2; } ; server_logfile: VAR_LOGFILE STRING_ARG { OUTYY(("P(server_logfile:%s)\n", $2)); free(cfg_parser->cfg->logfile); cfg_parser->cfg->logfile = $2; cfg_parser->cfg->use_syslog = 0; } ; server_pidfile: VAR_PIDFILE STRING_ARG { OUTYY(("P(server_pidfile:%s)\n", $2)); free(cfg_parser->cfg->pidfile); cfg_parser->cfg->pidfile = $2; } ; server_root_hints: VAR_ROOT_HINTS STRING_ARG { OUTYY(("P(server_root_hints:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, $2)) yyerror("out of memory"); } ; server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG { OUTYY(("P(server_dlv_anchor_file:%s)\n", $2)); free(cfg_parser->cfg->dlv_anchor_file); cfg_parser->cfg->dlv_anchor_file = $2; } ; server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG { OUTYY(("P(server_dlv_anchor:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, $2)) yyerror("out of memory"); } ; server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG { OUTYY(("P(server_auto_trust_anchor_file:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg-> auto_trust_anchor_file_list, $2)) yyerror("out of memory"); } ; server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG { OUTYY(("P(server_trust_anchor_file:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg-> trust_anchor_file_list, $2)) yyerror("out of memory"); } ; server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG { OUTYY(("P(server_trusted_keys_file:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg-> trusted_keys_file_list, $2)) yyerror("out of memory"); } ; server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG { OUTYY(("P(server_trust_anchor:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, $2)) yyerror("out of memory"); } ; server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG { OUTYY(("P(server_domain_insecure:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, $2)) yyerror("out of memory"); } ; server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG { OUTYY(("P(server_hide_identity:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->hide_identity = (strcmp($2, "yes")==0); free($2); } ; server_hide_version: VAR_HIDE_VERSION STRING_ARG { OUTYY(("P(server_hide_version:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->hide_version = (strcmp($2, "yes")==0); free($2); } ; server_identity: VAR_IDENTITY STRING_ARG { OUTYY(("P(server_identity:%s)\n", $2)); free(cfg_parser->cfg->identity); cfg_parser->cfg->identity = $2; } ; server_version: VAR_VERSION STRING_ARG { OUTYY(("P(server_version:%s)\n", $2)); free(cfg_parser->cfg->version); cfg_parser->cfg->version = $2; } ; server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG { OUTYY(("P(server_so_rcvbuf:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_rcvbuf)) yyerror("buffer size expected"); free($2); } ; server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG { OUTYY(("P(server_so_sndbuf:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_sndbuf)) yyerror("buffer size expected"); free($2); } ; server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG { OUTYY(("P(server_so_reuseport:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->so_reuseport = (strcmp($2, "yes")==0); free($2); } ; server_ip_transparent: VAR_IP_TRANSPARENT STRING_ARG { OUTYY(("P(server_ip_transparent:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->ip_transparent = (strcmp($2, "yes")==0); free($2); } ; server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG { OUTYY(("P(server_edns_buffer_size:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else if (atoi($2) < 12) yyerror("edns buffer size too small"); else if (atoi($2) > 65535) cfg_parser->cfg->edns_buffer_size = 65535; else cfg_parser->cfg->edns_buffer_size = atoi($2); free($2); } ; server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG { OUTYY(("P(server_msg_buffer_size:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else if (atoi($2) < 4096) yyerror("message buffer size too small (use 4096)"); else cfg_parser->cfg->msg_buffer_size = atoi($2); free($2); } ; server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG { OUTYY(("P(server_msg_cache_size:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->msg_cache_size)) yyerror("memory size expected"); free($2); } ; server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG { OUTYY(("P(server_msg_cache_slabs:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else { cfg_parser->cfg->msg_cache_slabs = atoi($2); if(!is_pow2(cfg_parser->cfg->msg_cache_slabs)) yyerror("must be a power of 2"); } free($2); } ; server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG { OUTYY(("P(server_num_queries_per_thread:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else cfg_parser->cfg->num_queries_per_thread = atoi($2); free($2); } ; server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG { OUTYY(("P(server_jostle_timeout:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->jostle_time = atoi($2); free($2); } ; server_delay_close: VAR_DELAY_CLOSE STRING_ARG { OUTYY(("P(server_delay_close:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->delay_close = atoi($2); free($2); } ; server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG { OUTYY(("P(server_unblock_lan_zones:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->unblock_lan_zones = + (strcmp($2, "yes")==0); + free($2); + } + ; +server_insecure_lan_zones: VAR_INSECURE_LAN_ZONES STRING_ARG + { + OUTYY(("P(server_insecure_lan_zones:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->insecure_lan_zones = (strcmp($2, "yes")==0); free($2); } ; server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG { OUTYY(("P(server_rrset_cache_size:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->rrset_cache_size)) yyerror("memory size expected"); free($2); } ; server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG { OUTYY(("P(server_rrset_cache_slabs:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else { cfg_parser->cfg->rrset_cache_slabs = atoi($2); if(!is_pow2(cfg_parser->cfg->rrset_cache_slabs)) yyerror("must be a power of 2"); } free($2); } ; server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG { OUTYY(("P(server_infra_host_ttl:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->host_ttl = atoi($2); free($2); } ; server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG { OUTYY(("P(server_infra_lame_ttl:%s)\n", $2)); verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option " "removed, use infra-host-ttl)", $2); free($2); } ; server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG { OUTYY(("P(server_infra_cache_numhosts:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else cfg_parser->cfg->infra_cache_numhosts = atoi($2); free($2); } ; server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG { OUTYY(("P(server_infra_cache_lame_size:%s)\n", $2)); verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s " "(option removed, use infra-cache-numhosts)", $2); free($2); } ; server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG { OUTYY(("P(server_infra_cache_slabs:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else { cfg_parser->cfg->infra_cache_slabs = atoi($2); if(!is_pow2(cfg_parser->cfg->infra_cache_slabs)) yyerror("must be a power of 2"); } free($2); } ; server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG { OUTYY(("P(server_infra_cache_min_rtt:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->infra_cache_min_rtt = atoi($2); free($2); } ; server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG { OUTYY(("P(server_target_fetch_policy:%s)\n", $2)); free(cfg_parser->cfg->target_fetch_policy); cfg_parser->cfg->target_fetch_policy = $2; } ; server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG { OUTYY(("P(server_harden_short_bufsize:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_short_bufsize = (strcmp($2, "yes")==0); free($2); } ; server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG { OUTYY(("P(server_harden_large_queries:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_large_queries = (strcmp($2, "yes")==0); free($2); } ; server_harden_glue: VAR_HARDEN_GLUE STRING_ARG { OUTYY(("P(server_harden_glue:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_glue = (strcmp($2, "yes")==0); free($2); } ; server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG { OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_dnssec_stripped = (strcmp($2, "yes")==0); free($2); } ; server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG { OUTYY(("P(server_harden_below_nxdomain:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_below_nxdomain = (strcmp($2, "yes")==0); free($2); } ; server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG { OUTYY(("P(server_harden_referral_path:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_referral_path = (strcmp($2, "yes")==0); free($2); } ; server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG { OUTYY(("P(server_harden_algo_downgrade:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->harden_algo_downgrade = (strcmp($2, "yes")==0); free($2); } ; server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG { OUTYY(("P(server_use_caps_for_id:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->use_caps_bits_for_id = (strcmp($2, "yes")==0); free($2); } ; server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG { OUTYY(("P(server_caps_whitelist:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2)) yyerror("out of memory"); } ; server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG { OUTYY(("P(server_private_address:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, $2)) yyerror("out of memory"); } ; server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG { OUTYY(("P(server_private_domain:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, $2)) yyerror("out of memory"); } ; server_prefetch: VAR_PREFETCH STRING_ARG { OUTYY(("P(server_prefetch:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->prefetch = (strcmp($2, "yes")==0); free($2); } ; server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG { OUTYY(("P(server_prefetch_key:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->prefetch_key = (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)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->unwanted_threshold = atoi($2); free($2); } ; server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG { OUTYY(("P(server_do_not_query_address:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, $2)) yyerror("out of memory"); } ; server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG { OUTYY(("P(server_do_not_query_localhost:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->donotquery_localhost = (strcmp($2, "yes")==0); free($2); } ; server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG { OUTYY(("P(server_access_control:%s %s)\n", $2, $3)); if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 && strcmp($3, "deny_non_local")!=0 && strcmp($3, "refuse_non_local")!=0 && strcmp($3, "allow")!=0 && strcmp($3, "allow_snoop")!=0) { yyerror("expected deny, refuse, deny_non_local, " "refuse_non_local, allow or allow_snoop " "in access control action"); } else { if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3)) fatal_exit("out of memory adding acl"); } } ; server_module_conf: VAR_MODULE_CONF STRING_ARG { OUTYY(("P(server_module_conf:%s)\n", $2)); free(cfg_parser->cfg->module_conf); cfg_parser->cfg->module_conf = $2; } ; server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG { OUTYY(("P(server_val_override_date:%s)\n", $2)); if(strlen($2) == 0 || strcmp($2, "0") == 0) { cfg_parser->cfg->val_date_override = 0; } else if(strlen($2) == 14) { cfg_parser->cfg->val_date_override = cfg_convert_timeval($2); if(!cfg_parser->cfg->val_date_override) yyerror("bad date/time specification"); } else { if(atoi($2) == 0) yyerror("number expected"); cfg_parser->cfg->val_date_override = atoi($2); } free($2); } ; server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG { OUTYY(("P(server_val_sig_skew_min:%s)\n", $2)); if(strlen($2) == 0 || strcmp($2, "0") == 0) { cfg_parser->cfg->val_sig_skew_min = 0; } else { cfg_parser->cfg->val_sig_skew_min = atoi($2); if(!cfg_parser->cfg->val_sig_skew_min) yyerror("number expected"); } free($2); } ; server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG { OUTYY(("P(server_val_sig_skew_max:%s)\n", $2)); if(strlen($2) == 0 || strcmp($2, "0") == 0) { cfg_parser->cfg->val_sig_skew_max = 0; } else { cfg_parser->cfg->val_sig_skew_max = atoi($2); if(!cfg_parser->cfg->val_sig_skew_max) yyerror("number expected"); } free($2); } ; server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG { OUTYY(("P(server_cache_max_ttl:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->max_ttl = atoi($2); free($2); } ; server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG { OUTYY(("P(server_cache_max_negative_ttl:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->max_negative_ttl = atoi($2); free($2); } ; server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG { OUTYY(("P(server_cache_min_ttl:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->min_ttl = atoi($2); free($2); } ; server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG { OUTYY(("P(server_bogus_ttl:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->bogus_ttl = atoi($2); free($2); } ; server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG { OUTYY(("P(server_val_clean_additional:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->val_clean_additional = (strcmp($2, "yes")==0); free($2); } ; server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG { OUTYY(("P(server_val_permissive_mode:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->val_permissive_mode = (strcmp($2, "yes")==0); free($2); } ; server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG { OUTYY(("P(server_ignore_cd_flag:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->ignore_cd = (strcmp($2, "yes")==0); free($2); } ; server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG { OUTYY(("P(server_val_log_level:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->val_log_level = atoi($2); free($2); } ; server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG { OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", $2)); free(cfg_parser->cfg->val_nsec3_key_iterations); cfg_parser->cfg->val_nsec3_key_iterations = $2; } ; server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG { OUTYY(("P(server_add_holddown:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->add_holddown = atoi($2); free($2); } ; server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG { OUTYY(("P(server_del_holddown:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->del_holddown = atoi($2); free($2); } ; server_keep_missing: VAR_KEEP_MISSING STRING_ARG { OUTYY(("P(server_keep_missing:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->keep_missing = atoi($2); free($2); } ; server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG { OUTYY(("P(server_permit_small_holddown:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->permit_small_holddown = (strcmp($2, "yes")==0); free($2); } server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG { OUTYY(("P(server_key_cache_size:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->key_cache_size)) yyerror("memory size expected"); free($2); } ; server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG { OUTYY(("P(server_key_cache_slabs:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else { cfg_parser->cfg->key_cache_slabs = atoi($2); if(!is_pow2(cfg_parser->cfg->key_cache_slabs)) yyerror("must be a power of 2"); } free($2); } ; server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG { OUTYY(("P(server_neg_cache_size:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->neg_cache_size)) yyerror("memory size expected"); free($2); } ; server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG { OUTYY(("P(server_local_zone:%s %s)\n", $2, $3)); if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 && strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0 && strcmp($3, "typetransparent")!=0 && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " "typetransparent, inform, inform_deny " "or nodefault"); else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, $2)) fatal_exit("out of memory adding local-zone"); free($3); } else { if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones, $2, $3)) fatal_exit("out of memory adding local-zone"); } } ; server_local_data: VAR_LOCAL_DATA STRING_ARG { OUTYY(("P(server_local_data:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2)) fatal_exit("out of memory adding local-data"); } ; server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG { char* ptr; OUTYY(("P(server_local_data_ptr:%s)\n", $2)); ptr = cfg_ptr_reverse($2); free($2); if(ptr) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_data, ptr)) fatal_exit("out of memory adding local-data"); } else { yyerror("local-data-ptr could not be reversed"); } } ; server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG { OUTYY(("P(server_minimal_responses:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->minimal_responses = (strcmp($2, "yes")==0); free($2); } ; server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG { OUTYY(("P(server_rrset_roundrobin:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->rrset_roundrobin = (strcmp($2, "yes")==0); free($2); } ; server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG { OUTYY(("P(server_max_udp_size:%s)\n", $2)); cfg_parser->cfg->max_udp_size = atoi($2); free($2); } ; server_dns64_prefix: VAR_DNS64_PREFIX STRING_ARG { OUTYY(("P(dns64_prefix:%s)\n", $2)); free(cfg_parser->cfg->dns64_prefix); cfg_parser->cfg->dns64_prefix = $2; } ; server_dns64_synthall: VAR_DNS64_SYNTHALL STRING_ARG { OUTYY(("P(server_dns64_synthall:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dns64_synthall = (strcmp($2, "yes")==0); free($2); } ; server_ratelimit: VAR_RATELIMIT STRING_ARG { OUTYY(("P(server_ratelimit:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->ratelimit = atoi($2); free($2); } ; server_ratelimit_size: VAR_RATELIMIT_SIZE STRING_ARG { OUTYY(("P(server_ratelimit_size:%s)\n", $2)); if(!cfg_parse_memsize($2, &cfg_parser->cfg->ratelimit_size)) yyerror("memory size expected"); free($2); } ; server_ratelimit_slabs: VAR_RATELIMIT_SLABS STRING_ARG { OUTYY(("P(server_ratelimit_slabs:%s)\n", $2)); if(atoi($2) == 0) yyerror("number expected"); else { cfg_parser->cfg->ratelimit_slabs = atoi($2); if(!is_pow2(cfg_parser->cfg->ratelimit_slabs)) yyerror("must be a power of 2"); } free($2); } ; server_ratelimit_for_domain: VAR_RATELIMIT_FOR_DOMAIN STRING_ARG STRING_ARG { OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", $2, $3)); if(atoi($3) == 0 && strcmp($3, "0") != 0) { yyerror("number expected"); } else { if(!cfg_str2list_insert(&cfg_parser->cfg-> ratelimit_for_domain, $2, $3)) fatal_exit("out of memory adding " "ratelimit-for-domain"); } } ; server_ratelimit_below_domain: VAR_RATELIMIT_BELOW_DOMAIN STRING_ARG STRING_ARG { OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", $2, $3)); if(atoi($3) == 0 && strcmp($3, "0") != 0) { yyerror("number expected"); } else { if(!cfg_str2list_insert(&cfg_parser->cfg-> ratelimit_below_domain, $2, $3)) fatal_exit("out of memory adding " "ratelimit-below-domain"); } } ; server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG { OUTYY(("P(server_ratelimit_factor:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->ratelimit_factor = atoi($2); free($2); } ; server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG { OUTYY(("P(server_qname_minimisation:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->qname_minimisation = (strcmp($2, "yes")==0); free($2); } ; stub_name: VAR_NAME STRING_ARG { OUTYY(("P(name:%s)\n", $2)); if(cfg_parser->cfg->stubs->name) yyerror("stub name override, there must be one name " "for one stub-zone"); free(cfg_parser->cfg->stubs->name); cfg_parser->cfg->stubs->name = $2; } ; stub_host: VAR_STUB_HOST STRING_ARG { OUTYY(("P(stub-host:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, $2)) yyerror("out of memory"); } ; stub_addr: VAR_STUB_ADDR STRING_ARG { OUTYY(("P(stub-addr:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, $2)) yyerror("out of memory"); } ; stub_first: VAR_STUB_FIRST STRING_ARG { OUTYY(("P(stub-first:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0); free($2); } ; stub_prime: VAR_STUB_PRIME STRING_ARG { OUTYY(("P(stub-prime:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->stubs->isprime = (strcmp($2, "yes")==0); free($2); } ; forward_name: VAR_NAME STRING_ARG { OUTYY(("P(name:%s)\n", $2)); if(cfg_parser->cfg->forwards->name) yyerror("forward name override, there must be one " "name for one forward-zone"); free(cfg_parser->cfg->forwards->name); cfg_parser->cfg->forwards->name = $2; } ; forward_host: VAR_FORWARD_HOST STRING_ARG { OUTYY(("P(forward-host:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, $2)) yyerror("out of memory"); } ; forward_addr: VAR_FORWARD_ADDR STRING_ARG { OUTYY(("P(forward-addr:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, $2)) yyerror("out of memory"); } ; forward_first: VAR_FORWARD_FIRST STRING_ARG { OUTYY(("P(forward-first:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0); free($2); } ; rcstart: VAR_REMOTE_CONTROL { OUTYY(("\nP(remote-control:)\n")); } ; contents_rc: contents_rc content_rc | ; content_rc: rc_control_enable | rc_control_interface | rc_control_port | rc_server_key_file | rc_server_cert_file | rc_control_key_file | rc_control_cert_file | rc_control_use_cert ; rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG { OUTYY(("P(control_enable:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->remote_control_enable = (strcmp($2, "yes")==0); free($2); } ; rc_control_port: VAR_CONTROL_PORT STRING_ARG { OUTYY(("P(control_port:%s)\n", $2)); if(atoi($2) == 0) yyerror("control port number expected"); else cfg_parser->cfg->control_port = atoi($2); free($2); } ; rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG { OUTYY(("P(control_interface:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, $2)) yyerror("out of memory"); } ; rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG { OUTYY(("P(control_use_cert:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->remote_control_use_cert = (strcmp($2, "yes")==0); free($2); } ; rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG { OUTYY(("P(rc_server_key_file:%s)\n", $2)); free(cfg_parser->cfg->server_key_file); cfg_parser->cfg->server_key_file = $2; } ; rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG { OUTYY(("P(rc_server_cert_file:%s)\n", $2)); free(cfg_parser->cfg->server_cert_file); cfg_parser->cfg->server_cert_file = $2; } ; rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG { OUTYY(("P(rc_control_key_file:%s)\n", $2)); free(cfg_parser->cfg->control_key_file); cfg_parser->cfg->control_key_file = $2; } ; rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG { OUTYY(("P(rc_control_cert_file:%s)\n", $2)); free(cfg_parser->cfg->control_cert_file); cfg_parser->cfg->control_cert_file = $2; } ; dtstart: VAR_DNSTAP { OUTYY(("\nP(dnstap:)\n")); } ; contents_dt: contents_dt content_dt | ; content_dt: dt_dnstap_enable | dt_dnstap_socket_path | dt_dnstap_send_identity | dt_dnstap_send_version | dt_dnstap_identity | dt_dnstap_version | dt_dnstap_log_resolver_query_messages | dt_dnstap_log_resolver_response_messages | dt_dnstap_log_client_query_messages | dt_dnstap_log_client_response_messages | dt_dnstap_log_forwarder_query_messages | dt_dnstap_log_forwarder_response_messages ; dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG { OUTYY(("P(dt_dnstap_enable:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0); } ; dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG { OUTYY(("P(dt_dnstap_socket_path:%s)\n", $2)); free(cfg_parser->cfg->dnstap_socket_path); cfg_parser->cfg->dnstap_socket_path = $2; } ; dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG { OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0); } ; dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG { OUTYY(("P(dt_dnstap_send_version:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0); } ; dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG { OUTYY(("P(dt_dnstap_identity:%s)\n", $2)); free(cfg_parser->cfg->dnstap_identity); cfg_parser->cfg->dnstap_identity = $2; } ; dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG { OUTYY(("P(dt_dnstap_version:%s)\n", $2)); free(cfg_parser->cfg->dnstap_version); cfg_parser->cfg->dnstap_version = $2; } ; dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_log_resolver_query_messages = (strcmp($2, "yes")==0); } ; dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_log_resolver_response_messages = (strcmp($2, "yes")==0); } ; dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_log_client_query_messages = (strcmp($2, "yes")==0); } ; dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_log_client_response_messages = (strcmp($2, "yes")==0); } ; dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_log_forwarder_query_messages = (strcmp($2, "yes")==0); } ; dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", $2)); if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_log_forwarder_response_messages = (strcmp($2, "yes")==0); } ; pythonstart: VAR_PYTHON { OUTYY(("\nP(python:)\n")); } ; contents_py: contents_py content_py | ; content_py: py_script ; py_script: VAR_PYTHON_SCRIPT STRING_ARG { OUTYY(("P(python-script:%s)\n", $2)); free(cfg_parser->cfg->python_script); cfg_parser->cfg->python_script = $2; } %% /* parse helper routines could be here */ Index: vendor/unbound/dist/validator/val_anchor.c =================================================================== --- vendor/unbound/dist/validator/val_anchor.c (revision 295529) +++ vendor/unbound/dist/validator/val_anchor.c (revision 295530) @@ -1,1262 +1,1273 @@ /* * validator/val_anchor.c - validator trust anchor storage. * * Copyright (c) 2007, 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 storage for the trust anchors for the validator. */ #include "config.h" #include #include "validator/val_anchor.h" #include "validator/val_sigcrypt.h" #include "validator/autotrust.h" #include "util/data/packed_rrset.h" #include "util/data/dname.h" #include "util/log.h" #include "util/net_help.h" #include "util/config_file.h" +#include "util/as112.h" #include "sldns/sbuffer.h" #include "sldns/rrdef.h" #include "sldns/str2wire.h" #ifdef HAVE_GLOB_H #include #endif int anchor_cmp(const void* k1, const void* k2) { int m; struct trust_anchor* n1 = (struct trust_anchor*)k1; struct trust_anchor* n2 = (struct trust_anchor*)k2; /* no need to ntohs(class) because sort order is irrelevant */ if(n1->dclass != n2->dclass) { if(n1->dclass < n2->dclass) return -1; return 1; } return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs, &m); } struct val_anchors* anchors_create(void) { struct val_anchors* a = (struct val_anchors*)calloc(1, sizeof(*a)); if(!a) return NULL; a->tree = rbtree_create(anchor_cmp); if(!a->tree) { anchors_delete(a); return NULL; } a->autr = autr_global_create(); if(!a->autr) { anchors_delete(a); return NULL; } lock_basic_init(&a->lock); lock_protect(&a->lock, a, sizeof(*a)); lock_protect(&a->lock, a->autr, sizeof(*a->autr)); return a; } /** delete assembled rrset */ static void assembled_rrset_delete(struct ub_packed_rrset_key* pkey) { if(!pkey) return; if(pkey->entry.data) { struct packed_rrset_data* pd = (struct packed_rrset_data*) pkey->entry.data; free(pd->rr_data); free(pd->rr_ttl); free(pd->rr_len); free(pd); } free(pkey->rk.dname); free(pkey); } /** destroy locks in tree and delete autotrust anchors */ static void anchors_delfunc(rbnode_t* elem, void* ATTR_UNUSED(arg)) { struct trust_anchor* ta = (struct trust_anchor*)elem; if(!ta) return; if(ta->autr) { autr_point_delete(ta); } else { struct ta_key* p, *np; lock_basic_destroy(&ta->lock); free(ta->name); p = ta->keylist; while(p) { np = p->next; free(p->data); free(p); p = np; } assembled_rrset_delete(ta->ds_rrset); assembled_rrset_delete(ta->dnskey_rrset); free(ta); } } void anchors_delete(struct val_anchors* anchors) { if(!anchors) return; lock_unprotect(&anchors->lock, anchors->autr); lock_unprotect(&anchors->lock, anchors); lock_basic_destroy(&anchors->lock); if(anchors->tree) traverse_postorder(anchors->tree, anchors_delfunc, NULL); free(anchors->tree); autr_global_delete(anchors->autr); free(anchors); } void anchors_init_parents_locked(struct val_anchors* anchors) { struct trust_anchor* node, *prev = NULL, *p; int m; /* nobody else can grab locks because we hold the main lock. * Thus the previous items, after unlocked, are not deleted */ RBTREE_FOR(node, struct trust_anchor*, anchors->tree) { lock_basic_lock(&node->lock); node->parent = NULL; if(!prev || prev->dclass != node->dclass) { prev = node; lock_basic_unlock(&node->lock); continue; } (void)dname_lab_cmp(prev->name, prev->namelabs, node->name, node->namelabs, &m); /* we know prev is smaller */ /* sort order like: . com. bla.com. zwb.com. net. */ /* find the previous, or parent-parent-parent */ for(p = prev; p; p = p->parent) /* looking for name with few labels, a parent */ if(p->namelabs <= m) { /* ==: since prev matched m, this is closest*/ /* <: prev matches more, but is not a parent, * this one is a (grand)parent */ node->parent = p; break; } lock_basic_unlock(&node->lock); prev = node; } } /** initialise parent pointers in the tree */ static void init_parents(struct val_anchors* anchors) { lock_basic_lock(&anchors->lock); anchors_init_parents_locked(anchors); lock_basic_unlock(&anchors->lock); } struct trust_anchor* anchor_find(struct val_anchors* anchors, uint8_t* name, int namelabs, size_t namelen, uint16_t dclass) { struct trust_anchor key; rbnode_t* n; if(!name) return NULL; key.node.key = &key; key.name = name; key.namelabs = namelabs; key.namelen = namelen; key.dclass = dclass; lock_basic_lock(&anchors->lock); n = rbtree_search(anchors->tree, &key); if(n) { lock_basic_lock(&((struct trust_anchor*)n->key)->lock); } lock_basic_unlock(&anchors->lock); if(!n) return NULL; return (struct trust_anchor*)n->key; } /** create new trust anchor object */ static struct trust_anchor* anchor_new_ta(struct val_anchors* anchors, uint8_t* name, int namelabs, size_t namelen, uint16_t dclass, int lockit) { #ifdef UNBOUND_DEBUG rbnode_t* r; #endif struct trust_anchor* ta = (struct trust_anchor*)malloc( sizeof(struct trust_anchor)); if(!ta) return NULL; memset(ta, 0, sizeof(*ta)); ta->node.key = ta; ta->name = memdup(name, namelen); if(!ta->name) { free(ta); return NULL; } ta->namelabs = namelabs; ta->namelen = namelen; ta->dclass = dclass; lock_basic_init(&ta->lock); if(lockit) { lock_basic_lock(&anchors->lock); } #ifdef UNBOUND_DEBUG r = #else (void) #endif rbtree_insert(anchors->tree, &ta->node); if(lockit) { lock_basic_unlock(&anchors->lock); } log_assert(r != NULL); return ta; } /** find trustanchor key by exact data match */ static struct ta_key* anchor_find_key(struct trust_anchor* ta, uint8_t* rdata, size_t rdata_len, uint16_t type) { struct ta_key* k; for(k = ta->keylist; k; k = k->next) { if(k->type == type && k->len == rdata_len && memcmp(k->data, rdata, rdata_len) == 0) return k; } return NULL; } /** create new trustanchor key */ static struct ta_key* anchor_new_ta_key(uint8_t* rdata, size_t rdata_len, uint16_t type) { struct ta_key* k = (struct ta_key*)malloc(sizeof(*k)); if(!k) return NULL; memset(k, 0, sizeof(*k)); k->data = memdup(rdata, rdata_len); if(!k->data) { free(k); return NULL; } k->len = rdata_len; k->type = type; return k; } /** * This routine adds a new RR to a trust anchor. The trust anchor may not * exist yet, and is created if not. The RR can be DS or DNSKEY. * This routine will also remove duplicates; storing them only once. * @param anchors: anchor storage. * @param name: name of trust anchor (wireformat) * @param type: type or RR * @param dclass: class of RR * @param rdata: rdata wireformat, starting with rdlength. * If NULL, nothing is stored, but an entry is created. * @param rdata_len: length of rdata including rdlength. * @return: NULL on error, else the trust anchor. */ static struct trust_anchor* anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type, uint16_t dclass, uint8_t* rdata, size_t rdata_len) { struct ta_key* k; struct trust_anchor* ta; int namelabs; size_t namelen; namelabs = dname_count_size_labels(name, &namelen); if(type != LDNS_RR_TYPE_DS && type != LDNS_RR_TYPE_DNSKEY) { log_err("Bad type for trust anchor"); return 0; } /* lookup or create trustanchor */ ta = anchor_find(anchors, name, namelabs, namelen, dclass); if(!ta) { ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass, 1); if(!ta) return NULL; lock_basic_lock(&ta->lock); } if(!rdata) { lock_basic_unlock(&ta->lock); return ta; } /* look for duplicates */ if(anchor_find_key(ta, rdata, rdata_len, type)) { lock_basic_unlock(&ta->lock); return ta; } k = anchor_new_ta_key(rdata, rdata_len, type); if(!k) { lock_basic_unlock(&ta->lock); return NULL; } /* add new key */ if(type == LDNS_RR_TYPE_DS) ta->numDS++; else ta->numDNSKEY++; k->next = ta->keylist; ta->keylist = k; lock_basic_unlock(&ta->lock); return ta; } /** * Add new RR. It converts ldns RR to wire format. * @param anchors: anchor storage. * @param rr: the wirerr. * @param rl: length of rr. * @param dl: length of dname. * @return NULL on error, else the trust anchor. */ static struct trust_anchor* anchor_store_new_rr(struct val_anchors* anchors, uint8_t* rr, size_t rl, size_t dl) { struct trust_anchor* ta; if(!(ta=anchor_store_new_key(anchors, rr, sldns_wirerr_get_type(rr, rl, dl), sldns_wirerr_get_class(rr, rl, dl), sldns_wirerr_get_rdatawl(rr, rl, dl), sldns_wirerr_get_rdatalen(rr, rl, dl)+2))) { return NULL; } log_nametypeclass(VERB_QUERY, "adding trusted key", rr, sldns_wirerr_get_type(rr, rl, dl), sldns_wirerr_get_class(rr, rl, dl)); return ta; } /** * Insert insecure anchor * @param anchors: anchor storage. * @param str: the domain name. * @return NULL on error, Else last trust anchor point */ static struct trust_anchor* anchor_insert_insecure(struct val_anchors* anchors, const char* str) { struct trust_anchor* ta; size_t dname_len = 0; uint8_t* nm = sldns_str2wire_dname(str, &dname_len); if(!nm) { log_err("parse error in domain name '%s'", str); return NULL; } ta = anchor_store_new_key(anchors, nm, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, NULL, 0); free(nm); return ta; } struct trust_anchor* anchor_store_str(struct val_anchors* anchors, sldns_buffer* buffer, const char* str) { struct trust_anchor* ta; uint8_t* rr = sldns_buffer_begin(buffer); size_t len = sldns_buffer_capacity(buffer), dname_len = 0; int status = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 0, NULL, 0, NULL, 0); if(status != 0) { log_err("error parsing trust anchor %s: at %d: %s", str, LDNS_WIREPARSE_OFFSET(status), sldns_get_errorstr_parse(status)); return NULL; } if(!(ta=anchor_store_new_rr(anchors, rr, len, dname_len))) { log_err("out of memory"); return NULL; } return ta; } /** * Read a file with trust anchors * @param anchors: anchor storage. * @param buffer: parsing buffer. * @param fname: string. * @param onlyone: only one trust anchor allowed in file. * @return NULL on error. Else last trust-anchor point. */ static struct trust_anchor* anchor_read_file(struct val_anchors* anchors, sldns_buffer* buffer, const char* fname, int onlyone) { struct trust_anchor* ta = NULL, *tanew; struct sldns_file_parse_state pst; int status; size_t len, dname_len; uint8_t* rr = sldns_buffer_begin(buffer); int ok = 1; FILE* in = fopen(fname, "r"); if(!in) { log_err("error opening file %s: %s", fname, strerror(errno)); return 0; } memset(&pst, 0, sizeof(pst)); pst.default_ttl = 3600; pst.lineno = 1; while(!feof(in)) { len = sldns_buffer_capacity(buffer); dname_len = 0; status = sldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst); if(len == 0) /* empty, $TTL, $ORIGIN */ continue; if(status != 0) { log_err("parse error in %s:%d:%d : %s", fname, pst.lineno, LDNS_WIREPARSE_OFFSET(status), sldns_get_errorstr_parse(status)); ok = 0; break; } if(sldns_wirerr_get_type(rr, len, dname_len) != LDNS_RR_TYPE_DS && sldns_wirerr_get_type(rr, len, dname_len) != LDNS_RR_TYPE_DNSKEY) { continue; } if(!(tanew=anchor_store_new_rr(anchors, rr, len, dname_len))) { log_err("mem error at %s line %d", fname, pst.lineno); ok = 0; break; } if(onlyone && ta && ta != tanew) { log_err("error at %s line %d: no multiple anchor " "domains allowed (you can have multiple " "keys, but they must have the same name).", fname, pst.lineno); ok = 0; break; } ta = tanew; } fclose(in); if(!ok) return NULL; /* empty file is OK when multiple anchors are allowed */ if(!onlyone && !ta) return (struct trust_anchor*)1; return ta; } /** skip file to end of line */ static void skip_to_eol(FILE* in) { int c; while((c = getc(in)) != EOF ) { if(c == '\n') return; } } /** true for special characters in bind configs */ static int is_bind_special(int c) { switch(c) { case '{': case '}': case '"': case ';': return 1; } return 0; } /** * Read a keyword skipping bind comments; spaces, specials, restkeywords. * The file is split into the following tokens: * * special characters, on their own, rdlen=1, { } doublequote ; * * whitespace becomes a single ' ' or tab. Newlines become spaces. * * other words ('keywords') * * comments are skipped if desired * / / C++ style comment to end of line * # to end of line * / * C style comment * / * @param in: file to read from. * @param buf: buffer, what is read is stored after current buffer position. * Space is left in the buffer to write a terminating 0. * @param line: line number is increased per line, for error reports. * @param comments: if 0, comments are not possible and become text. * if 1, comments are skipped entirely. * In BIND files, this is when reading quoted strings, for example * " base 64 text with / / in there " * @return the number of character written to the buffer. * 0 on end of file. */ static int readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) { int c; int numdone = 0; while((c = getc(in)) != EOF ) { if(comments && c == '#') { /* # blabla */ skip_to_eol(in); (*line)++; continue; } else if(comments && c=='/' && numdone>0 && /* /_/ bla*/ sldns_buffer_read_u8_at(buf, sldns_buffer_position(buf)-1) == '/') { sldns_buffer_skip(buf, -1); numdone--; skip_to_eol(in); (*line)++; continue; } else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */ sldns_buffer_read_u8_at(buf, sldns_buffer_position(buf)-1) == '/') { sldns_buffer_skip(buf, -1); numdone--; /* skip to end of comment */ while(c != EOF && (c=getc(in)) != EOF ) { if(c == '*') { if((c=getc(in)) == '/') break; } if(c == '\n') (*line)++; } continue; } /* not a comment, complete the keyword */ if(numdone > 0) { /* check same type */ if(isspace((unsigned char)c)) { ungetc(c, in); return numdone; } if(is_bind_special(c)) { ungetc(c, in); return numdone; } } if(c == '\n') { c = ' '; (*line)++; } /* space for 1 char + 0 string terminator */ if(sldns_buffer_remaining(buf) < 2) { fatal_exit("trusted-keys, %d, string too long", *line); } sldns_buffer_write_u8(buf, (uint8_t)c); numdone++; if(isspace((unsigned char)c)) { /* collate whitespace into ' ' */ while((c = getc(in)) != EOF ) { if(c == '\n') (*line)++; if(!isspace((unsigned char)c)) { ungetc(c, in); break; } } return numdone; } if(is_bind_special(c)) return numdone; } return numdone; } /** skip through file to { or ; */ static int skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec) { int rdlen; sldns_buffer_clear(buf); while((rdlen=readkeyword_bindfile(in, buf, line, 1))) { if(rdlen == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) { sldns_buffer_clear(buf); continue; } if(rdlen != 1 || *sldns_buffer_begin(buf) != (uint8_t)spec) { sldns_buffer_write_u8(buf, 0); log_err("trusted-keys, line %d, expected %c", *line, spec); return 0; } return 1; } log_err("trusted-keys, line %d, expected %c got EOF", *line, spec); return 0; } /** * read contents of trusted-keys{ ... ; clauses and insert keys into storage. * @param anchors: where to store keys * @param buf: buffer to use * @param line: line number in file * @param in: file to read from. * @return 0 on error. */ static int process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, int* line, FILE* in) { /* loop over contents, collate strings before ; */ /* contents is (numbered): 0 1 2 3 4 5 6 7 8 */ /* name. 257 3 5 base64 base64 */ /* quoted value: 0 "111" 0 0 0 0 0 0 0 */ /* comments value: 1 "000" 1 1 1 "0 0 0 0" 1 */ int contnum = 0; int quoted = 0; int comments = 1; int rdlen; char* str = 0; sldns_buffer_clear(buf); while((rdlen=readkeyword_bindfile(in, buf, line, comments))) { if(rdlen == 1 && sldns_buffer_position(buf) == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) { /* starting whitespace is removed */ sldns_buffer_clear(buf); continue; } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '"') { /* remove " from the string */ if(contnum == 0) { quoted = 1; comments = 0; } sldns_buffer_skip(buf, -1); if(contnum > 0 && quoted) { if(sldns_buffer_remaining(buf) < 8+1) { log_err("line %d, too long", *line); return 0; } sldns_buffer_write(buf, " DNSKEY ", 8); quoted = 0; comments = 1; } else if(contnum > 0) comments = !comments; continue; } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == ';') { if(contnum < 5) { sldns_buffer_write_u8(buf, 0); log_err("line %d, bad key", *line); return 0; } sldns_buffer_skip(buf, -1); sldns_buffer_write_u8(buf, 0); str = strdup((char*)sldns_buffer_begin(buf)); if(!str) { log_err("line %d, allocation failure", *line); return 0; } if(!anchor_store_str(anchors, buf, str)) { log_err("line %d, bad key", *line); free(str); return 0; } free(str); sldns_buffer_clear(buf); contnum = 0; quoted = 0; comments = 1; continue; } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '}') { if(contnum > 0) { sldns_buffer_write_u8(buf, 0); log_err("line %d, bad key before }", *line); return 0; } return 1; } else if(rdlen == 1 && isspace((unsigned char)sldns_buffer_current(buf)[-1])) { /* leave whitespace here */ } else { /* not space or whatnot, so actual content */ contnum ++; if(contnum == 1 && !quoted) { if(sldns_buffer_remaining(buf) < 8+1) { log_err("line %d, too long", *line); return 0; } sldns_buffer_write(buf, " DNSKEY ", 8); } } } log_err("line %d, EOF before }", *line); return 0; } /** * Read a BIND9 like file with trust anchors in named.conf format. * @param anchors: anchor storage. * @param buffer: parsing buffer. * @param fname: string. * @return false on error. */ static int anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer, const char* fname) { int line_nr = 1; FILE* in = fopen(fname, "r"); int rdlen = 0; if(!in) { log_err("error opening file %s: %s", fname, strerror(errno)); return 0; } verbose(VERB_QUERY, "reading in bind-compat-mode: '%s'", fname); /* scan for trusted-keys keyword, ignore everything else */ sldns_buffer_clear(buffer); while((rdlen=readkeyword_bindfile(in, buffer, &line_nr, 1)) != 0) { if(rdlen != 12 || strncmp((char*)sldns_buffer_begin(buffer), "trusted-keys", 12) != 0) { sldns_buffer_clear(buffer); /* ignore everything but trusted-keys */ continue; } if(!skip_to_special(in, buffer, &line_nr, '{')) { log_err("error in trusted key: \"%s\"", fname); fclose(in); return 0; } /* process contents */ if(!process_bind_contents(anchors, buffer, &line_nr, in)) { log_err("error in trusted key: \"%s\"", fname); fclose(in); return 0; } if(!skip_to_special(in, buffer, &line_nr, ';')) { log_err("error in trusted key: \"%s\"", fname); fclose(in); return 0; } sldns_buffer_clear(buffer); } fclose(in); return 1; } /** * Read a BIND9 like files with trust anchors in named.conf format. * Performs wildcard processing of name. * @param anchors: anchor storage. * @param buffer: parsing buffer. * @param pat: pattern string. (can be wildcarded) * @return false on error. */ static int anchor_read_bind_file_wild(struct val_anchors* anchors, sldns_buffer* buffer, const char* pat) { #ifdef HAVE_GLOB glob_t g; size_t i; int r, flags; if(!strchr(pat, '*') && !strchr(pat, '?') && !strchr(pat, '[') && !strchr(pat, '{') && !strchr(pat, '~')) { return anchor_read_bind_file(anchors, buffer, pat); } verbose(VERB_QUERY, "wildcard found, processing %s", pat); flags = 0 #ifdef GLOB_ERR | GLOB_ERR #endif #ifdef GLOB_NOSORT | GLOB_NOSORT #endif #ifdef GLOB_BRACE | GLOB_BRACE #endif #ifdef GLOB_TILDE | GLOB_TILDE #endif ; memset(&g, 0, sizeof(g)); r = glob(pat, flags, NULL, &g); if(r) { /* some error */ if(r == GLOB_NOMATCH) { verbose(VERB_QUERY, "trusted-keys-file: " "no matches for %s", pat); return 1; } else if(r == GLOB_NOSPACE) { log_err("wildcard trusted-keys-file %s: " "pattern out of memory", pat); } else if(r == GLOB_ABORTED) { log_err("wildcard trusted-keys-file %s: expansion " "aborted (%s)", pat, strerror(errno)); } else { log_err("wildcard trusted-keys-file %s: expansion " "failed (%s)", pat, strerror(errno)); } /* ignore globs that yield no files */ return 1; } /* process files found, if any */ for(i=0; i<(size_t)g.gl_pathc; i++) { if(!anchor_read_bind_file(anchors, buffer, g.gl_pathv[i])) { log_err("error reading wildcard " "trusted-keys-file: %s", g.gl_pathv[i]); globfree(&g); return 0; } } globfree(&g); return 1; #else /* not HAVE_GLOB */ return anchor_read_bind_file(anchors, buffer, pat); #endif /* HAVE_GLOB */ } /** * Assemble an rrset structure for the type * @param ta: trust anchor. * @param num: number of items to fetch from list. * @param type: fetch only items of this type. * @return rrset or NULL on error. */ static struct ub_packed_rrset_key* assemble_it(struct trust_anchor* ta, size_t num, uint16_t type) { struct ub_packed_rrset_key* pkey = (struct ub_packed_rrset_key*) malloc(sizeof(*pkey)); struct packed_rrset_data* pd; struct ta_key* tk; size_t i; if(!pkey) return NULL; memset(pkey, 0, sizeof(*pkey)); pkey->rk.dname = memdup(ta->name, ta->namelen); if(!pkey->rk.dname) { free(pkey); return NULL; } pkey->rk.dname_len = ta->namelen; pkey->rk.type = htons(type); pkey->rk.rrset_class = htons(ta->dclass); /* The rrset is build in an uncompressed way. This means it * cannot be copied in the normal way. */ pd = (struct packed_rrset_data*)malloc(sizeof(*pd)); if(!pd) { free(pkey->rk.dname); free(pkey); return NULL; } memset(pd, 0, sizeof(*pd)); pd->count = num; pd->trust = rrset_trust_ultimate; pd->rr_len = (size_t*)reallocarray(NULL, num, sizeof(size_t)); if(!pd->rr_len) { free(pd); free(pkey->rk.dname); free(pkey); return NULL; } pd->rr_ttl = (time_t*)reallocarray(NULL, num, sizeof(time_t)); if(!pd->rr_ttl) { free(pd->rr_len); free(pd); free(pkey->rk.dname); free(pkey); return NULL; } pd->rr_data = (uint8_t**)reallocarray(NULL, num, sizeof(uint8_t*)); if(!pd->rr_data) { free(pd->rr_ttl); free(pd->rr_len); free(pd); free(pkey->rk.dname); free(pkey); return NULL; } /* fill in rrs */ i=0; for(tk = ta->keylist; tk; tk = tk->next) { if(tk->type != type) continue; pd->rr_len[i] = tk->len; /* reuse data ptr to allocation in talist */ pd->rr_data[i] = tk->data; pd->rr_ttl[i] = 0; i++; } pkey->entry.data = (void*)pd; return pkey; } /** * Assemble structures for the trust DS and DNSKEY rrsets. * @param ta: trust anchor * @return: false on error. */ static int anchors_assemble(struct trust_anchor* ta) { if(ta->numDS > 0) { ta->ds_rrset = assemble_it(ta, ta->numDS, LDNS_RR_TYPE_DS); if(!ta->ds_rrset) return 0; } if(ta->numDNSKEY > 0) { ta->dnskey_rrset = assemble_it(ta, ta->numDNSKEY, LDNS_RR_TYPE_DNSKEY); if(!ta->dnskey_rrset) return 0; } return 1; } /** * Check DS algos for support, warn if not. * @param ta: trust anchor * @return number of DS anchors with unsupported algorithms. */ static size_t anchors_ds_unsupported(struct trust_anchor* ta) { size_t i, num = 0; for(i=0; inumDS; i++) { if(!ds_digest_algo_is_supported(ta->ds_rrset, i) || !ds_key_algo_is_supported(ta->ds_rrset, i)) num++; } return num; } /** * Check DNSKEY algos for support, warn if not. * @param ta: trust anchor * @return number of DNSKEY anchors with unsupported algorithms. */ static size_t anchors_dnskey_unsupported(struct trust_anchor* ta) { size_t i, num = 0; for(i=0; inumDNSKEY; i++) { if(!dnskey_algo_is_supported(ta->dnskey_rrset, i)) num++; } return num; } /** * Assemble the rrsets in the anchors, ready for use by validator. * @param anchors: trust anchor storage. * @return: false on error. */ static int anchors_assemble_rrsets(struct val_anchors* anchors) { struct trust_anchor* ta; struct trust_anchor* next; size_t nods, nokey; lock_basic_lock(&anchors->lock); ta=(struct trust_anchor*)rbtree_first(anchors->tree); while((rbnode_t*)ta != RBTREE_NULL) { next = (struct trust_anchor*)rbtree_next(&ta->node); lock_basic_lock(&ta->lock); if(ta->autr || (ta->numDS == 0 && ta->numDNSKEY == 0)) { lock_basic_unlock(&ta->lock); ta = next; /* skip */ continue; } if(!anchors_assemble(ta)) { log_err("out of memory"); lock_basic_unlock(&ta->lock); lock_basic_unlock(&anchors->lock); return 0; } nods = anchors_ds_unsupported(ta); nokey = anchors_dnskey_unsupported(ta); if(nods) { log_nametypeclass(0, "warning: unsupported " "algorithm for trust anchor", ta->name, LDNS_RR_TYPE_DS, ta->dclass); } if(nokey) { log_nametypeclass(0, "warning: unsupported " "algorithm for trust anchor", ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); } if(nods == ta->numDS && nokey == ta->numDNSKEY) { char b[257]; dname_str(ta->name, b); log_warn("trust anchor %s has no supported algorithms," " the anchor is ignored (check if you need to" " upgrade unbound and " #ifdef HAVE_LIBRESSL "libressl" #else "openssl" #endif ")", b); (void)rbtree_delete(anchors->tree, &ta->node); lock_basic_unlock(&ta->lock); anchors_delfunc(&ta->node, NULL); ta = next; continue; } lock_basic_unlock(&ta->lock); ta = next; } lock_basic_unlock(&anchors->lock); return 1; } int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) { struct config_strlist* f; + const char** zstr; char* nm; sldns_buffer* parsebuf = sldns_buffer_new(65535); + if(cfg->insecure_lan_zones) { + for(zstr = as112_zones; *zstr; zstr++) { + if(!anchor_insert_insecure(anchors, *zstr)) { + log_err("error in insecure-lan-zones: %s", *zstr); + sldns_buffer_free(parsebuf); + return 0; + } + } + } for(f = cfg->domain_insecure; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; if(!anchor_insert_insecure(anchors, f->str)) { log_err("error in domain-insecure: %s", f->str); sldns_buffer_free(parsebuf); return 0; } } for(f = cfg->trust_anchor_file_list; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; nm = f->str; if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm, cfg->chrootdir, strlen(cfg->chrootdir)) == 0) nm += strlen(cfg->chrootdir); if(!anchor_read_file(anchors, parsebuf, nm, 0)) { log_err("error reading trust-anchor-file: %s", f->str); sldns_buffer_free(parsebuf); return 0; } } for(f = cfg->trusted_keys_file_list; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; nm = f->str; if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm, cfg->chrootdir, strlen(cfg->chrootdir)) == 0) nm += strlen(cfg->chrootdir); if(!anchor_read_bind_file_wild(anchors, parsebuf, nm)) { log_err("error reading trusted-keys-file: %s", f->str); sldns_buffer_free(parsebuf); return 0; } } for(f = cfg->trust_anchor_list; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; if(!anchor_store_str(anchors, parsebuf, f->str)) { log_err("error in trust-anchor: \"%s\"", f->str); sldns_buffer_free(parsebuf); return 0; } } if(cfg->dlv_anchor_file && cfg->dlv_anchor_file[0] != 0) { struct trust_anchor* dlva; nm = cfg->dlv_anchor_file; if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm, cfg->chrootdir, strlen(cfg->chrootdir)) == 0) nm += strlen(cfg->chrootdir); if(!(dlva = anchor_read_file(anchors, parsebuf, nm, 1))) { log_err("error reading dlv-anchor-file: %s", cfg->dlv_anchor_file); sldns_buffer_free(parsebuf); return 0; } lock_basic_lock(&anchors->lock); anchors->dlv_anchor = dlva; lock_basic_unlock(&anchors->lock); } for(f = cfg->dlv_anchor_list; f; f = f->next) { struct trust_anchor* dlva; if(!f->str || f->str[0] == 0) /* empty "" */ continue; if(!(dlva = anchor_store_str( anchors, parsebuf, f->str))) { log_err("error in dlv-anchor: \"%s\"", f->str); sldns_buffer_free(parsebuf); return 0; } lock_basic_lock(&anchors->lock); anchors->dlv_anchor = dlva; lock_basic_unlock(&anchors->lock); } /* do autr last, so that it sees what anchors are filled by other * means can can print errors about double config for the name */ for(f = cfg->auto_trust_anchor_file_list; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; nm = f->str; if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm, cfg->chrootdir, strlen(cfg->chrootdir)) == 0) nm += strlen(cfg->chrootdir); if(!autr_read_file(anchors, nm)) { log_err("error reading auto-trust-anchor-file: %s", f->str); sldns_buffer_free(parsebuf); return 0; } } /* first assemble, since it may delete useless anchors */ anchors_assemble_rrsets(anchors); init_parents(anchors); sldns_buffer_free(parsebuf); if(verbosity >= VERB_ALGO) autr_debug_print(anchors); return 1; } struct trust_anchor* anchors_lookup(struct val_anchors* anchors, uint8_t* qname, size_t qname_len, uint16_t qclass) { struct trust_anchor key; struct trust_anchor* result; rbnode_t* res = NULL; key.node.key = &key; key.name = qname; key.namelabs = dname_count_labels(qname); key.namelen = qname_len; key.dclass = qclass; lock_basic_lock(&anchors->lock); if(rbtree_find_less_equal(anchors->tree, &key, &res)) { /* exact */ result = (struct trust_anchor*)res; } else { /* smaller element (or no element) */ int m; result = (struct trust_anchor*)res; if(!result || result->dclass != qclass) { lock_basic_unlock(&anchors->lock); return NULL; } /* count number of labels matched */ (void)dname_lab_cmp(result->name, result->namelabs, key.name, key.namelabs, &m); while(result) { /* go up until qname is subdomain of stub */ if(result->namelabs <= m) break; result = result->parent; } } if(result) { lock_basic_lock(&result->lock); } lock_basic_unlock(&anchors->lock); return result; } size_t anchors_get_mem(struct val_anchors* anchors) { struct trust_anchor *ta; size_t s = sizeof(*anchors); if(!anchors) return 0; RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) { s += sizeof(*ta) + ta->namelen; /* keys and so on */ } return s; } int anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm) { struct trust_anchor key; key.node.key = &key; key.name = nm; key.namelabs = dname_count_size_labels(nm, &key.namelen); key.dclass = c; lock_basic_lock(&anchors->lock); if(rbtree_search(anchors->tree, &key)) { lock_basic_unlock(&anchors->lock); /* nothing to do, already an anchor or insecure point */ return 1; } if(!anchor_new_ta(anchors, nm, key.namelabs, key.namelen, c, 0)) { log_err("out of memory"); lock_basic_unlock(&anchors->lock); return 0; } /* no other contents in new ta, because it is insecure point */ anchors_init_parents_locked(anchors); lock_basic_unlock(&anchors->lock); return 1; } void anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm) { struct trust_anchor key; struct trust_anchor* ta; key.node.key = &key; key.name = nm; key.namelabs = dname_count_size_labels(nm, &key.namelen); key.dclass = c; lock_basic_lock(&anchors->lock); if(!(ta=(struct trust_anchor*)rbtree_search(anchors->tree, &key))) { lock_basic_unlock(&anchors->lock); /* nothing there */ return; } /* lock it to drive away other threads that use it */ lock_basic_lock(&ta->lock); /* see if its really an insecure point */ if(ta->keylist || ta->autr || ta->numDS || ta->numDNSKEY) { lock_basic_unlock(&anchors->lock); lock_basic_unlock(&ta->lock); /* its not an insecure point, do not remove it */ return; } /* remove from tree */ (void)rbtree_delete(anchors->tree, &ta->node); anchors_init_parents_locked(anchors); lock_basic_unlock(&anchors->lock); /* actual free of data */ lock_basic_unlock(&ta->lock); anchors_delfunc(&ta->node, NULL); }