Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Christopher Zimmermann 2021-02-03 13:19:19 +01:00
commit 1d23e0c920
370 changed files with 24681 additions and 14854 deletions

1
.gitignore vendored
View file

@ -31,6 +31,7 @@
/unbound.h /unbound.h
/asynclook /asynclook
/delayer /delayer
/dohclient
/lock-verify /lock-verify
/memstats /memstats
/perf /perf

View file

@ -25,6 +25,7 @@ DNSTAP_SRC=@DNSTAP_SRC@
DNSTAP_OBJ=@DNSTAP_OBJ@ DNSTAP_OBJ=@DNSTAP_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@ DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@ DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@ WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
WITH_PYUNBOUND=@WITH_PYUNBOUND@ WITH_PYUNBOUND=@WITH_PYUNBOUND@
PY_MAJOR_VERSION=@PY_MAJOR_VERSION@ PY_MAJOR_VERSION=@PY_MAJOR_VERSION@
@ -87,6 +88,12 @@ LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=i
INSTALL=$(SHELL) $(srcdir)/install-sh INSTALL=$(SHELL) $(srcdir)/install-sh
DYNLIBMOD_SRC=dynlibmod/dynlibmod.c
DYNLIBMOD_OBJ=@DYNLIBMOD_OBJ@
DYNLIBMOD_HEADER=@DYNLIBMOD_HEADER@
DYNLIBMOD_EXTRALIBS=@DYNLIBMOD_EXTRALIBS@
#pythonmod.c is not here, it is mentioned by itself in its own rules, #pythonmod.c is not here, it is mentioned by itself in its own rules,
#makedepend fails on missing interface.h otherwise. #makedepend fails on missing interface.h otherwise.
PYTHONMOD_SRC=pythonmod/pythonmod_utils.c PYTHONMOD_SRC=pythonmod/pythonmod_utils.c
@ -140,7 +147,7 @@ autotrust.lo val_anchor.lo rpz.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \ val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \ $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \ COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@ -224,6 +231,10 @@ STREAMTCP_SRC=testcode/streamtcp.c
STREAMTCP_OBJ=streamtcp.lo STREAMTCP_OBJ=streamtcp.lo
STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ) $(SLDNS_OBJ)
DOHCLIENT_SRC=testcode/dohclient.c
DOHCLIENT_OBJ=dohclient.lo
DOHCLIENT_OBJ_LINK=$(DOHCLIENT_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
PERF_SRC=testcode/perf.c PERF_SRC=testcode/perf.c
PERF_OBJ=perf.lo PERF_OBJ=perf.lo
PERF_OBJ_LINK=$(PERF_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ) PERF_OBJ_LINK=$(PERF_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ)
@ -237,6 +248,7 @@ DNSTAP_SOCKET_SRC=dnstap/unbound-dnstap-socket.c
DNSTAP_SOCKET_OBJ=unbound-dnstap-socket.lo DNSTAP_SOCKET_OBJ=unbound-dnstap-socket.lo
DNSTAP_SOCKET_OBJ_LINK=$(DNSTAP_SOCKET_OBJ) $(COMMON_OBJ) \ DNSTAP_SOCKET_OBJ_LINK=$(DNSTAP_SOCKET_OBJ) $(COMMON_OBJ) \
$(COMPAT_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ)
DNSTAP_SOCKET_TESTBIN=@DNSTAP_SOCKET_TESTBIN@
LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \ LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
libunbound/libworker.c libunbound/libworker.c
LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
@ -265,7 +277,8 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \ $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\ $(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \ $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) \
$(DOHCLIENT_SRC)
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \ $(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
@ -273,7 +286,8 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \ $(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\ $(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\
$(COMPAT_OBJ) $(PYUNBOUND_OBJ) \ $(COMPAT_OBJ) $(PYUNBOUND_OBJ) \
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) $(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) \
$(DOHCLIENT_OBJ)
COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
@ -310,7 +324,7 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h
TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \ TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \
lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \ lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \
petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \ petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \
unbound-dnstap-socket$(EXEEXT) \ $(DNSTAP_SOCKET_TESTBIN) dohclient$(EXEEXT) \
testbound$(EXEEXT) unittest$(EXEEXT) testbound$(EXEEXT) unittest$(EXEEXT)
tests: all $(TEST_BIN) tests: all $(TEST_BIN)
@ -333,7 +347,7 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS) $(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS)
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
@ -380,6 +394,9 @@ asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK) streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS) $(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
dohclient$(EXEEXT): $(DOHCLIENT_OBJ_LINK)
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
perf$(EXEEXT): $(PERF_OBJ_LINK) perf$(EXEEXT): $(PERF_OBJ_LINK)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS) $(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
@ -413,6 +430,7 @@ dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h
dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h
unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h
dynlibmod.lo dynlibdmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h
# dnscrypt # dnscrypt
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
@ -466,6 +484,7 @@ clean:
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
rm -f $(ALL_SRC:.c=.lint) 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 -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
rm -f libunbound.a
rm -rf autom4te.cache .libs build doc/html doc/xml rm -rf autom4te.cache .libs build doc/html doc/xml
distclean: clean distclean: clean
@ -640,6 +659,7 @@ depend:
-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \ -e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \ -e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
-e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \ -e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
-e 's?$$(srcdir)/dynlibmod/dynlibmod.h?$$(DYNLIBMOD_HEADER)?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \ -e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP) > $(DEPEND_TMP)
cp $(DEPEND_TARGET) $(DEPEND_TMP2) cp $(DEPEND_TARGET) $(DEPEND_TMP2)
@ -663,7 +683,7 @@ dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_de
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.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 \ infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \
@ -704,10 +724,11 @@ msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/d
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/respip/respip.h $(srcdir)/respip/respip.h
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \ packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterator/iterator.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)/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/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
@ -776,7 +797,7 @@ listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.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)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/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/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
@ -799,10 +820,10 @@ mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(s
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \ $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
$(srcdir)/util/alloc.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/alloc.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h $(srcdir)/services/listen_dnsport.h
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \ 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/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)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
@ -812,7 +833,11 @@ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/service
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(PYTHONMOD_HEADER) $(DYNLIBMOD_HEADER) $(srcdir)/cachedb/cachedb.h \
$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \ view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
@ -843,7 +868,8 @@ outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c confi
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h \ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/util/edns.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 \ 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/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@ -864,7 +890,8 @@ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/ut
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \ $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/iana_ports.inc $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/edns-subnet/edns-subnet.h \
$(srcdir)/util/iana_ports.inc
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \ configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h $(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \ configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
@ -893,8 +920,8 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
$(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \ $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \ $(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_secalgo.h
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
@ -903,7 +930,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \ $(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \ $(srcdir)/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)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
@ -911,18 +938,13 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.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)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/libunbound/worker.h $(srcdir)/libunbound/worker.h $(PYTHONMOD_HEADER) $(DYNLIBMOD_HEADER) \
$(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h $(srcdir)/dnstap/dtstream.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.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 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 \ mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ 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/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)/sldns/wire2str.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
@ -935,12 +957,14 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h $(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h \
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \ 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/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)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h $(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 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 \ rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@ -956,11 +980,11 @@ rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/itera
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.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/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)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/config_file.h \ edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/regional.h \
$(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h
dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \ 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/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 $(srcdir)/util/log.h $(srcdir)/util/net_help.h
@ -994,7 +1018,8 @@ tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/u
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h
ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \ ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/util/tube.h \
ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \ ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \ $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
@ -1004,7 +1029,8 @@ ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.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 \ 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/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
@ -1017,7 +1043,8 @@ autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/val
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h \
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \ 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/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)/sldns/pkthdr.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \
@ -1047,11 +1074,13 @@ val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/
val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.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/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)/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 $(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 \ val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \ $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.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)/sldns/pkthdr.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/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 $(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 \ val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \
@ -1069,15 +1098,17 @@ val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/valida
val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.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)/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)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/sbuffer.h \
val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.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)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h \ $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/wire2str.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 \ 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)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
@ -1098,15 +1129,43 @@ dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(src
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h \
subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h $(srcdir)/edns-subnet/subnetmod.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/outbound_list.h $(srcdir)/util/alloc.h \
$(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h \
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
$(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/respip/respip.h $(srcdir)/services/cache/dns.h $(srcdir)/util/regional.h \
$(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h
addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \ addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h
subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h \
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/cachedb/redis.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h \
$(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h $(srcdir)/cachedb/cachedb.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h \
$(srcdir)/sldns/sbuffer.h
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \ respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
@ -1119,8 +1178,42 @@ respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localz
$(srcdir)/util/regional.h $(srcdir)/util/regional.h
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/testcode/checklocks.h $(srcdir)/testcode/checklocks.h
ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.h \
ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnstap/dnstap.h \
$(srcdir)/dnstap/dtstream.h $(srcdir)/util/locks.h dnstap/dnstap.pb-c.h
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h \
dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/dnstap/dnstap_fstrm.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \
$(srcdir)/util/net_help.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/sldns/sbuffer.h \
ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h $(srcdir)/ipsecmod/ipsecmod.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/rbtree.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/wire2str.h
ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h \
$(srcdir)/ipsecmod/ipsecmod.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/rbtree.h \
$(srcdir)/ipsecmod/ipsecmod-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/regional.h \
$(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
ipset.lo ipset.o: $(srcdir)/ipset/ipset.c config.h $(srcdir)/ipset/ipset.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.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)/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 $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
@ -1129,7 +1222,8 @@ unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.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 $(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 \ 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/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)/util/timehist.h $(srcdir)/iterator/iterator.h \ $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
@ -1137,7 +1231,8 @@ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/r
$(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/random.h $(srcdir)/respip/respip.h \ $(srcdir)/util/random.h $(srcdir)/respip/respip.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/outside_network.h
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.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)/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/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
@ -1167,8 +1262,15 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.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 $(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 \ 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 $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h $(srcdir)/sldns/parseutil.h
unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h $(srcdir)/util/log.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)/testcode/unitmain.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/services/outbound_list.h $(srcdir)/util/alloc.h \
$(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h \
$(srcdir)/edns-subnet/edns-subnet.h
unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \ unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
@ -1185,40 +1287,43 @@ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/ac
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \ cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.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)/dnscrypt/dnscrypt.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
$(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)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \ $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.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)/dnscrypt/dnscrypt.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/edns.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.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)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/keyraw.h $(srcdir)/sldns/keyraw.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/daemon/remote.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/alloc.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \ $(srcdir)/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/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/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
@ -1243,19 +1348,21 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h $(srcdir)/edns-subnet/subnetmod.h \
$(srcdir)/util/data/dname.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.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)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \ $(srcdir)/daemon/remote.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \ $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ 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/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/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
@ -1263,22 +1370,24 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/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)/services/modstack.h $(srcdir)/daemon/remote.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \ $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \ $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.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)/util/edns.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \ $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/util/shm_side/shm_main.h $(srcdir)/dnstap/dtstream.h
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.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)/daemon/remote.h \
$(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.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)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.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/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
@ -1297,33 +1406,35 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/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)/services/modstack.h $(srcdir)/daemon/remote.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \ $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \ $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.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)/util/edns.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \ $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/util/shm_side/shm_main.h $(srcdir)/dnstap/dtstream.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.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)/services/view.h $(srcdir)/util/locks.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.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)/daemon/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \ $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \ $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/edns.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.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)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \ $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
@ -1341,7 +1452,9 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h $(srcdir)/edns-subnet/subnetmod.h \
$(srcdir)/util/data/dname.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.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)/dnscrypt/dnscrypt.h \ $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \ $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
@ -1351,13 +1464,14 @@ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/t
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.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/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/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/edns.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h \
$(srcdir)/util/rbtree.h $(srcdir)/services/cache/infra.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \ $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \ 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)/dnscrypt/dnscrypt.h \ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
@ -1392,7 +1506,8 @@ unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
$(PYTHONMOD_HEADER) $(srcdir)/edns-subnet/subnet-whitelist.h
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
@ -1413,70 +1528,83 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.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)/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/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/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/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/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
$(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \ $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h $(srcdir)/util/edns.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h \ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h \
$(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h \ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \ $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.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 $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.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)/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-event.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h $(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 \ 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/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/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)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.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 \ 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/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)/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 $(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 \ 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 $(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 \ unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \
$(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \ $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \ $(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \ $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/modstack.h $(srcdir)/respip/respip.h $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \ 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 $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h \
$(srcdir)/dnstap/dtstream.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/dnstap/dnstap_fstrm.h \
$(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h \
dnstap/dnstap.pb-c.h \
$(srcdir)/util/config_file.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h
pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.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/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)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.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)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \ 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/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \ $(srcdir)/daemon/worker.h \
@ -1484,8 +1612,8 @@ win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h 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 \ unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
$(srcdir)/winrc/w_inst.h $(srcdir)/winrc/w_inst.h
@ -1493,18 +1621,26 @@ unbound-service-remove.lo unbound-service-remove.o: $(srcdir)/winrc/unbound-serv
$(srcdir)/winrc/w_inst.h $(srcdir)/winrc/w_inst.h
anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.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 $(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 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 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 \ 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/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/keyraw.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/sldns/keyraw.h \
$(srcdir)/util/log.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \ parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/sbuffer.h
parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.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 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 \ 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 $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h
dohclient.lo dohclient.o: $(srcdir)/testcode/dohclient.c config.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.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)/util/net_help.h \
ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.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 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 gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h
@ -1519,9 +1655,11 @@ strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
getentropy_freebsd.lo getentropy_freebsd.o: $(srcdir)/compat/getentropy_freebsd.c getentropy_freebsd.lo getentropy_freebsd.o: $(srcdir)/compat/getentropy_freebsd.c
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.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 getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h \
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h 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.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h

View file

@ -9,7 +9,7 @@ fast and lean and incorporates modern features based on open standards. If you
have any feedback, we would love to hear from you. Dont hesitate to have any feedback, we would love to hear from you. Dont hesitate to
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new) [create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users). or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
You can lean more about Unbound by reading our You can learn more about Unbound by reading our
[documentation](https://nlnetlabs.nl/documentation/unbound/). [documentation](https://nlnetlabs.nl/documentation/unbound/).
## Compiling ## Compiling

134
aclocal.m4 vendored
View file

@ -736,7 +736,6 @@ _LT_CONFIG_SAVE_COMMANDS([
cat <<_LT_EOF >> "$cfgfile" cat <<_LT_EOF >> "$cfgfile"
#! $SHELL #! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION # Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh. # NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services. # Provide generalized library-building support services.
@ -1048,8 +1047,8 @@ int forced_loaded() { return 2;}
_LT_EOF _LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
cat > conftest.c << _LT_EOF cat > conftest.c << _LT_EOF
@ -1499,7 +1498,7 @@ need_locks=$enable_libtool_lock
m4_defun([_LT_PROG_AR], m4_defun([_LT_PROG_AR],
[AC_CHECK_TOOLS(AR, [ar], false) [AC_CHECK_TOOLS(AR, [ar], false)
: ${AR=ar} : ${AR=ar}
: ${AR_FLAGS=cru} : ${AR_FLAGS=cr}
_LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR], [1], [The archiver])
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
@ -2873,9 +2872,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# before this can be enabled. # before this can be enabled.
hardcode_into_libs=yes hardcode_into_libs=yes
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
# Ideally, we could use ldconfig to report *all* directores which are # Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not # searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command # being certain /sbin/ldconfig is available, command
@ -2884,7 +2880,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# appending ld.so.conf contents (and includes) to the search path. # appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi fi
# We used to test for /lib/ld.so.1 and disable shared libraries on # We used to test for /lib/ld.so.1 and disable shared libraries on
@ -2896,6 +2892,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
dynamic_linker='GNU/Linux ld.so' dynamic_linker='GNU/Linux ld.so'
;; ;;
netbsdelf*-gnu)
version_type=linux
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='NetBSD ld.elf_so'
;;
netbsd*) netbsd*)
version_type=sunos version_type=sunos
need_lib_prefix=no need_lib_prefix=no
@ -3555,7 +3563,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all lt_cv_deplibs_check_method=pass_all
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else else
@ -4061,7 +4069,8 @@ _LT_EOF
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols. # Now try to grab the symbols.
nlist=conftest.nm nlist=conftest.nm
if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
# Try sorting and uniquifying the output. # Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist" mv -f "$nlist"T "$nlist"
@ -4433,7 +4442,7 @@ m4_if([$1], [CXX], [
;; ;;
esac esac
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
;; ;;
*qnx* | *nto*) *qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise # QNX uses GNU C++, but need to define -shared option too, otherwise
@ -4701,6 +4710,12 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;; ;;
# flang / f18. f95 an alias for gfortran or flang on Debian
flang* | f18* | f95*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# icc used to be incompatible with GCC. # icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more. # ICC 10 doesn't accept -KPIC any more.
icc* | ifort*) icc* | ifort*)
@ -4945,6 +4960,9 @@ m4_if([$1], [CXX], [
;; ;;
esac esac
;; ;;
linux* | k*bsd*-gnu | gnu*)
_LT_TAGVAR(link_all_deplibs, $1)=no
;;
*) *)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;; ;;
@ -5007,6 +5025,9 @@ dnl Note also adjust exclude_expsyms for C++ above.
openbsd* | bitrig*) openbsd* | bitrig*)
with_gnu_ld=no with_gnu_ld=no
;; ;;
linux* | k*bsd*-gnu | gnu*)
_LT_TAGVAR(link_all_deplibs, $1)=no
;;
esac esac
_LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(ld_shlibs, $1)=yes
@ -5261,7 +5282,7 @@ _LT_EOF
fi fi
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc= wlarc=
@ -5782,6 +5803,7 @@ _LT_EOF
if test yes = "$lt_cv_irix_exported_symbol"; then if test yes = "$lt_cv_irix_exported_symbol"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi fi
_LT_TAGVAR(link_all_deplibs, $1)=no
else else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@ -5803,7 +5825,7 @@ _LT_EOF
esac esac
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else else
@ -6425,7 +6447,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else else
GXX=no GXX=no
@ -6800,7 +6822,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
# dependencies. # dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;; ;;
*) *)
if test yes = "$GXX"; then if test yes = "$GXX"; then
@ -6865,7 +6887,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them # explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library # from the output so that they don't get included in the library
# dependencies. # dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;; ;;
*) *)
if test yes = "$GXX"; then if test yes = "$GXX"; then
@ -7204,7 +7226,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else else
# FIXME: insert proper C++ library support # FIXME: insert proper C++ library support
@ -7288,7 +7310,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else else
# g++ 2.7 appears to require '-G' NOT '-shared' on this # g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform. # platform.
@ -7299,7 +7321,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists # Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when # what "hidden" libraries, object files and flags are used when
# linking a shared library. # linking a shared library.
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
fi fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
@ -9044,9 +9066,9 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 11 (pkg-config-0.29.1) dnl serial 11 (pkg-config-0.29.1)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl dnl
@ -9320,74 +9342,6 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR ])dnl PKG_CHECK_VAR
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------
dnl
dnl Prepare a "--with-" configure option using the lowercase
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
dnl PKG_CHECK_MODULES in a single macro.
AC_DEFUN([PKG_WITH_MODULES],
[
m4_pushdef([with_arg], m4_tolower([$1]))
m4_pushdef([description],
[m4_default([$5], [build with ]with_arg[ support])])
m4_pushdef([def_arg], [m4_default([$6], [auto])])
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
m4_case(def_arg,
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
[m4_pushdef([with_without],[--with-]with_arg)])
AC_ARG_WITH(with_arg,
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
[AS_TR_SH([with_]with_arg)=def_arg])
AS_CASE([$AS_TR_SH([with_]with_arg)],
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
[auto],[PKG_CHECK_MODULES([$1],[$2],
[m4_n([def_action_if_found]) $3],
[m4_n([def_action_if_not_found]) $4])])
m4_popdef([with_arg])
m4_popdef([description])
m4_popdef([def_arg])
])dnl PKG_WITH_MODULES
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl -----------------------------------------------
dnl
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
dnl check._[VARIABLE-PREFIX] is exported as make variable.
AC_DEFUN([PKG_HAVE_WITH_MODULES],
[
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
AM_CONDITIONAL([HAVE_][$1],
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
])dnl PKG_HAVE_WITH_MODULES
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------------------
dnl
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
dnl and preprocessor variable.
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
[
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
])dnl PKG_HAVE_DEFINE_WITH_MODULES
# AM_CONDITIONAL -*- Autoconf -*- # AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2018 Free Software Foundation, Inc. # Copyright (C) 1997-2018 Free Software Foundation, Inc.

View file

@ -2,7 +2,10 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs. # Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed. # BSD licensed.
# #
# Version 34 # Version 37
# 2021-01-05 fix defun for aclocal
# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE
# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0. # 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0.
# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0). # 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0).
# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20 # 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20
@ -446,15 +449,12 @@ AC_DEFUN([ACX_CHECK_FORMAT_ATTRIBUTE],
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute) AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute)
AC_CACHE_VAL(ac_cv_c_format_attribute, AC_CACHE_VAL(ac_cv_c_format_attribute,
[ac_cv_c_format_attribute=no [ac_cv_c_format_attribute=no
AC_TRY_COMPILE( AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
[#include <stdio.h>
void f (char *format, ...) __attribute__ ((format (printf, 1, 2))); void f (char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2))); void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2)));
], [ ]], [[
f ("%s", "str"); f ("%s", "str");
], ]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"])
[ac_cv_c_format_attribute="yes"],
[ac_cv_c_format_attribute="no"])
]) ])
AC_MSG_RESULT($ac_cv_c_format_attribute) AC_MSG_RESULT($ac_cv_c_format_attribute)
@ -483,14 +483,11 @@ AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute) AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute)
AC_CACHE_VAL(ac_cv_c_unused_attribute, AC_CACHE_VAL(ac_cv_c_unused_attribute,
[ac_cv_c_unused_attribute=no [ac_cv_c_unused_attribute=no
AC_TRY_COMPILE( AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
[#include <stdio.h>
void f (char *u __attribute__((unused))); void f (char *u __attribute__((unused)));
], [ ]], [[
f ("x"); f ("x");
], ]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"])
[ac_cv_c_unused_attribute="yes"],
[ac_cv_c_unused_attribute="no"])
]) ])
dnl Setup ATTR_UNUSED config.h parts. dnl Setup ATTR_UNUSED config.h parts.
@ -547,7 +544,7 @@ dnl as a requirement so that is gets called before LIBTOOL
dnl because libtools 'AC_REQUIRE' names are right after this one, before dnl because libtools 'AC_REQUIRE' names are right after this one, before
dnl this function contents. dnl this function contents.
AC_REQUIRE([ACX_LIBTOOL_C_PRE]) AC_REQUIRE([ACX_LIBTOOL_C_PRE])
AC_PROG_LIBTOOL LT_INIT
]) ])
dnl Detect if u_char type is defined, otherwise define it. dnl Detect if u_char type is defined, otherwise define it.
@ -673,17 +670,17 @@ AC_DEFUN([ACX_SSL_CHECKS], [
ACX_RUNTIME_PATH_ADD([$ssldir/lib]) ACX_RUNTIME_PATH_ADD([$ssldir/lib])
fi fi
AC_MSG_CHECKING([for HMAC_Update in -lcrypto]) AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
LIBS="$LIBS -lcrypto" LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto" LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
AC_TRY_LINK(, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
], [ ]])],[
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_HMAC_UPDATE], 1, AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have HMAC_Update]) [If you have EVP_sha256])
], [ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
# check if -lwsock32 or -lgdi32 are needed. # check if -lwsock32 or -lgdi32 are needed.
BAKLIBS="$LIBS" BAKLIBS="$LIBS"
@ -691,12 +688,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBS="$LIBS -lgdi32 -lws2_32" LIBS="$LIBS -lgdi32 -lws2_32"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32" LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32]) AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
AC_TRY_LINK([], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
],[ ]])],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1, AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have HMAC_Update]) [If you have EVP_sha256])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@ -705,12 +702,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBS="$LIBS -ldl" LIBS="$LIBS -ldl"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl" LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl]) AC_MSG_CHECKING([if -lcrypto needs -ldl])
AC_TRY_LINK([], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
],[ ]])],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1, AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have HMAC_Update]) [If you have EVP_sha256])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@ -719,12 +716,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBS="$LIBS -ldl -pthread" LIBS="$LIBS -ldl -pthread"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread" LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread]) AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
AC_TRY_LINK([], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
],[ ]])],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1, AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have HMAC_Update]) [If you have EVP_sha256])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@ -749,8 +746,7 @@ dnl Checks main header files of SSL.
dnl dnl
AC_DEFUN([ACX_WITH_SSL], AC_DEFUN([ACX_WITH_SSL],
[ [
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname], AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[ /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
],[ ],[
withval="yes" withval="yes"
@ -768,8 +764,7 @@ dnl Checks main header files of SSL.
dnl dnl
AC_DEFUN([ACX_WITH_SSL_OPTIONAL], AC_DEFUN([ACX_WITH_SSL_OPTIONAL],
[ [
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname], AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[ /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
],[ ],[
withval="yes" withval="yes"
@ -1061,7 +1056,7 @@ dnl defines MKDIR_HAS_ONE_ARG
AC_DEFUN([ACX_MKDIR_ONE_ARG], AC_DEFUN([ACX_MKDIR_ONE_ARG],
[ [
AC_MSG_CHECKING([whether mkdir has one arg]) AC_MSG_CHECKING([whether mkdir has one arg])
AC_TRY_COMPILE([ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
@ -1070,14 +1065,12 @@ AC_TRY_COMPILE([
#ifdef HAVE_SYS_STAT_H #ifdef HAVE_SYS_STAT_H
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
], [ ]], [[
(void)mkdir("directory"); (void)mkdir("directory");
], ]])],[AC_MSG_RESULT(yes)
AC_MSG_RESULT(yes)
AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.]) AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.])
, ],[AC_MSG_RESULT(no)
AC_MSG_RESULT(no) ])
)
])dnl end of ACX_MKDIR_ONE_ARG ])dnl end of ACX_MKDIR_ONE_ARG
dnl Check for ioctlsocket function. works on mingw32 too. dnl Check for ioctlsocket function. works on mingw32 too.

View file

@ -85,11 +85,11 @@ $ac_distutils_result])
LIBS="$LIBS $PYTHON_LDFLAGS" LIBS="$LIBS $PYTHON_LDFLAGS"
CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
AC_TRY_LINK([ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <Python.h> #include <Python.h>
],[ ]],[[
Py_Initialize(); Py_Initialize();
],[pythonexists=yes],[pythonexists=no]) ]])],[pythonexists=yes],[pythonexists=no])
AC_MSG_RESULT([$pythonexists]) AC_MSG_RESULT([$pythonexists])

View file

@ -465,6 +465,7 @@ packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
data->rr_ttl[i] -= subtract; data->rr_ttl[i] -= subtract;
else data->rr_ttl[i] = 0; else data->rr_ttl[i] = 0;
} }
data->ttl_add = (subtract < data->ttl_add) ? (data->ttl_add - subtract) : 0;
} }
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is /* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is

View file

@ -113,6 +113,10 @@
don't. */ don't. */
#undef HAVE_DECL_INET_PTON #undef HAVE_DECL_INET_PTON
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
and to 0 if you don't. */
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you /* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */ don't. */
#undef HAVE_DECL_NID_ED25519 #undef HAVE_DECL_NID_ED25519
@ -221,6 +225,9 @@
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ /* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#undef HAVE_EVP_ENCRYPTINIT_EX #undef HAVE_EVP_ENCRYPTINIT_EX
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */ /* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#undef HAVE_EVP_MD_CTX_NEW #undef HAVE_EVP_MD_CTX_NEW
@ -269,6 +276,9 @@
/* Define to 1 if you have the `getentropy' function. */ /* Define to 1 if you have the `getentropy' function. */
#undef HAVE_GETENTROPY #undef HAVE_GETENTROPY
/* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS
/* Define to 1 if you have the <getopt.h> header file. */ /* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H #undef HAVE_GETOPT_H
@ -296,12 +306,12 @@
/* Define to 1 if you have the `HMAC_Init_ex' function. */ /* Define to 1 if you have the `HMAC_Init_ex' function. */
#undef HAVE_HMAC_INIT_EX #undef HAVE_HMAC_INIT_EX
/* If you have HMAC_Update */
#undef HAVE_HMAC_UPDATE
/* If we have htobe64 */ /* If we have htobe64 */
#undef HAVE_HTOBE64 #undef HAVE_HTOBE64
/* Define to 1 if you have the <ifaddrs.h> header file. */
#undef HAVE_IFADDRS_H
/* Define to 1 if you have the `inet_aton' function. */ /* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON #undef HAVE_INET_ATON
@ -374,6 +384,15 @@
/* Define to 1 if you have the <net/pfvar.h> header file. */ /* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H #undef HAVE_NET_PFVAR_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define this to use nghttp2 client. */
#undef HAVE_NGHTTP2
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
#undef HAVE_NGHTTP2_NGHTTP2_H
/* Use libnss for crypto */ /* Use libnss for crypto */
#undef HAVE_NSS #undef HAVE_NSS
@ -389,6 +408,9 @@
/* Define to 1 if you have the <openssl/conf.h> header file. */ /* Define to 1 if you have the <openssl/conf.h> header file. */
#undef HAVE_OPENSSL_CONF_H #undef HAVE_OPENSSL_CONF_H
/* Define to 1 if you have the <openssl/core_names.h> header file. */
#undef HAVE_OPENSSL_CORE_NAMES_H
/* Define to 1 if you have the <openssl/dh.h> header file. */ /* Define to 1 if you have the <openssl/dh.h> header file. */
#undef HAVE_OPENSSL_DH_H #undef HAVE_OPENSSL_DH_H
@ -497,14 +519,18 @@
/* Define if you have the SSL libraries installed. */ /* Define if you have the SSL libraries installed. */
#undef HAVE_SSL #undef HAVE_SSL
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */ /* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
#undef HAVE_SSL_CTX_SET_CIPHERSUITES #undef HAVE_SSL_CTX_SET_CIPHERSUITES
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */ /* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL #undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */ /* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_evp_cb'
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
/* Define to 1 if you have the `SSL_get0_peername' function. */ /* Define to 1 if you have the `SSL_get0_peername' function. */
#undef HAVE_SSL_GET0_PEERNAME #undef HAVE_SSL_GET0_PEERNAME
@ -572,6 +598,9 @@
/* Define to 1 if you have the <sys/resource.h> header file. */ /* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H #undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/sha2.h> header file. */ /* Define to 1 if you have the <sys/sha2.h> header file. */
#undef HAVE_SYS_SHA2_H #undef HAVE_SYS_SHA2_H
@ -721,7 +750,8 @@
your system. */ your system. */
#undef PTHREAD_CREATE_JOINABLE #undef PTHREAD_CREATE_JOINABLE
/* Define as the return type of signal handlers (`int' or `void'). */ /* Return type of signal handlers, but autoconf 2.70 says 'your code may
safely assume C89 semantics that RETSIGTYPE is void.' */
#undef RETSIGTYPE #undef RETSIGTYPE
/* if REUSEPORT is enabled by default */ /* if REUSEPORT is enabled by default */
@ -869,6 +899,9 @@
/* the version of the windows API enabled */ /* the version of the windows API enabled */
#undef WINVER #undef WINVER
/* Define if you want dynlib module. */
#undef WITH_DYNLIBMODULE
/* Define if you want Python module. */ /* Define if you want Python module. */
#undef WITH_PYTHONMODULE #undef WITH_PYTHONMODULE
@ -1354,6 +1387,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_PORT 53 #define UNBOUND_DNS_PORT 53
/** default port for DNS over TLS traffic. */ /** default port for DNS over TLS traffic. */
#define UNBOUND_DNS_OVER_TLS_PORT 853 #define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for unbound control traffic, registered port with IANA, /** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */ ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953 #define UNBOUND_CONTROL_PORT 8953

350
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.10.1. # Generated by GNU Autoconf 2.69 for unbound 1.13.1.
# #
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>. # Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
# #
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='unbound' PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound' PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.10.1' PACKAGE_VERSION='1.13.1'
PACKAGE_STRING='unbound 1.10.1' PACKAGE_STRING='unbound 1.13.1'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL='' PACKAGE_URL=''
@ -649,6 +649,7 @@ ENABLE_DNSCRYPT
ENABLE_DNSCRYPT_XCHACHA20 ENABLE_DNSCRYPT_XCHACHA20
DNSTAP_OBJ DNSTAP_OBJ
DNSTAP_SRC DNSTAP_SRC
DNSTAP_SOCKET_TESTBIN
DNSTAP_SOCKET_PATH DNSTAP_SOCKET_PATH
opt_dnstap_socket_path opt_dnstap_socket_path
ENABLE_DNSTAP ENABLE_DNSTAP
@ -700,6 +701,10 @@ PYTHON_LDFLAGS
PYTHON_CPPFLAGS PYTHON_CPPFLAGS
PYTHON PYTHON
PYTHON_VERSION PYTHON_VERSION
DYNLIBMOD_EXTRALIBS
DYNLIBMOD_HEADER
DYNLIBMOD_OBJ
WITH_DYNLIBMODULE
PTHREAD_CFLAGS_ONLY PTHREAD_CFLAGS_ONLY
PTHREAD_CFLAGS PTHREAD_CFLAGS
PTHREAD_LIBS PTHREAD_LIBS
@ -856,6 +861,7 @@ enable_alloc_nonregional
with_pthreads with_pthreads
with_solaris_threads with_solaris_threads
with_syslog_facility with_syslog_facility
with_dynlibmodule
with_pyunbound with_pyunbound
with_pythonmodule with_pythonmodule
enable_swig_version_check enable_swig_version_check
@ -877,6 +883,7 @@ enable_tfo_server
with_libevent with_libevent
with_libexpat with_libexpat
with_libhiredis with_libhiredis
with_libnghttp2
enable_static_exe enable_static_exe
enable_fully_static enable_fully_static
enable_lock_checks enable_lock_checks
@ -1453,7 +1460,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures unbound 1.10.1 to adapt to many kinds of systems. \`configure' configures unbound 1.13.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1518,7 +1525,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.10.1:";; short | recursive ) echo "Configuration of unbound 1.13.1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1618,6 +1625,8 @@ Optional Packages:
--with-solaris-threads use solaris native thread library. --with-solaris-threads use solaris native thread library.
--with-syslog-facility=LOCAL0 - LOCAL7 --with-syslog-facility=LOCAL0 - LOCAL7
set SYSLOG_FACILITY, default DAEMON set SYSLOG_FACILITY, default DAEMON
--with-dynlibmodule build dynamic library module, or
--without-dynlibmodule to disable it. (default=no)
--with-pyunbound build PyUnbound, or --without-pyunbound to skip it. --with-pyunbound build PyUnbound, or --without-pyunbound to skip it.
(default=no) (default=no)
--with-pythonmodule build Python module, or --without-pythonmodule to --with-pythonmodule build Python module, or --without-pythonmodule to
@ -1635,6 +1644,7 @@ Optional Packages:
outgoing port ranges. outgoing port ranges.
--with-libexpat=path specify explicit path for libexpat. --with-libexpat=path specify explicit path for libexpat.
--with-libhiredis=path specify explicit path for libhiredis. --with-libhiredis=path specify explicit path for libhiredis.
--with-libnghttp2=path specify explicit path for libnghttp2.
--with-dnstap-socket-path=pathname --with-dnstap-socket-path=pathname
set default dnstap socket path set default dnstap socket path
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap --with-protobuf-c=path Path where protobuf-c is installed, for dnstap
@ -1743,7 +1753,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
unbound configure 1.10.1 unbound configure 1.13.1
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -2452,7 +2462,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.10.1, which was It was created by unbound $as_me 1.13.1, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2802,13 +2812,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1 UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=10 UNBOUND_VERSION_MINOR=13
UNBOUND_VERSION_MICRO=1 UNBOUND_VERSION_MICRO=1
LIBUNBOUND_CURRENT=9 LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=8 LIBUNBOUND_REVISION=12
LIBUNBOUND_AGE=1 LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0 # 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0 # 1.0.1 had 0:13:0
@ -2884,6 +2894,10 @@ LIBUNBOUND_AGE=1
# 1.9.6 had 9:6:1 # 1.9.6 had 9:6:1
# 1.10.0 had 9:7:1 # 1.10.0 had 9:7:1
# 1.10.1 had 9:8:1 # 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1
# 1.12.0 had 9:10:1
# 1.13.0 had 9:11:1
# 1.13.1 had 9:12:1
# Current -- the number of the binary API that we're implementing # Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary # Revision -- which iteration of the implementation of the binary
@ -4164,7 +4178,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
$as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
if test "$ac_cv_header_minix_config_h" = "yes"; then if test "$ac_cv_header_minix_config_h" = "yes"; then
$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h $as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h
@ -8058,7 +8071,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all lt_cv_deplibs_check_method=pass_all
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else else
@ -8420,7 +8433,7 @@ esac
fi fi
: ${AR=ar} : ${AR=ar}
: ${AR_FLAGS=cru} : ${AR_FLAGS=cr}
@ -8963,11 +8976,8 @@ _LT_EOF
test $ac_status = 0; }; then test $ac_status = 0; }; then
# Now try to grab the symbols. # Now try to grab the symbols.
nlist=conftest.nm nlist=conftest.nm
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
(eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && test -s "$nlist"; then
# Try sorting and uniquifying the output. # Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist" mv -f "$nlist"T "$nlist"
@ -10186,8 +10196,8 @@ int forced_loaded() { return 2;}
_LT_EOF _LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
echo "$AR cru libconftest.a conftest.o" >&5 echo "$AR cr libconftest.a conftest.o" >&5
$AR cru libconftest.a conftest.o 2>&5 $AR cr libconftest.a conftest.o 2>&5
echo "$RANLIB libconftest.a" >&5 echo "$RANLIB libconftest.a" >&5
$RANLIB libconftest.a 2>&5 $RANLIB libconftest.a 2>&5
cat > conftest.c << _LT_EOF cat > conftest.c << _LT_EOF
@ -11047,6 +11057,12 @@ lt_prog_compiler_static=
lt_prog_compiler_pic='-KPIC' lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-static' lt_prog_compiler_static='-static'
;; ;;
# flang / f18. f95 an alias for gfortran or flang on Debian
flang* | f18* | f95*)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-fPIC'
lt_prog_compiler_static='-static'
;;
# icc used to be incompatible with GCC. # icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more. # ICC 10 doesn't accept -KPIC any more.
icc* | ifort*) icc* | ifort*)
@ -11523,6 +11539,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
openbsd* | bitrig*) openbsd* | bitrig*)
with_gnu_ld=no with_gnu_ld=no
;; ;;
linux* | k*bsd*-gnu | gnu*)
link_all_deplibs=no
;;
esac esac
ld_shlibs=yes ld_shlibs=yes
@ -11777,7 +11796,7 @@ _LT_EOF
fi fi
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc= wlarc=
@ -12447,6 +12466,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
if test yes = "$lt_cv_irix_exported_symbol"; then if test yes = "$lt_cv_irix_exported_symbol"; then
archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi fi
link_all_deplibs=no
else else
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@ -12468,7 +12488,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
esac esac
;; ;;
netbsd*) netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else else
@ -13563,9 +13583,6 @@ fi
# before this can be enabled. # before this can be enabled.
hardcode_into_libs=yes hardcode_into_libs=yes
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
# Ideally, we could use ldconfig to report *all* directores which are # Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not # searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command # being certain /sbin/ldconfig is available, command
@ -13574,7 +13591,7 @@ fi
# appending ld.so.conf contents (and includes) to the search path. # appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi fi
# We used to test for /lib/ld.so.1 and disable shared libraries on # We used to test for /lib/ld.so.1 and disable shared libraries on
@ -13586,6 +13603,18 @@ fi
dynamic_linker='GNU/Linux ld.so' dynamic_linker='GNU/Linux ld.so'
;; ;;
netbsdelf*-gnu)
version_type=linux
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='NetBSD ld.elf_so'
;;
netbsd*) netbsd*)
version_type=sunos version_type=sunos
need_lib_prefix=no need_lib_prefix=no
@ -14717,7 +14746,7 @@ $as_echo "no" >&6; }
fi fi
# Checks for header files. # Checks for header files.
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
@ -14731,6 +14760,34 @@ fi
done done
# net/if.h portability for Darwin see:
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
for ac_header in net/if.h
do :
ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
"
if test "x$ac_cv_header_net_if_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_NET_IF_H 1
_ACEOF
fi
done
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
for ac_header in TargetConditionals.h for ac_header in TargetConditionals.h
@ -15539,38 +15596,8 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
$as_echo_n "checking return type of signal handlers... " >&6; }
if ${ac_cv_type_signal+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <signal.h>
int
main ()
{
return *(signal (0, 0)) (0) == 1;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_type_signal=int
else
ac_cv_type_signal=void
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
$as_echo "$ac_cv_type_signal" >&6; }
cat >>confdefs.h <<_ACEOF
#define RETSIGTYPE $ac_cv_type_signal
_ACEOF
$as_echo "#define RETSIGTYPE void" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
@ -17188,6 +17215,93 @@ cat >>confdefs.h <<_ACEOF
_ACEOF _ACEOF
# Check for dynamic library module
# Check whether --with-dynlibmodule was given.
if test "${with_dynlibmodule+set}" = set; then :
withval=$with_dynlibmodule;
else
withval="no"
fi
if test x_$withval != x_no; then
$as_echo "#define WITH_DYNLIBMODULE 1" >>confdefs.h
WITH_DYNLIBMODULE=yes
DYNLIBMOD_OBJ="dynlibmod.lo"
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
if test $on_mingw = "no"; then
# link with -ldl if not already there, for all executables because
# dlopen call is in the dynlib module. For unbound executable, also
# export symbols.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
$as_echo_n "checking for library containing dlopen... " >&6; }
if ${ac_cv_search_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char dlopen ();
int
main ()
{
return dlopen ();
;
return 0;
}
_ACEOF
for ac_lib in '' dl; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_dlopen=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_dlopen+:} false; then :
break
fi
done
if ${ac_cv_search_dlopen+:} false; then :
else
ac_cv_search_dlopen=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
$as_echo "$ac_cv_search_dlopen" >&6; }
ac_res=$ac_cv_search_dlopen
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
DYNLIBMOD_EXTRALIBS="-export-dynamic"
else
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.dll.a"
fi
fi
# Check for PyUnbound # Check for PyUnbound
# Check whether --with-pyunbound was given. # Check whether --with-pyunbound was given.
@ -17906,8 +18020,8 @@ $as_echo "found in $ssldir" >&6; }
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for HMAC_Update in -lcrypto" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_sha256 in -lcrypto" >&5
$as_echo_n "checking for HMAC_Update in -lcrypto... " >&6; } $as_echo_n "checking for EVP_sha256 in -lcrypto... " >&6; }
LIBS="$LIBS -lcrypto" LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto" LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@ -17917,8 +18031,8 @@ int
main () main ()
{ {
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
; ;
return 0; return 0;
@ -17929,7 +18043,7 @@ if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; } $as_echo "yes" >&6; }
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h $as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
else else
@ -17950,8 +18064,8 @@ int
main () main ()
{ {
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
; ;
return 0; return 0;
@ -17960,7 +18074,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then : if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h $as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; } $as_echo "yes" >&6; }
@ -17982,8 +18096,8 @@ int
main () main ()
{ {
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
; ;
return 0; return 0;
@ -17992,7 +18106,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then : if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h $as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; } $as_echo "yes" >&6; }
@ -18014,8 +18128,8 @@ int
main () main ()
{ {
int HMAC_Update(void); int EVP_sha256(void);
(void)HMAC_Update(); (void)EVP_sha256();
; ;
return 0; return 0;
@ -18024,7 +18138,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then : if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h $as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; } $as_echo "yes" >&6; }
@ -18203,17 +18317,13 @@ $as_echo_n "checking if libssl needs -lcrypt32... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char HMAC_Update ();
int int
main () main ()
{ {
return HMAC_Update ();
int EVP_sha256(void);
(void)EVP_sha256();
; ;
return 0; return 0;
} }
@ -18290,7 +18400,7 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; } $as_echo "no" >&6; }
fi fi
for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
@ -18304,7 +18414,7 @@ fi
done done
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -18320,7 +18430,7 @@ done
# these check_funcs need -lssl # these check_funcs need -lssl
BAKLIBS="$LIBS" BAKLIBS="$LIBS"
LIBS="-lssl $LIBS" LIBS="-lssl $LIBS"
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -19632,6 +19742,70 @@ _ACEOF
fi fi
# nghttp2
# Check whether --with-libnghttp2 was given.
if test "${with_libnghttp2+set}" = set; then :
withval=$with_libnghttp2;
else
withval="no"
fi
found_libnghttp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnghttp2" >&5
$as_echo_n "checking for libnghttp2... " >&6; }
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/nghttp2/nghttp2.h"; then
found_libnghttp2="yes"
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
$as_echo "found in $dir" >&6; }
$as_echo "#define HAVE_NGHTTP2 1" >>confdefs.h
LIBS="$LIBS -lnghttp2"
break;
fi
done
if test x_$found_libnghttp2 != x_yes; then
as_fn_error $? "Could not find libnghttp2, nghttp2.h" "$LINENO" 5
fi
for ac_header in nghttp2/nghttp2.h
do :
ac_fn_c_check_header_compile "$LINENO" "nghttp2/nghttp2.h" "ac_cv_header_nghttp2_nghttp2_h" "$ac_includes_default
"
if test "x$ac_cv_header_nghttp2_nghttp2_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_NGHTTP2_NGHTTP2_H 1
_ACEOF
fi
done
ac_fn_c_check_decl "$LINENO" "nghttp2_session_server_new" "ac_cv_have_decl_nghttp2_session_server_new" "$ac_includes_default
#include <nghttp2/nghttp2.h>
"
if test "x$ac_cv_have_decl_nghttp2_session_server_new" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW $ac_have_decl
_ACEOF
fi
# set static linking for uninstalled libraries if requested # set static linking for uninstalled libraries if requested
staticexe="" staticexe=""
@ -19651,6 +19825,7 @@ if test x_$enable_static_exe = x_yes; then
LIBS="$LIBS -lgdi32" LIBS="$LIBS -lgdi32"
fi fi
LIBS="$LIBS -lz" LIBS="$LIBS -lz"
LIBS="$LIBS -l:libssp.a"
fi fi
fi fi
@ -19670,6 +19845,7 @@ if test x_$enable_fully_static = x_yes; then
LIBS="$LIBS -lgdi32" LIBS="$LIBS -lgdi32"
fi fi
LIBS="$LIBS -lz" LIBS="$LIBS -lz"
LIBS="$LIBS -l:libssp.a"
fi fi
fi fi
@ -20187,7 +20363,7 @@ if test "$ac_res" != no; then :
fi fi
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -21077,6 +21253,7 @@ _ACEOF
DNSTAP_SOCKET_PATH="$hdr_dnstap_socket_path" DNSTAP_SOCKET_PATH="$hdr_dnstap_socket_path"
DNSTAP_SOCKET_TESTBIN='unbound-dnstap-socket$(EXEEXT)'
DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c" DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"
@ -21604,7 +21781,7 @@ _ACEOF
version=1.10.1 version=1.13.1
date=`date +'%b %e, %Y'` date=`date +'%b %e, %Y'`
@ -22123,7 +22300,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by unbound $as_me 1.10.1, which was This file was extended by unbound $as_me 1.13.1, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -22189,7 +22366,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
unbound config.status 1.10.1 unbound config.status 1.13.1
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
@ -23182,7 +23359,6 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
cat <<_LT_EOF >> "$cfgfile" cat <<_LT_EOF >> "$cfgfile"
#! $SHELL #! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION # Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh. # NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services. # Provide generalized library-building support services.

View file

@ -1,6 +1,6 @@
# -*- Autoconf -*- # -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ(2.56) AC_PREREQ([2.56])
sinclude(acx_nlnetlabs.m4) sinclude(acx_nlnetlabs.m4)
sinclude(ax_pthread.m4) sinclude(ax_pthread.m4)
sinclude(acx_python.m4) sinclude(acx_python.m4)
@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing # must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1]) m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[10]) m4_define([VERSION_MINOR],[13])
m4_define([VERSION_MICRO],[1]) m4_define([VERSION_MICRO],[1])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound) AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9 LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=8 LIBUNBOUND_REVISION=12
LIBUNBOUND_AGE=1 LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0 # 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0 # 1.0.1 had 0:13:0
@ -94,6 +94,10 @@ LIBUNBOUND_AGE=1
# 1.9.6 had 9:6:1 # 1.9.6 had 9:6:1
# 1.10.0 had 9:7:1 # 1.10.0 had 9:7:1
# 1.10.1 had 9:8:1 # 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1
# 1.12.0 had 9:10:1
# 1.13.0 had 9:11:1
# 1.13.1 had 9:12:1
# Current -- the number of the binary API that we're implementing # Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary # Revision -- which iteration of the implementation of the binary
@ -122,7 +126,7 @@ cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure]) AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure])
CFLAGS="$CFLAGS" CFLAGS="$CFLAGS"
AC_AIX AC_USE_SYSTEM_EXTENSIONS
if test "$ac_cv_header_minix_config_h" = "yes"; then if test "$ac_cv_header_minix_config_h" = "yes"; then
AC_DEFINE(_NETBSD_SOURCE,1, [Enable for compile on Minix]) AC_DEFINE(_NETBSD_SOURCE,1, [Enable for compile on Minix])
fi fi
@ -163,8 +167,7 @@ else
ub_conf_file="C:\\Program Files\\Unbound\\service.conf" ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
fi fi
AC_ARG_WITH([conf_file], AC_ARG_WITH([conf_file],
AC_HELP_STRING([--with-conf-file=path], AS_HELP_STRING([--with-conf-file=path],[Pathname to the Unbound configuration file]),
[Pathname to the Unbound configuration file]),
[ub_conf_file="$withval"]) [ub_conf_file="$withval"])
AC_SUBST(ub_conf_file) AC_SUBST(ub_conf_file)
ACX_ESCAPE_BACKSLASH($ub_conf_file, hdr_config) ACX_ESCAPE_BACKSLASH($ub_conf_file, hdr_config)
@ -174,8 +177,7 @@ AC_SUBST(ub_conf_dir)
# Determine run, chroot directory and pidfile locations # Determine run, chroot directory and pidfile locations
AC_ARG_WITH(run-dir, AC_ARG_WITH(run-dir,
AC_HELP_STRING([--with-run-dir=path], AS_HELP_STRING([--with-run-dir=path],[set default directory to chdir to (by default dir part of cfg file)]),
[set default directory to chdir to (by default dir part of cfg file)]),
UNBOUND_RUN_DIR="$withval", UNBOUND_RUN_DIR="$withval",
if test $on_mingw = no; then if test $on_mingw = no; then
UNBOUND_RUN_DIR=`dirname "$ub_conf_file"` UNBOUND_RUN_DIR=`dirname "$ub_conf_file"`
@ -188,8 +190,7 @@ ACX_ESCAPE_BACKSLASH($UNBOUND_RUN_DIR, hdr_run)
AC_DEFINE_UNQUOTED(RUN_DIR, ["$hdr_run"], [Directory to chdir to]) AC_DEFINE_UNQUOTED(RUN_DIR, ["$hdr_run"], [Directory to chdir to])
AC_ARG_WITH(chroot-dir, AC_ARG_WITH(chroot-dir,
AC_HELP_STRING([--with-chroot-dir=path], AS_HELP_STRING([--with-chroot-dir=path],[set default directory to chroot to (by default same as run-dir)]),
[set default directory to chroot to (by default same as run-dir)]),
UNBOUND_CHROOT_DIR="$withval", UNBOUND_CHROOT_DIR="$withval",
if test $on_mingw = no; then if test $on_mingw = no; then
UNBOUND_CHROOT_DIR="$UNBOUND_RUN_DIR" UNBOUND_CHROOT_DIR="$UNBOUND_RUN_DIR"
@ -202,16 +203,14 @@ ACX_ESCAPE_BACKSLASH($UNBOUND_CHROOT_DIR, hdr_chroot)
AC_DEFINE_UNQUOTED(CHROOT_DIR, ["$hdr_chroot"], [Directory to chroot to]) AC_DEFINE_UNQUOTED(CHROOT_DIR, ["$hdr_chroot"], [Directory to chroot to])
AC_ARG_WITH(share-dir, AC_ARG_WITH(share-dir,
AC_HELP_STRING([--with-share-dir=path], AS_HELP_STRING([--with-share-dir=path],[set default directory with shared data (by default same as share/unbound)]),
[set default directory with shared data (by default same as share/unbound)]),
UNBOUND_SHARE_DIR="$withval", UNBOUND_SHARE_DIR="$withval",
UNBOUND_SHARE_DIR="$UNBOUND_RUN_DIR") UNBOUND_SHARE_DIR="$UNBOUND_RUN_DIR")
AC_SUBST(UNBOUND_SHARE_DIR) AC_SUBST(UNBOUND_SHARE_DIR)
AC_DEFINE_UNQUOTED(SHARE_DIR, ["$UNBOUND_SHARE_DIR"], [Shared data]) AC_DEFINE_UNQUOTED(SHARE_DIR, ["$UNBOUND_SHARE_DIR"], [Shared data])
AC_ARG_WITH(pidfile, AC_ARG_WITH(pidfile,
AC_HELP_STRING([--with-pidfile=filename], AS_HELP_STRING([--with-pidfile=filename],[set default pathname to unbound pidfile (default run-dir/unbound.pid)]),
[set default pathname to unbound pidfile (default run-dir/unbound.pid)]),
UNBOUND_PIDFILE="$withval", UNBOUND_PIDFILE="$withval",
if test $on_mingw = no; then if test $on_mingw = no; then
UNBOUND_PIDFILE="$UNBOUND_RUN_DIR/unbound.pid" UNBOUND_PIDFILE="$UNBOUND_RUN_DIR/unbound.pid"
@ -224,8 +223,7 @@ ACX_ESCAPE_BACKSLASH($UNBOUND_PIDFILE, hdr_pid)
AC_DEFINE_UNQUOTED(PIDFILE, ["$hdr_pid"], [default pidfile location]) AC_DEFINE_UNQUOTED(PIDFILE, ["$hdr_pid"], [default pidfile location])
AC_ARG_WITH(rootkey-file, AC_ARG_WITH(rootkey-file,
AC_HELP_STRING([--with-rootkey-file=filename], AS_HELP_STRING([--with-rootkey-file=filename],[set default pathname to root key file (default run-dir/root.key). This file is read and written.]),
[set default pathname to root key file (default run-dir/root.key). This file is read and written.]),
UNBOUND_ROOTKEY_FILE="$withval", UNBOUND_ROOTKEY_FILE="$withval",
if test $on_mingw = no; then if test $on_mingw = no; then
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key" UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
@ -238,8 +236,7 @@ ACX_ESCAPE_BACKSLASH($UNBOUND_ROOTKEY_FILE, hdr_rkey)
AC_DEFINE_UNQUOTED(ROOT_ANCHOR_FILE, ["$hdr_rkey"], [default rootkey location]) AC_DEFINE_UNQUOTED(ROOT_ANCHOR_FILE, ["$hdr_rkey"], [default rootkey location])
AC_ARG_WITH(rootcert-file, AC_ARG_WITH(rootcert-file,
AC_HELP_STRING([--with-rootcert-file=filename], AS_HELP_STRING([--with-rootcert-file=filename],[set default pathname to root update certificate file (default run-dir/icannbundle.pem). This file need not exist if you are content with the builtin.]),
[set default pathname to root update certificate file (default run-dir/icannbundle.pem). This file need not exist if you are content with the builtin.]),
UNBOUND_ROOTCERT_FILE="$withval", UNBOUND_ROOTCERT_FILE="$withval",
if test $on_mingw = no; then if test $on_mingw = no; then
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem" UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
@ -252,8 +249,7 @@ ACX_ESCAPE_BACKSLASH($UNBOUND_ROOTCERT_FILE, hdr_rpem)
AC_DEFINE_UNQUOTED(ROOT_CERT_FILE, ["$hdr_rpem"], [default rootcert location]) AC_DEFINE_UNQUOTED(ROOT_CERT_FILE, ["$hdr_rpem"], [default rootcert location])
AC_ARG_WITH(username, AC_ARG_WITH(username,
AC_HELP_STRING([--with-username=user], AS_HELP_STRING([--with-username=user],[set default user that unbound changes to (default user is unbound)]),
[set default user that unbound changes to (default user is unbound)]),
UNBOUND_USERNAME="$withval", UNBOUND_USERNAME="$withval",
UNBOUND_USERNAME="unbound") UNBOUND_USERNAME="unbound")
AC_SUBST(UNBOUND_USERNAME) AC_SUBST(UNBOUND_USERNAME)
@ -265,7 +261,7 @@ AC_DEFINE_UNQUOTED(RSRC_PACKAGE_VERSION, [$wnvs], [version number for resource f
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
AC_LANG_C AC_LANG([C])
# allow user to override the -g -O2 flags. # allow user to override the -g -O2 flags.
default_cflags=no default_cflags=no
if test "x$CFLAGS" = "x" ; then if test "x$CFLAGS" = "x" ; then
@ -278,8 +274,8 @@ ACX_DEPFLAG
ACX_DETERMINE_EXT_FLAGS_UNBOUND ACX_DETERMINE_EXT_FLAGS_UNBOUND
# debug mode flags warnings # debug mode flags warnings
AC_ARG_ENABLE(checking, AC_HELP_STRING([--enable-checking], [Enable warnings, asserts, makefile-dependencies])) AC_ARG_ENABLE(checking, AS_HELP_STRING([--enable-checking],[Enable warnings, asserts, makefile-dependencies]))
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [same as enable-checking])) AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],[same as enable-checking]))
if test "$enable_debug" = "yes"; then debug_enabled="$enable_debug"; if test "$enable_debug" = "yes"; then debug_enabled="$enable_debug";
else debug_enabled="$enable_checking"; fi else debug_enabled="$enable_checking"; fi
AC_SUBST(debug_enabled) AC_SUBST(debug_enabled)
@ -313,14 +309,11 @@ AC_DEFUN([CHECK_WEAK_ATTRIBUTE],
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "weak" attribute) AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "weak" attribute)
AC_CACHE_VAL(ac_cv_c_weak_attribute, AC_CACHE_VAL(ac_cv_c_weak_attribute,
[ac_cv_c_weak_attribute=no [ac_cv_c_weak_attribute=no
AC_TRY_COMPILE( AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
[ #include <stdio.h>
__attribute__((weak)) void f(int x) { printf("%d", x); } __attribute__((weak)) void f(int x) { printf("%d", x); }
], [ ]], [[
f(1); f(1);
], ]])],[ac_cv_c_weak_attribute="yes"],[ac_cv_c_weak_attribute="no"])
[ac_cv_c_weak_attribute="yes"],
[ac_cv_c_weak_attribute="no"])
]) ])
AC_MSG_RESULT($ac_cv_c_weak_attribute) AC_MSG_RESULT($ac_cv_c_weak_attribute)
@ -337,14 +330,11 @@ AC_DEFUN([CHECK_NORETURN_ATTRIBUTE],
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute) AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute)
AC_CACHE_VAL(ac_cv_c_noreturn_attribute, AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
[ac_cv_c_noreturn_attribute=no [ac_cv_c_noreturn_attribute=no
AC_TRY_COMPILE( AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
[ #include <stdio.h>
__attribute__((noreturn)) void f(int x) { printf("%d", x); } __attribute__((noreturn)) void f(int x) { printf("%d", x); }
], [ ]], [[
f(1); f(1);
], ]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"])
[ac_cv_c_noreturn_attribute="yes"],
[ac_cv_c_noreturn_attribute="no"])
]) ])
AC_MSG_RESULT($ac_cv_c_noreturn_attribute) AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
@ -382,7 +372,7 @@ EOF
fi fi
]) ])
AC_PROG_LEX AC_PROG_LEX([noyywrap])
if test "$LEX" != "" -a "$LEX" != ":"; then if test "$LEX" != "" -a "$LEX" != ":"; then
ACX_YYLEX_DESTROY ACX_YYLEX_DESTROY
fi fi
@ -397,7 +387,23 @@ ACX_LIBTOOL_C_ONLY
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
# Checks for header files. # Checks for header files.
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h],,, [AC_INCLUDES_DEFAULT])
# net/if.h portability for Darwin see:
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
AC_CHECK_HEADERS([net/if.h],,, [
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
AC_CHECK_HEADERS([TargetConditionals.h]) AC_CHECK_HEADERS([TargetConditionals.h])
@ -475,7 +481,7 @@ fi
# check some functions of the OS before linking libs (while still runnable). # check some functions of the OS before linking libs (while still runnable).
AC_FUNC_CHOWN AC_FUNC_CHOWN
AC_FUNC_FORK AC_FUNC_FORK
AC_TYPE_SIGNAL AC_DEFINE(RETSIGTYPE,void,[Return type of signal handlers, but autoconf 2.70 says 'your code may safely assume C89 semantics that RETSIGTYPE is void.'])
AC_FUNC_FSEEKO AC_FUNC_FSEEKO
ACX_SYS_LARGEFILE ACX_SYS_LARGEFILE
ACX_CHECK_NONBLOCKING_BROKEN ACX_CHECK_NONBLOCKING_BROKEN
@ -494,14 +500,11 @@ sinclude(systemd.m4)
# Include systemd.m4 - end # Include systemd.m4 - end
# set memory allocation checking if requested # set memory allocation checking if requested
AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks], AC_ARG_ENABLE(alloc-checks, AS_HELP_STRING([--enable-alloc-checks],[ enable to memory allocation statistics, for debug purposes ]),
[ enable to memory allocation statistics, for debug purposes ]),
, ) , )
AC_ARG_ENABLE(alloc-lite, AC_HELP_STRING([--enable-alloc-lite], AC_ARG_ENABLE(alloc-lite, AS_HELP_STRING([--enable-alloc-lite],[ enable for lightweight alloc assertions, for debug purposes ]),
[ enable for lightweight alloc assertions, for debug purposes ]),
, ) , )
AC_ARG_ENABLE(alloc-nonregional, AC_HELP_STRING([--enable-alloc-nonregional], AC_ARG_ENABLE(alloc-nonregional, AS_HELP_STRING([--enable-alloc-nonregional],[ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes ]),
[ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes ]),
, ) , )
if test x_$enable_alloc_nonregional = x_yes; then if test x_$enable_alloc_nonregional = x_yes; then
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use]) AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
@ -545,8 +548,7 @@ else
# check this first, so that the pthread lib does not get linked in via # check this first, so that the pthread lib does not get linked in via
# libssl or libpython, and thus distorts the tests, and we end up using # libssl or libpython, and thus distorts the tests, and we end up using
# the non-threadsafe C libraries. # the non-threadsafe C libraries.
AC_ARG_WITH(pthreads, AC_HELP_STRING([--with-pthreads], AC_ARG_WITH(pthreads, AS_HELP_STRING([--with-pthreads],[use pthreads library, or --without-pthreads to disable threading support.]),
[use pthreads library, or --without-pthreads to disable threading support.]),
[ ],[ withval="yes" ]) [ ],[ withval="yes" ])
ub_have_pthreads=no ub_have_pthreads=no
if test x_$withval != x_no; then if test x_$withval != x_no; then
@ -593,12 +595,11 @@ int main(void) {return 0;}
fi fi
# check solaris thread library # check solaris thread library
AC_ARG_WITH(solaris-threads, AC_HELP_STRING([--with-solaris-threads], AC_ARG_WITH(solaris-threads, AS_HELP_STRING([--with-solaris-threads],[use solaris native thread library.]), [ ],[ withval="no" ])
[use solaris native thread library.]), [ ],[ withval="no" ])
ub_have_sol_threads=no ub_have_sol_threads=no
if test x_$withval != x_no; then if test x_$withval != x_no; then
if test x_$ub_have_pthreads != x_no; then if test x_$ub_have_pthreads != x_no; then
AC_WARN([Have pthreads already, ignoring --with-solaris-threads]) AC_MSG_WARN([Have pthreads already, ignoring --with-solaris-threads])
else else
AC_SEARCH_LIBS(thr_create, [thread], AC_SEARCH_LIBS(thr_create, [thread],
[ [
@ -608,7 +609,7 @@ if test x_$withval != x_no; then
[CFLAGS="$CFLAGS -D_REENTRANT"]) [CFLAGS="$CFLAGS -D_REENTRANT"])
ub_have_sol_threads=yes ub_have_sol_threads=yes
] , [ ] , [
AC_ERROR([no solaris threads found.]) AC_MSG_ERROR([no solaris threads found.])
]) ])
fi fi
fi fi
@ -616,7 +617,7 @@ fi
fi # end of non-mingw check of thread libraries fi # end of non-mingw check of thread libraries
# Check for SYSLOG_FACILITY # Check for SYSLOG_FACILITY
AC_ARG_WITH(syslog-facility, AC_HELP_STRING([--with-syslog-facility=LOCAL0 - LOCAL7], [ set SYSLOG_FACILITY, default DAEMON ]), AC_ARG_WITH(syslog-facility, AS_HELP_STRING([--with-syslog-facility=LOCAL0 - LOCAL7],[ set SYSLOG_FACILITY, default DAEMON ]),
[ UNBOUND_SYSLOG_FACILITY="$withval" ], []) [ UNBOUND_SYSLOG_FACILITY="$withval" ], [])
case "${UNBOUND_SYSLOG_FACILITY}" in case "${UNBOUND_SYSLOG_FACILITY}" in
@ -627,10 +628,34 @@ case "${UNBOUND_SYSLOG_FACILITY}" in
esac esac
AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON]) AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
# Check for dynamic library module
AC_ARG_WITH(dynlibmodule,
AS_HELP_STRING([--with-dynlibmodule],[build dynamic library module, or --without-dynlibmodule to disable it. (default=no)]),
[], [ withval="no" ])
if test x_$withval != x_no; then
AC_DEFINE(WITH_DYNLIBMODULE, 1, [Define if you want dynlib module.])
WITH_DYNLIBMODULE=yes
AC_SUBST(WITH_DYNLIBMODULE)
DYNLIBMOD_OBJ="dynlibmod.lo"
AC_SUBST(DYNLIBMOD_OBJ)
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
AC_SUBST(DYNLIBMOD_HEADER)
if test $on_mingw = "no"; then
# link with -ldl if not already there, for all executables because
# dlopen call is in the dynlib module. For unbound executable, also
# export symbols.
AC_SEARCH_LIBS([dlopen], [dl])
DYNLIBMOD_EXTRALIBS="-export-dynamic"
else
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.dll.a"
fi
AC_SUBST(DYNLIBMOD_EXTRALIBS)
fi
# Check for PyUnbound # Check for PyUnbound
AC_ARG_WITH(pyunbound, AC_ARG_WITH(pyunbound,
AC_HELP_STRING([--with-pyunbound], AS_HELP_STRING([--with-pyunbound],[build PyUnbound, or --without-pyunbound to skip it. (default=no)]),
[build PyUnbound, or --without-pyunbound to skip it. (default=no)]),
[], [ withval="no" ]) [], [ withval="no" ])
ub_test_python=no ub_test_python=no
@ -642,8 +667,7 @@ fi
# Check for Python module # Check for Python module
AC_ARG_WITH(pythonmodule, AC_ARG_WITH(pythonmodule,
AC_HELP_STRING([--with-pythonmodule], AS_HELP_STRING([--with-pythonmodule],[build Python module, or --without-pythonmodule to disable script engine. (default=no)]),
[build Python module, or --without-pythonmodule to disable script engine. (default=no)]),
[], [ withval="no" ]) [], [ withval="no" ])
ub_with_pythonmod=no ub_with_pythonmod=no
@ -661,7 +685,7 @@ if test x_$ub_test_python != x_no; then
AC_PYTHON_DEVEL AC_PYTHON_DEVEL
if test ! -z "$PYTHON_VERSION"; then if test ! -z "$PYTHON_VERSION"; then
if test `$PYTHON -c "print('$PYTHON_VERSION' >= '2.4.0')"` = "False"; then if test `$PYTHON -c "print('$PYTHON_VERSION' >= '2.4.0')"` = "False"; then
AC_ERROR([Python version >= 2.4.0 is required]) AC_MSG_ERROR([Python version >= 2.4.0 is required])
fi fi
[PY_MAJOR_VERSION="`$PYTHON -c \"import sys; print(sys.version_info[0])\"`"] [PY_MAJOR_VERSION="`$PYTHON -c \"import sys; print(sys.version_info[0])\"`"]
@ -689,7 +713,7 @@ if test x_$ub_test_python != x_no; then
# Check for SWIG # Check for SWIG
ub_have_swig=no ub_have_swig=no
AC_ARG_ENABLE(swig-version-check, AC_HELP_STRING([--disable-swig-version-check], [Disable swig version check to build python modules with older swig even though that is unreliable])) AC_ARG_ENABLE(swig-version-check, AS_HELP_STRING([--disable-swig-version-check],[Disable swig version check to build python modules with older swig even though that is unreliable]))
if test "$enable_swig_version_check" = "yes"; then if test "$enable_swig_version_check" = "yes"; then
AC_PROG_SWIG(2.0.1) AC_PROG_SWIG(2.0.1)
else else
@ -697,7 +721,7 @@ if test x_$ub_test_python != x_no; then
fi fi
AC_MSG_CHECKING(SWIG) AC_MSG_CHECKING(SWIG)
if test ! -x "$SWIG"; then if test ! -x "$SWIG"; then
AC_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound]) AC_MSG_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound])
else else
AC_DEFINE(HAVE_SWIG, 1, [Define if you have Swig libraries and header files.]) AC_DEFINE(HAVE_SWIG, 1, [Define if you have Swig libraries and header files.])
AC_SUBST(swig, "$SWIG") AC_SUBST(swig, "$SWIG")
@ -752,8 +776,7 @@ AC_SUBST(CONFIG_DATE)
# libnss # libnss
USE_NSS="no" USE_NSS="no"
AC_ARG_WITH([nss], AC_HELP_STRING([--with-nss=path], AC_ARG_WITH([nss], AS_HELP_STRING([--with-nss=path],[use libnss instead of openssl, installed at path.]),
[use libnss instead of openssl, installed at path.]),
[ [
USE_NSS="yes" USE_NSS="yes"
AC_DEFINE(HAVE_NSS, 1, [Use libnss for crypto]) AC_DEFINE(HAVE_NSS, 1, [Use libnss for crypto])
@ -775,8 +798,7 @@ AC_ARG_WITH([nss], AC_HELP_STRING([--with-nss=path],
# libnettle # libnettle
USE_NETTLE="no" USE_NETTLE="no"
AC_ARG_WITH([nettle], AC_HELP_STRING([--with-nettle=path], AC_ARG_WITH([nettle], AS_HELP_STRING([--with-nettle=path],[use libnettle as crypto library, installed at path.]),
[use libnettle as crypto library, installed at path.]),
[ [
USE_NETTLE="yes" USE_NETTLE="yes"
AC_DEFINE(HAVE_NETTLE, 1, [Use libnettle for crypto]) AC_DEFINE(HAVE_NETTLE, 1, [Use libnettle for crypto])
@ -808,7 +830,10 @@ AC_SUBST(PC_CRYPTO_DEPENDENCY)
BAKLIBS="$LIBS" BAKLIBS="$LIBS"
LIBS="-lssl $LIBS" LIBS="-lssl $LIBS"
AC_MSG_CHECKING([if libssl needs -lcrypt32]) AC_MSG_CHECKING([if libssl needs -lcrypt32])
AC_TRY_LINK_FUNC([HMAC_Update], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])], [
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
LIBS="$BAKLIBS" LIBS="$BAKLIBS"
], [ ], [
@ -827,13 +852,13 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/
else else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
fi fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback]) AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params])
# these check_funcs need -lssl # these check_funcs need -lssl
BAKLIBS="$LIBS" BAKLIBS="$LIBS"
LIBS="-lssl $LIBS" LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites]) AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb])
LIBS="$BAKLIBS" LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [ AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
@ -896,7 +921,7 @@ fi
AC_SUBST(SSLLIB) AC_SUBST(SSLLIB)
# libbsd # libbsd
AC_ARG_WITH([libbsd], AC_HELP_STRING([--with-libbsd], [Use portable libbsd functions]), [ AC_ARG_WITH([libbsd], AS_HELP_STRING([--with-libbsd],[Use portable libbsd functions]), [
AC_CHECK_HEADERS([bsd/string.h bsd/stdlib.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([bsd/string.h bsd/stdlib.h],,, [AC_INCLUDES_DEFAULT])
if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
@ -909,7 +934,7 @@ AC_ARG_WITH([libbsd], AC_HELP_STRING([--with-libbsd], [Use portable libbsd funct
fi fi
]) ])
AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support])) AC_ARG_ENABLE(sha1, AS_HELP_STRING([--disable-sha1],[Disable SHA1 RRSIG support, does not disable nsec3 support]))
case "$enable_sha1" in case "$enable_sha1" in
no) no)
;; ;;
@ -919,7 +944,7 @@ case "$enable_sha1" in
esac esac
AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support])) AC_ARG_ENABLE(sha2, AS_HELP_STRING([--disable-sha2],[Disable SHA256 and SHA512 RRSIG support]))
case "$enable_sha2" in case "$enable_sha2" in
no) no)
;; ;;
@ -928,7 +953,7 @@ case "$enable_sha2" in
;; ;;
esac esac
AC_ARG_ENABLE(subnet, AC_HELP_STRING([--enable-subnet], [Enable client subnet])) AC_ARG_ENABLE(subnet, AS_HELP_STRING([--enable-subnet],[Enable client subnet]))
case "$enable_subnet" in case "$enable_subnet" in
yes) yes)
AC_DEFINE([CLIENT_SUBNET], [1], [Define this to enable client subnet option.]) AC_DEFINE([CLIENT_SUBNET], [1], [Define this to enable client subnet option.])
@ -1039,7 +1064,7 @@ fi
AC_MSG_RESULT($ac_cv_c_gost_works) AC_MSG_RESULT($ac_cv_c_gost_works)
])dnl ])dnl
AC_ARG_ENABLE(gost, AC_HELP_STRING([--disable-gost], [Disable GOST support])) AC_ARG_ENABLE(gost, AS_HELP_STRING([--disable-gost],[Disable GOST support]))
use_gost="no" use_gost="no"
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
case "$enable_gost" in case "$enable_gost" in
@ -1057,7 +1082,7 @@ case "$enable_gost" in
esac esac
fi dnl !USE_NSS && !USE_NETTLE fi dnl !USE_NSS && !USE_NETTLE
AC_ARG_ENABLE(ecdsa, AC_HELP_STRING([--disable-ecdsa], [Disable ECDSA support])) AC_ARG_ENABLE(ecdsa, AS_HELP_STRING([--disable-ecdsa],[Disable ECDSA support]))
use_ecdsa="no" use_ecdsa="no"
case "$enable_ecdsa" in case "$enable_ecdsa" in
no) no)
@ -1089,7 +1114,7 @@ case "$enable_ecdsa" in
;; ;;
esac esac
AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support])) AC_ARG_ENABLE(dsa, AS_HELP_STRING([--disable-dsa],[Disable DSA support]))
use_dsa="no" use_dsa="no"
case "$enable_dsa" in case "$enable_dsa" in
yes) yes)
@ -1129,7 +1154,7 @@ AC_INCLUDES_DEFAULT
;; ;;
esac esac
AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support])) AC_ARG_ENABLE(ed25519, AS_HELP_STRING([--disable-ed25519],[Disable ED25519 support]))
use_ed25519="no" use_ed25519="no"
case "$enable_ed25519" in case "$enable_ed25519" in
no) no)
@ -1152,7 +1177,7 @@ case "$enable_ed25519" in
;; ;;
esac esac
AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support])) AC_ARG_ENABLE(ed448, AS_HELP_STRING([--disable-ed448],[Disable ED448 support]))
use_ed448="no" use_ed448="no"
case "$enable_ed448" in case "$enable_ed448" in
no) no)
@ -1172,7 +1197,7 @@ case "$enable_ed448" in
;; ;;
esac esac
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h])) AC_ARG_ENABLE(event-api, AS_HELP_STRING([--enable-event-api],[Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
case "$enable_event_api" in case "$enable_event_api" in
yes) yes)
AC_SUBST(UNBOUND_EVENT_INSTALL, [unbound-event-install]) AC_SUBST(UNBOUND_EVENT_INSTALL, [unbound-event-install])
@ -1182,7 +1207,7 @@ case "$enable_event_api" in
;; ;;
esac esac
AC_ARG_ENABLE(tfo-client, AC_HELP_STRING([--enable-tfo-client], [Enable TCP Fast Open for client mode])) AC_ARG_ENABLE(tfo-client, AS_HELP_STRING([--enable-tfo-client],[Enable TCP Fast Open for client mode]))
case "$enable_tfo_client" in case "$enable_tfo_client" in
yes) yes)
case `uname` in case `uname` in
@ -1206,7 +1231,7 @@ case "$enable_tfo_client" in
;; ;;
esac esac
AC_ARG_ENABLE(tfo-server, AC_HELP_STRING([--enable-tfo-server], [Enable TCP Fast Open for server mode])) AC_ARG_ENABLE(tfo-server, AS_HELP_STRING([--enable-tfo-server],[Enable TCP Fast Open for server mode]))
case "$enable_tfo_server" in case "$enable_tfo_server" in
yes) yes)
AC_CHECK_DECL([TCP_FASTOPEN], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support server mode TFO])], [AC_MSG_ERROR([TCP Fast Open is not available for server mode: please rerun without --enable-tfo-server])], [AC_INCLUDES_DEFAULT AC_CHECK_DECL([TCP_FASTOPEN], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support server mode TFO])], [AC_MSG_ERROR([TCP Fast Open is not available for server mode: please rerun without --enable-tfo-server])], [AC_INCLUDES_DEFAULT
@ -1219,8 +1244,7 @@ case "$enable_tfo_server" in
esac esac
# check for libevent # check for libevent
AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname], AC_ARG_WITH(libevent, AS_HELP_STRING([--with-libevent=pathname],[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
[ ],[ with_libevent="no" ]) [ ],[ with_libevent="no" ])
if test "x_$with_libevent" != x_no; then if test "x_$with_libevent" != x_no; then
AC_DEFINE([USE_LIBEVENT], [1], [Define if you enable libevent]) AC_DEFINE([USE_LIBEVENT], [1], [Define if you enable libevent])
@ -1314,8 +1338,7 @@ else
fi fi
# check for libexpat # check for libexpat
AC_ARG_WITH(libexpat, AC_HELP_STRING([--with-libexpat=path], AC_ARG_WITH(libexpat, AS_HELP_STRING([--with-libexpat=path],[specify explicit path for libexpat.]),
[specify explicit path for libexpat.]),
[ ],[ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" ]) [ ],[ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" ])
AC_MSG_CHECKING(for libexpat) AC_MSG_CHECKING(for libexpat)
found_libexpat="no" found_libexpat="no"
@ -1332,7 +1355,7 @@ for dir in $withval ; do
fi fi
done done
if test x_$found_libexpat != x_yes; then if test x_$found_libexpat != x_yes; then
AC_ERROR([Could not find libexpat, expat.h]) AC_MSG_ERROR([Could not find libexpat, expat.h])
fi fi
AC_CHECK_HEADERS([expat.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([expat.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
@ -1340,8 +1363,7 @@ AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
]) ])
# hiredis (redis C client for cachedb) # hiredis (redis C client for cachedb)
AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path], AC_ARG_WITH(libhiredis, AS_HELP_STRING([--with-libhiredis=path],[specify explicit path for libhiredis.]),
[specify explicit path for libhiredis.]),
[ ],[ withval="no" ]) [ ],[ withval="no" ])
found_libhiredis="no" found_libhiredis="no"
if test x_$withval = x_yes -o x_$withval != x_no; then if test x_$withval = x_yes -o x_$withval != x_no; then
@ -1364,7 +1386,7 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
fi fi
done done
if test x_$found_libhiredis != x_yes; then if test x_$found_libhiredis != x_yes; then
AC_ERROR([Could not find libhiredis, hiredis.h]) AC_MSG_ERROR([Could not find libhiredis, hiredis.h])
fi fi
AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT
@ -1372,11 +1394,42 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
]) ])
fi fi
# nghttp2
AC_ARG_WITH(libnghttp2, AS_HELP_STRING([--with-libnghttp2=path],[specify explicit path for libnghttp2.]),
[ ],[ withval="no" ])
found_libnghttp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
AC_MSG_CHECKING(for libnghttp2)
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/nghttp2/nghttp2.h"; then
found_libnghttp2="yes"
dnl assume /usr is in default path.
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
AC_MSG_RESULT(found in $dir)
AC_DEFINE([HAVE_NGHTTP2], [1], [Define this to use nghttp2 client.])
LIBS="$LIBS -lnghttp2"
break;
fi
done
if test x_$found_libnghttp2 != x_yes; then
AC_MSG_ERROR([Could not find libnghttp2, nghttp2.h])
fi
AC_CHECK_HEADERS([nghttp2/nghttp2.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([nghttp2_session_server_new], [], [], [AC_INCLUDES_DEFAULT
#include <nghttp2/nghttp2.h>
])
fi
# set static linking for uninstalled libraries if requested # set static linking for uninstalled libraries if requested
AC_SUBST(staticexe) AC_SUBST(staticexe)
staticexe="" staticexe=""
AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe], AC_ARG_ENABLE(static-exe, AS_HELP_STRING([--enable-static-exe],[ enable to compile executables statically against (event) uninstalled libs, for debug purposes ]),
[ enable to compile executables statically against (event) uninstalled libs, for debug purposes ]),
, ) , )
if test x_$enable_static_exe = x_yes; then if test x_$enable_static_exe = x_yes; then
staticexe="-static" staticexe="-static"
@ -1389,12 +1442,12 @@ if test x_$enable_static_exe = x_yes; then
LIBS="$LIBS -lgdi32" LIBS="$LIBS -lgdi32"
fi fi
LIBS="$LIBS -lz" LIBS="$LIBS -lz"
LIBS="$LIBS -l:libssp.a"
fi fi
fi fi
# set full static linking if requested # set full static linking if requested
AC_ARG_ENABLE(fully-static, AC_HELP_STRING([--enable-fully-static], AC_ARG_ENABLE(fully-static, AS_HELP_STRING([--enable-fully-static],[ enable to compile fully static ]),
[ enable to compile fully static ]),
, ) , )
if test x_$enable_fully_static = x_yes; then if test x_$enable_fully_static = x_yes; then
staticexe="-all-static" staticexe="-all-static"
@ -1406,12 +1459,12 @@ if test x_$enable_fully_static = x_yes; then
LIBS="$LIBS -lgdi32" LIBS="$LIBS -lgdi32"
fi fi
LIBS="$LIBS -lz" LIBS="$LIBS -lz"
LIBS="$LIBS -l:libssp.a"
fi fi
fi fi
# set lock checking if requested # set lock checking if requested
AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks], AC_ARG_ENABLE(lock_checks, AS_HELP_STRING([--enable-lock-checks],[ enable to check lock and unlock calls, for debug purposes ]),
[ enable to check lock and unlock calls, for debug purposes ]),
, ) , )
if test x_$enable_lock_checks = x_yes; then if test x_$enable_lock_checks = x_yes; then
AC_DEFINE(ENABLE_LOCK_CHECKS, 1, [Define if you want to use debug lock checking (slow).]) AC_DEFINE(ENABLE_LOCK_CHECKS, 1, [Define if you want to use debug lock checking (slow).])
@ -1528,7 +1581,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
AC_MSG_RESULT(no)) AC_MSG_RESULT(no))
AC_SEARCH_LIBS([setusercontext], [util]) AC_SEARCH_LIBS([setusercontext], [util])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4]) AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])]) AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])]) AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
@ -1653,7 +1706,7 @@ AC_SUBST(LIBOBJ_WITHOUT_CTIME)
AC_REPLACE_FUNCS(ctime_r) AC_REPLACE_FUNCS(ctime_r)
AC_REPLACE_FUNCS(strsep) AC_REPLACE_FUNCS(strsep)
AC_ARG_ENABLE(allsymbols, AC_HELP_STRING([--enable-allsymbols], [export all symbols from libunbound and link binaries to it, smaller install size but libunbound export table is polluted by internal symbols])) AC_ARG_ENABLE(allsymbols, AS_HELP_STRING([--enable-allsymbols],[export all symbols from libunbound and link binaries to it, smaller install size but libunbound export table is polluted by internal symbols]))
case "$enable_allsymbols" in case "$enable_allsymbols" in
yes) yes)
COMMON_OBJ_ALL_SYMBOLS="" COMMON_OBJ_ALL_SYMBOLS=""
@ -1696,7 +1749,7 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH, AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH,
["$hdr_dnstap_socket_path"], [default dnstap socket path]) ["$hdr_dnstap_socket_path"], [default dnstap socket path])
AC_SUBST(DNSTAP_SOCKET_PATH,["$hdr_dnstap_socket_path"]) AC_SUBST(DNSTAP_SOCKET_PATH,["$hdr_dnstap_socket_path"])
AC_SUBST(DNSTAP_SOCKET_TESTBIN,['unbound-dnstap-socket$(EXEEXT)'])
AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"]) AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"])
AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"]) AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"])
], ],
@ -1719,7 +1772,7 @@ dnsc_DNSCRYPT([
) )
# check for cachedb if requested # check for cachedb if requested
AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage])) AC_ARG_ENABLE(cachedb, AS_HELP_STRING([--enable-cachedb],[enable cachedb module that can use external cache storage]))
# turn on cachedb when hiredis support is enabled. # turn on cachedb when hiredis support is enabled.
if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
case "$enable_cachedb" in case "$enable_cachedb" in
@ -1732,7 +1785,7 @@ case "$enable_cachedb" in
esac esac
# check for ipsecmod if requested # check for ipsecmod if requested
AC_ARG_ENABLE(ipsecmod, AC_HELP_STRING([--enable-ipsecmod], [Enable ipsecmod module that facilitates opportunistic IPsec])) AC_ARG_ENABLE(ipsecmod, AS_HELP_STRING([--enable-ipsecmod],[Enable ipsecmod module that facilitates opportunistic IPsec]))
case "$enable_ipsecmod" in case "$enable_ipsecmod" in
yes) yes)
AC_DEFINE([USE_IPSECMOD], [1], [Define to 1 to use ipsecmod support.]) AC_DEFINE([USE_IPSECMOD], [1], [Define to 1 to use ipsecmod support.])
@ -1747,7 +1800,7 @@ case "$enable_ipsecmod" in
esac esac
# check for ipset if requested # check for ipset if requested
AC_ARG_ENABLE(ipset, AC_HELP_STRING([--enable-ipset], [enable ipset module])) AC_ARG_ENABLE(ipset, AS_HELP_STRING([--enable-ipset],[enable ipset module]))
case "$enable_ipset" in case "$enable_ipset" in
yes) yes)
AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support]) AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support])
@ -1759,8 +1812,7 @@ case "$enable_ipset" in
# BSD's pf # BSD's pf
AC_CHECK_HEADERS([net/pfvar.h], [], [ AC_CHECK_HEADERS([net/pfvar.h], [], [
# mnl # mnl
AC_ARG_WITH(libmnl, AC_HELP_STRING([--with-libmnl=path], AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
[specify explicit path for libmnl.]),
[ ],[ withval="yes" ]) [ ],[ withval="yes" ])
found_libmnl="no" found_libmnl="no"
AC_MSG_CHECKING(for libmnl) AC_MSG_CHECKING(for libmnl)
@ -1780,9 +1832,8 @@ case "$enable_ipset" in
break; break;
fi fi
done done
if test x_$found_libmnl != x_yes if test x_$found_libmnl != x_yes; then
then AC_MSG_ERROR([Could not find libmnl, libmnl.h])
AC_ERROR([Could not find libmnl, libmnl.h])
fi fi
], [ ], [
#include <netinet/in.h> #include <netinet/in.h>
@ -1793,7 +1844,7 @@ case "$enable_ipset" in
# nothing # nothing
;; ;;
esac esac
AC_ARG_ENABLE(explicit-port-randomisation, AC_HELP_STRING([--disable-explicit-port-randomisation], [disable explicit source port randomisation and rely on the kernel to provide random source ports])) AC_ARG_ENABLE(explicit-port-randomisation, AS_HELP_STRING([--disable-explicit-port-randomisation],[disable explicit source port randomisation and rely on the kernel to provide random source ports]))
case "$enable_explicit_port_randomisation" in case "$enable_explicit_port_randomisation" in
no) no)
AC_DEFINE([DISABLE_EXPLICIT_PORT_RANDOMISATION], [1], [Define this to enable kernel based UDP source port randomization.]) AC_DEFINE([DISABLE_EXPLICIT_PORT_RANDOMISATION], [1], [Define this to enable kernel based UDP source port randomization.])
@ -1841,8 +1892,7 @@ AC_SUBST(SOURCEFILE)
# see if we want to build the library or everything # see if we want to build the library or everything
ALLTARGET="alltargets" ALLTARGET="alltargets"
INSTALLTARGET="install-all" INSTALLTARGET="install-all"
AC_ARG_WITH(libunbound-only, AC_HELP_STRING([--with-libunbound-only], AC_ARG_WITH(libunbound-only, AS_HELP_STRING([--with-libunbound-only],[do not build daemon and tool programs]),
[do not build daemon and tool programs]),
[ [
if test "$withval" = "yes"; then if test "$withval" = "yes"; then
ALLTARGET="lib" ALLTARGET="lib"
@ -1851,10 +1901,10 @@ AC_ARG_WITH(libunbound-only, AC_HELP_STRING([--with-libunbound-only],
]) ])
if test $ALLTARGET = "alltargets"; then if test $ALLTARGET = "alltargets"; then
if test $USE_NSS = "yes"; then if test $USE_NSS = "yes"; then
AC_ERROR([--with-nss can only be used in combination with --with-libunbound-only.]) AC_MSG_ERROR([--with-nss can only be used in combination with --with-libunbound-only.])
fi fi
if test $USE_NETTLE = "yes"; then if test $USE_NETTLE = "yes"; then
AC_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.]) AC_MSG_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.])
fi fi
fi fi
@ -2115,6 +2165,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_PORT 53 #define UNBOUND_DNS_PORT 53
/** default port for DNS over TLS traffic. */ /** default port for DNS over TLS traffic. */
#define UNBOUND_DNS_OVER_TLS_PORT 853 #define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for unbound control traffic, registered port with IANA, /** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */ ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953 #define UNBOUND_CONTROL_PORT 8953
@ -2129,5 +2181,5 @@ AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
AC_SUBST(date, [`date +'%b %e, %Y'`]) AC_SUBST(date, [`date +'%b %e, %Y'`])
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service]) AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADERS([config.h])
AC_OUTPUT AC_OUTPUT

View file

@ -53,3 +53,5 @@ distribution but may be helpful.
lookups for downstream clients. lookups for downstream clients.
* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format, * drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
contributed by Andreas Schulze. contributed by Andreas Schulze.
* metrics.awk: awk script that can convert unbound-control stats to
Prometheus metrics format output.

View file

@ -1,10 +1,10 @@
Index: trunk/doc/unbound.conf.5.in diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
=================================================================== index f426ac5f..147fbfa9 100644
--- trunk/doc/unbound.conf.5.in (revision 4357) --- a/doc/unbound.conf.5.in
+++ trunk/doc/unbound.conf.5.in (working copy) +++ b/doc/unbound.conf.5.in
@@ -701,6 +701,13 @@ @@ -872,6 +872,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing. this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is off. This option only has effect when qname-minimisation is enabled. Default is no.
.TP .TP
+.B aaaa\-filter: \fI<yes or no> +.B aaaa\-filter: \fI<yes or no>
+Activate behavior similar to BIND's AAAA-filter. +Activate behavior similar to BIND's AAAA-filter.
@ -13,17 +13,18 @@ Index: trunk/doc/unbound.conf.5.in
+This also causes an additional A query to be sent for each AAAA query. +This also causes an additional A query to be sent for each AAAA query.
+This breaks DNSSEC! +This breaks DNSSEC!
+.TP +.TP
.B private\-address: \fI<IP address or subnet> .B aggressive\-nsec: \fI<yes or no>
Give IPv4 of IPv6 addresses or classless subnets. These are addresses Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
on your private network, and are not allowed to be returned for and other denials, using information from previous NXDOMAINs answers.
Index: trunk/iterator/iter_scrub.c diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
=================================================================== index aae934dd..55c55de0 100644
--- trunk/iterator/iter_scrub.c (revision 4357) --- a/iterator/iter_scrub.c
+++ trunk/iterator/iter_scrub.c (working copy) +++ b/iterator/iter_scrub.c
@@ -617,6 +617,32 @@ @@ -667,6 +667,32 @@ static int sanitize_nsec_is_overreach(struct rrset_parse* rrset,
return 0;
} }
/** +/**
+ * ASN: Lookup A records from rrset cache. + * ASN: Lookup A records from rrset cache.
+ * @param qinfo: the question originally asked. + * @param qinfo: the question originally asked.
+ * @param env: module environment with config and cache. + * @param env: module environment with config and cache.
@ -49,11 +50,10 @@ Index: trunk/iterator/iter_scrub.c
+ return 0; + return 0;
+} +}
+ +
+/** /**
* Given a response event, remove suspect RRsets from the response. * Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects * "Suspect" rrsets are potentially poison. Note that this routine expects
* the response to be in a "normalized" state -- that is, all "irrelevant" @@ -686,6 +712,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
@@ -635,6 +661,7 @@
struct query_info* qinfo, uint8_t* zonename, struct module_env* env, struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie) struct iter_env* ie)
{ {
@ -61,7 +61,7 @@ Index: trunk/iterator/iter_scrub.c
int del_addi = 0; /* if additional-holding rrsets are deleted, we int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */ do not trust the normalized additional-A-AAAA any more */
struct rrset_parse* rrset, *prev; struct rrset_parse* rrset, *prev;
@@ -670,6 +697,13 @@ @@ -721,6 +748,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = rrset->rrset_all_next; rrset = rrset->rrset_all_next;
} }
@ -75,11 +75,10 @@ Index: trunk/iterator/iter_scrub.c
/* At this point, we brutally remove ALL rrsets that aren't /* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that, * children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY * as far as we know, the server that we contacted is ONLY
@@ -680,6 +714,24 @@ @@ -732,6 +766,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
prev = NULL;
rrset = msg->rrset_first; rrset = msg->rrset_first;
while(rrset) { while(rrset) {
+
+ /* ASN: For AAAA records only... */ + /* ASN: For AAAA records only... */
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) { + if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
+ /* ASN: If this is not a AAAA query, then remove AAAA + /* ASN: If this is not a AAAA query, then remove AAAA
@ -97,14 +96,15 @@ Index: trunk/iterator/iter_scrub.c
+ LDNS_RR_TYPE_AAAA, qinfo->qclass); + LDNS_RR_TYPE_AAAA, qinfo->qclass);
+ } + }
+ /* ASN: End of added code */ + /* ASN: End of added code */
+
/* remove private addresses */ /* remove private addresses */
if( (rrset->type == LDNS_RR_TYPE_A || if( (rrset->type == LDNS_RR_TYPE_A ||
Index: trunk/iterator/iter_utils.c rrset->type == LDNS_RR_TYPE_AAAA)) {
=================================================================== diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
--- trunk/iterator/iter_utils.c (revision 4357) index 7bc67da6..e10f547a 100644
+++ trunk/iterator/iter_utils.c (working copy) --- a/iterator/iter_utils.c
@@ -175,6 +175,7 @@ +++ b/iterator/iter_utils.c
@@ -175,6 +175,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
} }
iter_env->supports_ipv6 = cfg->do_ip6; iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4; iter_env->supports_ipv4 = cfg->do_ip4;
@ -112,11 +112,11 @@ Index: trunk/iterator/iter_utils.c
return 1; return 1;
} }
Index: trunk/iterator/iterator.c diff --git a/iterator/iterator.c b/iterator/iterator.c
=================================================================== index 23b07ea9..ca29b48c 100644
--- trunk/iterator/iterator.c (revision 4357) --- a/iterator/iterator.c
+++ trunk/iterator/iterator.c (working copy) +++ b/iterator/iterator.c
@@ -1847,6 +1847,53 @@ @@ -2127,6 +2127,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
return 0; return 0;
} }
@ -147,9 +147,9 @@ Index: trunk/iterator/iterator.c
+ +
+ /* re-throw same query, but with a different type */ + /* re-throw same query, but with a different type */
+ if(!generate_sub_request(iq->qchase.qname, + if(!generate_sub_request(iq->qchase.qname,
+ iq->qchase.qname_len, LDNS_RR_TYPE_A, + iq->qchase.qname_len, LDNS_RR_TYPE_A,
+ iq->qchase.qclass, qstate, id, iq, + iq->qchase.qclass, qstate, id, iq,
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { + INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed " + log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
+ "preloading of A record for", + "preloading of A record for",
+ iq->qchase.qname, LDNS_RR_TYPE_A, + iq->qchase.qname, LDNS_RR_TYPE_A,
@ -170,7 +170,7 @@ Index: trunk/iterator/iterator.c
/** /**
* This is the request event state where the request will be sent to one of * This is the request event state where the request will be sent to one of
@@ -1894,6 +1941,13 @@ @@ -2186,6 +2233,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
} }
@ -184,7 +184,7 @@ Index: trunk/iterator/iterator.c
/* Make sure we have a delegation point, otherwise priming failed /* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */ * or another failure occurred */
if(!iq->dp) { if(!iq->dp) {
@@ -3095,6 +3149,61 @@ @@ -3574,6 +3628,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
return 0; return 0;
} }
@ -246,7 +246,7 @@ Index: trunk/iterator/iterator.c
/* /*
* Return priming query results to interested super querystates. * Return priming query results to interested super querystates.
* *
@@ -3114,6 +3223,9 @@ @@ -3593,6 +3702,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*) else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
super->minfo[id])->state == DSNS_FIND_STATE) super->minfo[id])->state == DSNS_FIND_STATE)
processDSNSResponse(qstate, id, super); processDSNSResponse(qstate, id, super);
@ -256,7 +256,7 @@ Index: trunk/iterator/iterator.c
else if(qstate->return_rcode != LDNS_RCODE_NOERROR) else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
error_supers(qstate, id, super); error_supers(qstate, id, super);
else if(qstate->is_priming) else if(qstate->is_priming)
@@ -3151,6 +3263,9 @@ @@ -3630,6 +3742,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
case INIT_REQUEST_3_STATE: case INIT_REQUEST_3_STATE:
cont = processInitRequest3(qstate, iq, id); cont = processInitRequest3(qstate, iq, id);
break; break;
@ -266,7 +266,7 @@ Index: trunk/iterator/iterator.c
case QUERYTARGETS_STATE: case QUERYTARGETS_STATE:
cont = processQueryTargets(qstate, iq, ie, id); cont = processQueryTargets(qstate, iq, ie, id);
break; break;
@@ -3460,6 +3575,8 @@ @@ -3961,6 +4076,8 @@ iter_state_to_string(enum iter_state state)
return "INIT REQUEST STATE (stage 2)"; return "INIT REQUEST STATE (stage 2)";
case INIT_REQUEST_3_STATE: case INIT_REQUEST_3_STATE:
return "INIT REQUEST STATE (stage 3)"; return "INIT REQUEST STATE (stage 3)";
@ -275,7 +275,7 @@ Index: trunk/iterator/iterator.c
case QUERYTARGETS_STATE : case QUERYTARGETS_STATE :
return "QUERY TARGETS STATE"; return "QUERY TARGETS STATE";
case PRIME_RESP_STATE : case PRIME_RESP_STATE :
@@ -3484,6 +3601,7 @@ @@ -3985,6 +4102,7 @@ iter_state_is_responsestate(enum iter_state s)
case INIT_REQUEST_STATE : case INIT_REQUEST_STATE :
case INIT_REQUEST_2_STATE : case INIT_REQUEST_2_STATE :
case INIT_REQUEST_3_STATE : case INIT_REQUEST_3_STATE :
@ -283,11 +283,11 @@ Index: trunk/iterator/iterator.c
case QUERYTARGETS_STATE : case QUERYTARGETS_STATE :
case COLLECT_CLASS_STATE : case COLLECT_CLASS_STATE :
return 0; return 0;
Index: trunk/iterator/iterator.h diff --git a/iterator/iterator.h b/iterator/iterator.h
=================================================================== index 342ac207..731948d1 100644
--- trunk/iterator/iterator.h (revision 4357) --- a/iterator/iterator.h
+++ trunk/iterator/iterator.h (working copy) +++ b/iterator/iterator.h
@@ -130,6 +130,9 @@ @@ -135,6 +135,9 @@ struct iter_env {
*/ */
int* target_fetch_policy; int* target_fetch_policy;
@ -297,10 +297,11 @@ Index: trunk/iterator/iterator.h
/** lock on ratelimit counter */ /** lock on ratelimit counter */
lock_basic_type queries_ratelimit_lock; lock_basic_type queries_ratelimit_lock;
/** number of queries that have been ratelimited */ /** number of queries that have been ratelimited */
@@ -182,6 +185,14 @@ @@ -186,6 +189,14 @@ enum iter_state {
*/
INIT_REQUEST_3_STATE, INIT_REQUEST_3_STATE,
/** + /**
+ * This state is responsible for intercepting AAAA queries, + * This state is responsible for intercepting AAAA queries,
+ * and launch a A subquery on the same target, to populate the + * and launch a A subquery on the same target, to populate the
+ * cache with A records, so the AAAA filter scrubbing logic can + * cache with A records, so the AAAA filter scrubbing logic can
@ -308,29 +309,28 @@ Index: trunk/iterator/iterator.h
+ */ + */
+ ASN_FETCH_A_FOR_AAAA_STATE, + ASN_FETCH_A_FOR_AAAA_STATE,
+ +
+ /** /**
* Each time a delegation point changes for a given query or a * Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited. * query times out and/or wakes up, this state is (re)visited.
* This state is responsible for iterating through a list of @@ -375,6 +386,13 @@ struct iter_qstate {
@@ -364,6 +375,13 @@
* be used when creating the state. A higher one will be attempted.
*/ */
int refetch_glue; int refetch_glue;
+
+ /** + /**
+ * ASN: This is a flag that, if true, means that this query is + * ASN: This is a flag that, if true, means that this query is
+ * for fetching A records to populate cache and determine if we must + * for fetching A records to populate cache and determine if we must
+ * return AAAA records or not. + * return AAAA records or not.
+ */ + */
+ int fetch_a_for_aaaa; + int fetch_a_for_aaaa;
+
/** list of pending queries to authoritative servers. */ /** list of pending queries to authoritative servers. */
struct outbound_list outlist; struct outbound_list outlist;
Index: trunk/pythonmod/interface.i
=================================================================== diff --git a/pythonmod/interface.i b/pythonmod/interface.i
--- trunk/pythonmod/interface.i (revision 4357) index f08b575d..47f1bb2e 100644
+++ trunk/pythonmod/interface.i (working copy) --- a/pythonmod/interface.i
@@ -851,6 +851,7 @@ +++ b/pythonmod/interface.i
@@ -975,6 +975,7 @@ struct config_file {
int harden_dnssec_stripped; int harden_dnssec_stripped;
int harden_referral_path; int harden_referral_path;
int use_caps_bits_for_id; int use_caps_bits_for_id;
@ -338,11 +338,11 @@ Index: trunk/pythonmod/interface.i
struct config_strlist* private_address; struct config_strlist* private_address;
struct config_strlist* private_domain; struct config_strlist* private_domain;
size_t unwanted_threshold; size_t unwanted_threshold;
Index: trunk/util/config_file.c diff --git a/util/config_file.c b/util/config_file.c
=================================================================== index 0ab8614a..729fb147 100644
--- trunk/util/config_file.c (revision 4357) --- a/util/config_file.c
+++ trunk/util/config_file.c (working copy) +++ b/util/config_file.c
@@ -195,6 +195,7 @@ @@ -218,6 +218,7 @@ config_create(void)
cfg->harden_referral_path = 0; cfg->harden_referral_path = 0;
cfg->harden_algo_downgrade = 0; cfg->harden_algo_downgrade = 0;
cfg->use_caps_bits_for_id = 0; cfg->use_caps_bits_for_id = 0;
@ -350,11 +350,11 @@ Index: trunk/util/config_file.c
cfg->caps_whitelist = NULL; cfg->caps_whitelist = NULL;
cfg->private_address = NULL; cfg->private_address = NULL;
cfg->private_domain = NULL; cfg->private_domain = NULL;
Index: trunk/util/config_file.h diff --git a/util/config_file.h b/util/config_file.h
=================================================================== index e61257a3..dabaa7bb 100644
--- trunk/util/config_file.h (revision 4357) --- a/util/config_file.h
+++ trunk/util/config_file.h (working copy) +++ b/util/config_file.h
@@ -209,6 +209,8 @@ @@ -260,6 +260,8 @@ struct config_file {
int harden_algo_downgrade; int harden_algo_downgrade;
/** use 0x20 bits in query as random ID bits */ /** use 0x20 bits in query as random ID bits */
int use_caps_bits_for_id; int use_caps_bits_for_id;
@ -363,11 +363,11 @@ Index: trunk/util/config_file.h
/** 0x20 whitelist, domains that do not use capsforid */ /** 0x20 whitelist, domains that do not use capsforid */
struct config_strlist* caps_whitelist; struct config_strlist* caps_whitelist;
/** strip away these private addrs from answers, no DNS Rebinding */ /** strip away these private addrs from answers, no DNS Rebinding */
Index: trunk/util/configlexer.lex diff --git a/util/configlexer.lex b/util/configlexer.lex
=================================================================== index 79a0edca..4eaec678 100644
--- trunk/util/configlexer.lex (revision 4357) --- a/util/configlexer.lex
+++ trunk/util/configlexer.lex (working copy) +++ b/util/configlexer.lex
@@ -279,6 +279,7 @@ @@ -304,6 +304,7 @@ harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) } use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) } caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
@ -375,11 +375,11 @@ Index: trunk/util/configlexer.lex
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
Index: trunk/util/configparser.y diff --git a/util/configparser.y b/util/configparser.y
=================================================================== index 1d0e8658..f284dd43 100644
--- trunk/util/configparser.y (revision 4357) --- a/util/configparser.y
+++ trunk/util/configparser.y (working copy) +++ b/util/configparser.y
@@ -95,6 +95,7 @@ @@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR %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_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
@ -387,7 +387,7 @@ Index: trunk/util/configparser.y
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE %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_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
@@ -203,6 +204,7 @@ @@ -233,6 +234,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size | server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
server_harden_referral_path | server_private_address | server_harden_referral_path | server_private_address |
server_private_domain | server_extended_statistics | server_private_domain | server_extended_statistics |
@ -395,12 +395,10 @@ Index: trunk/util/configparser.y
server_local_data_ptr | server_jostle_timeout | server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii | server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min | server_domain_insecure | server_val_sig_skew_min |
@@ -1183,6 +1185,15 @@ @@ -1563,6 +1565,15 @@ 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"); yyerror("out of memory");
+ } }
+ ; ;
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG +server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
+ { + {
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2)); + OUTYY(("P(server_aaaa_filter:%s)\n", $2));
@ -408,6 +406,8 @@ Index: trunk/util/configparser.y
+ yyerror("expected yes or no."); + yyerror("expected yes or no.");
+ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0); + else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
+ free($2); + free($2);
} + }
; + ;
server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
{
OUTYY(("P(server_private_address:%s)\n", $2));

View file

@ -2,7 +2,7 @@ Description: based on the included patch contrib/fastrpz.patch
Author: fastrpz@farsightsecurity.com Author: fastrpz@farsightsecurity.com
--- ---
diff --git a/Makefile.in b/Makefile.in diff --git a/Makefile.in b/Makefile.in
index a20058cc..495779cc 100644 index bac212df..4824927f 100644
--- a/Makefile.in --- a/Makefile.in
+++ b/Makefile.in +++ b/Makefile.in
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c @@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
@ -13,8 +13,8 @@ index a20058cc..495779cc 100644
+FASTRPZ_OBJ=@FASTRPZ_OBJ@ +FASTRPZ_OBJ=@FASTRPZ_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@ DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@ DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@ WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \ @@ -134,7 +136,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \ edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \ edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \ cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
@ -23,16 +23,16 @@ index a20058cc..495779cc 100644
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \ COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \ 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_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \ @@ -147,7 +149,7 @@ autotrust.lo val_anchor.lo rpz.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \ val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \ $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo -$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo +$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \ COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \ @@ -428,6 +430,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \ $(srcdir)/util/config_file.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/netevent.h
@ -45,10 +45,10 @@ index a20058cc..495779cc 100644
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \ pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
pythonmod/interface.h \ pythonmod/interface.h \
diff --git a/config.h.in b/config.h.in diff --git a/config.h.in b/config.h.in
index 78d47fed..e33073e4 100644 index f7a4095e..d5a4fa01 100644
--- a/config.h.in --- a/config.h.in
+++ b/config.h.in +++ b/config.h.in
@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, @@ -1364,4 +1364,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
/** the version of unbound-control that this software implements */ /** the version of unbound-control that this software implements */
#define UNBOUND_CONTROL_VERSION 1 #define UNBOUND_CONTROL_VERSION 1
@ -62,7 +62,7 @@ index 78d47fed..e33073e4 100644
+/** turn on fastrpz response policy zones */ +/** turn on fastrpz response policy zones */
+#undef ENABLE_FASTRPZ +#undef ENABLE_FASTRPZ
diff --git a/configure.ac b/configure.ac diff --git a/configure.ac b/configure.ac
index 2b91dd3c..e6063d17 100644 index 5c373d9d..e45abd89 100644
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4) @@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
@ -73,10 +73,10 @@ index 2b91dd3c..e6063d17 100644
sinclude(dnscrypt/dnscrypt.m4) sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing # must be numbers. ac_defun because of later processing
@@ -1778,6 +1779,9 @@ case "$enable_ipset" in @@ -1819,6 +1820,9 @@ case "$enable_explicit_port_randomisation" in
;;
esac esac
+# check for Fastrpz with fastrpz/rpz.m4 +# check for Fastrpz with fastrpz/rpz.m4
+ck_FASTRPZ +ck_FASTRPZ
+ +
@ -84,7 +84,7 @@ index 2b91dd3c..e6063d17 100644
# on openBSD, the implicit rule make $< work. # on openBSD, the implicit rule make $< work.
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies). # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
diff --git a/daemon/daemon.c b/daemon/daemon.c diff --git a/daemon/daemon.c b/daemon/daemon.c
index 8b0fc348..7ffb9221 100644 index 5d427925..f89f1437 100644
--- a/daemon/daemon.c --- a/daemon/daemon.c
+++ b/daemon/daemon.c +++ b/daemon/daemon.c
@@ -91,6 +91,9 @@ @@ -91,6 +91,9 @@
@ -97,8 +97,8 @@ index 8b0fc348..7ffb9221 100644
#ifdef HAVE_SYSTEMD #ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h> #include <systemd/sd-daemon.h>
@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon) @@ -456,6 +459,14 @@ daemon_create_workers(struct daemon* daemon)
dt_apply_cfg(daemon->dtenv, daemon->cfg); fatal_exit("dt_create failed");
#else #else
fatal_exit("dnstap enabled in config but not built with dnstap support"); fatal_exit("dnstap enabled in config but not built with dnstap support");
+#endif +#endif
@ -112,7 +112,7 @@ index 8b0fc348..7ffb9221 100644
#endif #endif
} }
for(i=0; i<daemon->num; i++) { for(i=0; i<daemon->num; i++) {
@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon) @@ -729,6 +740,9 @@ daemon_cleanup(struct daemon* daemon)
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT
dnsc_delete(daemon->dnscenv); dnsc_delete(daemon->dnscenv);
daemon->dnscenv = NULL; daemon->dnscenv = NULL;
@ -139,7 +139,7 @@ index 3effbafb..4d4c34da 100644
/** /**
diff --git a/daemon/worker.c b/daemon/worker.c diff --git a/daemon/worker.c b/daemon/worker.c
index eb7fdf2f..1982228d 100644 index 23e3244c..b63d49b7 100644
--- a/daemon/worker.c --- a/daemon/worker.c
+++ b/daemon/worker.c +++ b/daemon/worker.c
@@ -76,6 +76,9 @@ @@ -76,6 +76,9 @@
@ -152,7 +152,7 @@ index eb7fdf2f..1982228d 100644
#include "sldns/wire2str.h" #include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h" #include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h" #include "dnscrypt/dnscrypt.h"
@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo, @@ -535,8 +538,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
/* not secure */ /* not secure */
secure = 0; secure = 0;
break; break;
@ -180,7 +180,7 @@ index eb7fdf2f..1982228d 100644
/* return this delegation from the cache */ /* return this delegation from the cache */
edns_bak = *edns; edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION; edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, @@ -711,6 +733,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
*is_secure_answer = 0; *is_secure_answer = 0;
} }
} else *is_secure_answer = 0; } else *is_secure_answer = 0;
@ -204,7 +204,7 @@ index eb7fdf2f..1982228d 100644
edns_bak = *edns; edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION; edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error, @@ -1436,6 +1475,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from", log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen); &repinfo->addr, repinfo->addrlen);
goto send_reply; goto send_reply;
@ -220,7 +220,7 @@ index eb7fdf2f..1982228d 100644
} }
/* If we've found a local alias, replace the qname with the alias /* If we've found a local alias, replace the qname with the alias
@@ -1485,12 +1533,21 @@ lookup_cache: @@ -1486,12 +1534,21 @@ lookup_cache:
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) { if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */ /* answer from cache - we have acquired a readlock on it */
@ -244,7 +244,7 @@ index eb7fdf2f..1982228d 100644
/* prefetch it if the prefetch TTL expired. /* prefetch it if the prefetch TTL expired.
* Note that if there is more than one pass * Note that if there is more than one pass
* its qname must be that used for cache * its qname must be that used for cache
@@ -1547,11 +1604,19 @@ lookup_cache: @@ -1548,11 +1605,19 @@ lookup_cache:
lock_rw_unlock(&e->lock); lock_rw_unlock(&e->lock);
} }
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) { if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
@ -267,10 +267,10 @@ index eb7fdf2f..1982228d 100644
} }
verbose(VERB_ALGO, "answer norec from cache -- " verbose(VERB_ALGO, "answer norec from cache -- "
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index 38c2d298..3b07f392 100644 index cd43f04e..b92a1af8 100644
--- a/doc/unbound.conf.5.in --- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in
@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is @@ -1878,6 +1878,81 @@ List domain for which the AAAA records are ignored and the A record is
used by dns64 processing instead. Can be entered multiple times, list a used by dns64 processing instead. Can be entered multiple times, list a
new domain for which it applies, one per line. Applies also to names new domain for which it applies, one per line. Applies also to names
underneath the name given. underneath the name given.
@ -2888,7 +2888,7 @@ index 00000000..21235355
+ fi + fi
+]) +])
diff --git a/iterator/iterator.c b/iterator/iterator.c diff --git a/iterator/iterator.c b/iterator/iterator.c
index 1e0113a8..2fcbf547 100644 index 23b07ea9..c3d31a33 100644
--- a/iterator/iterator.c --- a/iterator/iterator.c
+++ b/iterator/iterator.c +++ b/iterator/iterator.c
@@ -68,6 +68,9 @@ @@ -68,6 +68,9 @@
@ -2901,7 +2901,7 @@ index 1e0113a8..2fcbf547 100644
/* in msec */ /* in msec */
int UNKNOWN_SERVER_NICENESS = 376; int UNKNOWN_SERVER_NICENESS = 376;
@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, @@ -563,6 +566,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME && if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(*mname, r->rk.dname) == 0 && query_dname_compare(*mname, r->rk.dname) == 0 &&
!iter_find_rrset_in_prepend_answer(iq, r)) { !iter_find_rrset_in_prepend_answer(iq, r)) {
@ -2925,7 +2925,7 @@ index 1e0113a8..2fcbf547 100644
/* Add this relevant CNAME rrset to the prepend list.*/ /* Add this relevant CNAME rrset to the prepend list.*/
if(!iter_add_prepend_answer(qstate, iq, r)) if(!iter_add_prepend_answer(qstate, iq, r))
return 0; return 0;
@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, @@ -571,6 +591,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
/* Other rrsets in the section are ignored. */ /* Other rrsets in the section are ignored. */
} }
@ -2935,7 +2935,7 @@ index 1e0113a8..2fcbf547 100644
/* add authority rrsets to authority prepend, for wildcarded CNAMEs */ /* add authority rrsets to authority prepend, for wildcarded CNAMEs */
for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets + for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
msg->rep->ns_numrrsets; i++) { msg->rep->ns_numrrsets; i++) {
@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, @@ -1231,6 +1254,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
uint8_t* delname; uint8_t* delname;
size_t delnamelen; size_t delnamelen;
struct dns_msg* msg = NULL; struct dns_msg* msg = NULL;
@ -2943,7 +2943,7 @@ index 1e0113a8..2fcbf547 100644
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo); log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
/* check effort */ /* check effort */
@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, @@ -1317,8 +1341,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
} }
if(msg) { if(msg) {
/* handle positive cache response */ /* handle positive cache response */
@ -2953,7 +2953,7 @@ index 1e0113a8..2fcbf547 100644
if(verbosity >= VERB_ALGO) { if(verbosity >= VERB_ALGO) {
log_dns_msg("msg from cache lookup", &msg->qinfo, log_dns_msg("msg from cache lookup", &msg->qinfo,
msg->rep); msg->rep);
@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, @@ -1326,7 +1349,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
(int)msg->rep->ttl, (int)msg->rep->ttl,
(int)msg->rep->prefetch_ttl); (int)msg->rep->prefetch_ttl);
} }
@ -2976,7 +2976,7 @@ index 1e0113a8..2fcbf547 100644
if(type == RESPONSE_TYPE_CNAME) { if(type == RESPONSE_TYPE_CNAME) {
uint8_t* sname = 0; uint8_t* sname = 0;
size_t slen = 0; size_t slen = 0;
@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, @@ -2801,6 +2839,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
sock_list_insert(&qstate->reply_origin, sock_list_insert(&qstate->reply_origin,
&qstate->reply->addr, qstate->reply->addrlen, &qstate->reply->addr, qstate->reply->addrlen,
qstate->region); qstate->region);
@ -3039,7 +3039,7 @@ index 1e0113a8..2fcbf547 100644
if(iq->minimisation_state != DONOT_MINIMISE_STATE if(iq->minimisation_state != DONOT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) { && !(iq->chase_flags & BIT_RD)) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) != if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, @@ -3563,12 +3657,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
* but only if we did recursion. The nonrecursion referral * but only if we did recursion. The nonrecursion referral
* from cache does not need to be stored in the msg cache. */ * from cache does not need to be stored in the msg cache. */
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) { if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
@ -3085,10 +3085,10 @@ index 1e0113a8..2fcbf547 100644
qstate->return_msg = iq->response; qstate->return_msg = iq->response;
return 0; return 0;
diff --git a/iterator/iterator.h b/iterator/iterator.h diff --git a/iterator/iterator.h b/iterator/iterator.h
index a2f1b570..e1e4a738 100644 index 342ac207..49b0ecdd 100644
--- a/iterator/iterator.h --- a/iterator/iterator.h
+++ b/iterator/iterator.h +++ b/iterator/iterator.h
@@ -386,6 +386,16 @@ struct iter_qstate { @@ -396,6 +396,16 @@ struct iter_qstate {
*/ */
int minimise_count; int minimise_count;
@ -3104,12 +3104,12 @@ index a2f1b570..e1e4a738 100644
+ +
/** /**
* Count number of time-outs. Used to prevent resolving failures when * Count number of time-outs. Used to prevent resolving failures when
* the QNAME minimisation QTYPE is blocked. */ * the QNAME minimisation QTYPE is blocked. Used to determine if
diff --git a/services/cache/dns.c b/services/cache/dns.c diff --git a/services/cache/dns.c b/services/cache/dns.c
index 2a5bca4a..6de8863a 100644 index 7b6e142c..6d7449f5 100644
--- a/services/cache/dns.c --- a/services/cache/dns.c
+++ b/services/cache/dns.c +++ b/services/cache/dns.c
@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, @@ -969,6 +969,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct regional* region, uint32_t flags) struct regional* region, uint32_t flags)
{ {
struct reply_info* rep = NULL; struct reply_info* rep = NULL;
@ -3125,7 +3125,7 @@ index 2a5bca4a..6de8863a 100644
rep = reply_info_copy(msgrep, env->alloc, NULL); rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep) if(!rep)
diff --git a/services/mesh.c b/services/mesh.c diff --git a/services/mesh.c b/services/mesh.c
index 9114ef4c..3dc518e5 100644 index 4b0c5db4..eb9cfa5b 100644
--- a/services/mesh.c --- a/services/mesh.c
+++ b/services/mesh.c +++ b/services/mesh.c
@@ -61,6 +61,9 @@ @@ -61,6 +61,9 @@
@ -3138,7 +3138,7 @@ index 9114ef4c..3dc518e5 100644
#include "respip/respip.h" #include "respip/respip.h"
#include "services/listen_dnsport.h" #include "services/listen_dnsport.h"
@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep, @@ -1207,6 +1210,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
else secure = 0; else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR) if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL; rcode = LDNS_RCODE_SERVFAIL;
@ -3152,7 +3152,7 @@ index 9114ef4c..3dc518e5 100644
/* send the reply */ /* send the reply */
/* We don't reuse the encoded answer if either the previous or current /* We don't reuse the encoded answer if either the previous or current
* response has a local alias. We could compare the alias records * response has a local alias. We could compare the alias records
@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh, @@ -1434,6 +1444,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
key.s.is_valrec = valrec; key.s.is_valrec = valrec;
key.s.qinfo = *qinfo; key.s.qinfo = *qinfo;
key.s.query_flags = qflags; key.s.query_flags = qflags;
@ -3160,7 +3160,7 @@ index 9114ef4c..3dc518e5 100644
/* We are searching for a similar mesh state when we DO want to /* We are searching for a similar mesh state when we DO want to
* aggregate the state. Thus unique is set to NULL. (default when we * aggregate the state. Thus unique is set to NULL. (default when we
* desire aggregation).*/ * desire aggregation).*/
@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns, @@ -1480,6 +1491,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
if(!r) if(!r)
return 0; return 0;
r->query_reply = *rep; r->query_reply = *rep;
@ -3172,11 +3172,11 @@ index 9114ef4c..3dc518e5 100644
if(edns->opt_list) { if(edns->opt_list) {
r->edns.opt_list = edns_opt_copy_region(edns->opt_list, r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
diff --git a/util/config_file.c b/util/config_file.c diff --git a/util/config_file.c b/util/config_file.c
index 52ca5a18..0660248f 100644 index 0e9ee471..a5fd72e0 100644
--- a/util/config_file.c --- a/util/config_file.c
+++ b/util/config_file.c +++ b/util/config_file.c
@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg) @@ -1495,6 +1495,8 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_socket_path); free(cfg->dnstap_tls_client_cert_file);
free(cfg->dnstap_identity); free(cfg->dnstap_identity);
free(cfg->dnstap_version); free(cfg->dnstap_version);
+ if (cfg->rpz_cstr) + if (cfg->rpz_cstr)
@ -3185,10 +3185,10 @@ index 52ca5a18..0660248f 100644
config_deldblstrlist(cfg->ratelimit_below_domain); config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script); config_delstrlist(cfg->python_script);
diff --git a/util/config_file.h b/util/config_file.h diff --git a/util/config_file.h b/util/config_file.h
index 8739ca2a..a2dcf215 100644 index 66e5025d..504f4f92 100644
--- a/util/config_file.h --- a/util/config_file.h
+++ b/util/config_file.h +++ b/util/config_file.h
@@ -499,6 +499,11 @@ struct config_file { @@ -522,6 +522,11 @@ struct config_file {
/** true to disable DNSSEC lameness check in iterator */ /** true to disable DNSSEC lameness check in iterator */
int disable_dnssec_lame_check; int disable_dnssec_lame_check;
@ -3201,10 +3201,10 @@ index 8739ca2a..a2dcf215 100644
int ip_ratelimit; int ip_ratelimit;
/** number of slabs for ip_ratelimit cache */ /** number of slabs for ip_ratelimit cache */
diff --git a/util/configlexer.lex b/util/configlexer.lex diff --git a/util/configlexer.lex b/util/configlexer.lex
index deedffa5..301458a3 100644 index 83cea4b9..9a7feea4 100644
--- a/util/configlexer.lex --- a/util/configlexer.lex
+++ b/util/configlexer.lex +++ b/util/configlexer.lex
@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} { @@ -467,6 +467,10 @@ dnstap-log-forwarder-query-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
dnstap-log-forwarder-response-messages{COLON} { dnstap-log-forwarder-response-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
@ -3216,18 +3216,18 @@ index deedffa5..301458a3 100644
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) } ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) } ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
diff --git a/util/configparser.y b/util/configparser.y diff --git a/util/configparser.y b/util/configparser.y
index d471babe..cb6b1d63 100644 index fe600a99..ce43390f 100644
--- a/util/configparser.y --- a/util/configparser.y
+++ b/util/configparser.y +++ b/util/configparser.y
@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser; @@ -128,6 +128,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
+%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION +%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
%token VAR_DISABLE_DNSSEC_LAME_CHECK %token VAR_IP_DSCP
@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser; @@ -179,7 +180,7 @@ extern struct config_parser_state* cfg_parser;
%% %%
toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -3236,7 +3236,7 @@ index d471babe..cb6b1d63 100644
forwardstart contents_forward | pythonstart contents_py | forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view | rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb | dnscstart contents_dnsc | cachedbstart contents_cachedb |
@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES @@ -2939,6 +2940,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
free($2); free($2);
} }
; ;
@ -3384,7 +3384,7 @@ index 729877ba..ccd1a0c2 100644
/** /**
diff --git a/util/netevent.c b/util/netevent.c diff --git a/util/netevent.c b/util/netevent.c
index 9fe5da2d..037e70d1 100644 index 3e7a433e..f20d806f 100644
--- a/util/netevent.c --- a/util/netevent.c
+++ b/util/netevent.c +++ b/util/netevent.c
@@ -57,6 +57,9 @@ @@ -57,6 +57,9 @@
@ -3397,7 +3397,7 @@ index 9fe5da2d..037e70d1 100644
/* -------- Start of local definitions -------- */ /* -------- Start of local definitions -------- */
/** if CMSG_ALIGN is not defined on this platform, a workaround */ /** if CMSG_ALIGN is not defined on this platform, a workaround */
@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) @@ -596,6 +599,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
struct cmsghdr* cmsg; struct cmsghdr* cmsg;
#endif /* S_SPLINT_S */ #endif /* S_SPLINT_S */
@ -3407,7 +3407,7 @@ index 9fe5da2d..037e70d1 100644
rep.c = (struct comm_point*)arg; rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp); log_assert(rep.c->type == comm_udp);
@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg) @@ -685,6 +691,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
int i; int i;
struct sldns_buffer *buffer; struct sldns_buffer *buffer;
@ -3417,7 +3417,7 @@ index 9fe5da2d..037e70d1 100644
rep.c = (struct comm_point*)arg; rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp); log_assert(rep.c->type == comm_udp);
@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg) @@ -728,6 +737,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
(void)comm_point_send_udp_msg(rep.c, buffer, (void)comm_point_send_udp_msg(rep.c, buffer,
(struct sockaddr*)&rep.addr, rep.addrlen); (struct sockaddr*)&rep.addr, rep.addrlen);
} }
@ -3427,7 +3427,7 @@ index 9fe5da2d..037e70d1 100644
if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
another UDP port. Note rep.c cannot be reused with TCP fd. */ another UDP port. Note rep.c cannot be reused with TCP fd. */
break; break;
@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo) @@ -3175,6 +3187,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
repinfo->c->tcp_timeout_msec); repinfo->c->tcp_timeout_msec);
} }
} }
@ -3437,7 +3437,7 @@ index 9fe5da2d..037e70d1 100644
} }
void void
@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo) @@ -3184,6 +3199,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
return; return;
log_assert(repinfo->c); log_assert(repinfo->c);
log_assert(repinfo->c->type != comm_tcp_accept); log_assert(repinfo->c->type != comm_tcp_accept);
@ -3447,7 +3447,7 @@ index 9fe5da2d..037e70d1 100644
if(repinfo->c->type == comm_udp) if(repinfo->c->type == comm_udp)
return; return;
if(repinfo->c->tcp_req_info) if(repinfo->c->tcp_req_info)
@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec) @@ -3205,6 +3223,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
{ {
verbose(VERB_ALGO, "comm point start listening %d (%d msec)", verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
c->fd==-1?newfd:c->fd, msec); c->fd==-1?newfd:c->fd, msec);
@ -3458,7 +3458,7 @@ index 9fe5da2d..037e70d1 100644
/* no use to start listening no free slots. */ /* no use to start listening no free slots. */
return; return;
diff --git a/util/netevent.h b/util/netevent.h diff --git a/util/netevent.h b/util/netevent.h
index d80c72b3..0233292f 100644 index bb2cd1e5..666067e8 100644
--- a/util/netevent.h --- a/util/netevent.h
+++ b/util/netevent.h +++ b/util/netevent.h
@@ -120,6 +120,10 @@ struct comm_reply { @@ -120,6 +120,10 @@ struct comm_reply {

View file

@ -7,8 +7,7 @@ Name: unbound
Description: Library with validating, recursive, and caching DNS resolver Description: Library with validating, recursive, and caching DNS resolver
URL: http://www.unbound.net URL: http://www.unbound.net
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@ Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@ @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@
Libs: -L${libdir} -lunbound Libs: -L${libdir} -lunbound
Libs.private: @SSLLIB@ @LIBS@ Libs.private: @SSLLIB@ @LIBS@
Cflags: -I${includedir} Cflags: -I${includedir}

180
contrib/metrics.awk Normal file
View file

@ -0,0 +1,180 @@
# read output of unbound-control stats
# and output prometheus metrics style output.
# use these options:
# server: extended-statistics: yes
# statistics-cumulative: no
# statistics-interval: 0
# remote-control: control-enable: yes
# Can use it like unbound-control stats | awk -f "metrics.awk"
BEGIN {
FS="=";
}
# everything like total.num.queries=value is put in val["total.num.queries"]
/^.*\..*=/ {
val[$1]=$2;
}
# print the output metrics
END {
print "# HELP unbound_hits_queries Unbound DNS traffic and cache hits"
print "# TYPE unbound_hits_queries gauge"
print "unbound_hits_queries{type=\"total.num.queries\"} " val["total.num.queries"];
for (x=0; x<99; x++) {
if(val["thread" $x ".num.queries"] != "") {
print "unbound_hits_queries{type=\"thread" $x ".num.queries\"} " val["thread" $x ".num.queries"];
}
}
print "unbound_hits_queries{type=\"total.num.cachehits\"} " val["total.num.cachehits"];
print "unbound_hits_queries{type=\"total.num.prefetch\"} " val["total.num.prefetch"];
print "unbound_hits_queries{type=\"num.query.tcp\"} " val["num.query.tcp"];
print "unbound_hits_queries{type=\"num.query.tcpout\"} " val["num.query.tcpout"];
print "unbound_hits_queries{type=\"num.query.tls\"} " val["num.query.tls"];
print "unbound_hits_queries{type=\"num.query.tls.resume\"} " val["num.query.tls.resume"];
print "unbound_hits_queries{type=\"num.query.ipv6\"} " val["num.query.ipv6"];
print "unbound_hits_queries{type=\"unwanted.queries\"} " val["unwanted.queries"];
print ""
print "# HELP unbound_queue_queries Unbound requestlist size"
print "# TYPE unbound_queue_queries gauge"
print "unbound_queue_queries{type=\"total.requestlist.avg\"} " val["total.requestlist.avg"];
print "unbound_queue_queries{type=\"total.requestlist.max\"} " val["total.requestlist.max"];
print "unbound_queue_queries{type=\"total.requestlist.overwritten\"} " val["total.requestlist.overwritten"];
print "unbound_queue_queries{type=\"total.requestlist.exceeded\"} " val["total.requestlist.exceeded"];
print ""
print "# HELP unbound_memory_bytes Unbound memory usage"
print "# TYPE unbound_memory_bytes gauge"
print "unbound_memory_bytes{type=\"mem.cache.rrset\"} " val["mem.cache.rrset"];
print "unbound_memory_bytes{type=\"mem.cache.message\"} " val["mem.cache.message"];
print "unbound_memory_bytes{type=\"mem.mod.iterator\"} " val["mem.mod.iterator"];
if(val["mem.mod.validator"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.validator\"} " val["mem.mod.validator"];
}
if(val["mem.mod.respip"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.respip\"} " val["mem.mod.respip"];
}
if(val["mem.mod.subnet"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.subnet\"} " val["mem.mod.subnet"];
}
if(val["mem.mod.ipsecmod"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.ipsecmod\"} " val["mem.mod.ipsecmod"];
}
if(val["mem.mod.dynlibmod"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.dynlibmod\"} " val["mem.mod.dynlibmod"];
}
print "unbound_memory_bytes{type=\"msg.cache.count\"} " val["msg.cache.count"];
print "unbound_memory_bytes{type=\"rrset.cache.count\"} " val["rrset.cache.count"];
print "unbound_memory_bytes{type=\"infra.cache.count\"} " val["infra.cache.count"];
print "unbound_memory_bytes{type=\"key.cache.count\"} " val["key.cache.count"];
print ""
print "# HELP unbound_by_type_queries Unbound DNS queries by type"
print "# TYPE unbound_by_type_queries gauge"
for(x in val) {
if(x ~ /^num.query.type./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_type_queries{type=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_class_queries Unbound DNS queries by class"
print "# TYPE unbound_by_class_queries gauge"
for(x in val) {
if(x ~ /^num.query.class./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_class_queries{class=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_opcode_queries Unbound DNS queries by opcode"
print "# TYPE unbound_by_opcode_queries gauge"
for(x in val) {
if(x ~ /^num.query.opcode./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_opcode_queries{opcode=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_rcode_queries Unbound DNS answers by rcode"
print "# TYPE unbound_by_rcode_queries gauge"
for(x in val) {
if(x ~ /^num.answer.rcode./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_rcode_queries{rcode=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_flags_queries Unbound DNS queries by flags"
print "# TYPE unbound_by_flags_queries gauge"
for(x in val) {
if(x ~ /^num.query.flags./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_flags_queries{flag=\"" a[4] "\"} " val[x];
}
}
}
if(val["num.query.edns.present"] != "") {
print "unbound_by_flags_queries{flag=\"num.query.edns.present\"} " val["num.query.edns.present"];
}
if(val["num.query.edns.DO"] != "") {
print "unbound_by_flags_queries{flag=\"num.query.edns.DO\"} " val["num.query.edns.DO"];
}
print ""
print "# HELP unbound_histogram_seconds Unbound DNS histogram of reply time"
print "# TYPE unbound_histogram_seconds gauge"
print "unbound_histogram_seconds{bucket=\"000000.000000.to.000000.000001\"} " val["histogram.000000.000000.to.000000.000001"];
print "unbound_histogram_seconds{bucket=\"000000.000001.to.000000.000002\"} " val["histogram.000000.000001.to.000000.000002"];
print "unbound_histogram_seconds{bucket=\"000000.000002.to.000000.000004\"} " val["histogram.000000.000002.to.000000.000004"];
print "unbound_histogram_seconds{bucket=\"000000.000004.to.000000.000008\"} " val["histogram.000000.000004.to.000000.000008"];
print "unbound_histogram_seconds{bucket=\"000000.000008.to.000000.000016\"} " val["histogram.000000.000008.to.000000.000016"];
print "unbound_histogram_seconds{bucket=\"000000.000016.to.000000.000032\"} " val["histogram.000000.000016.to.000000.000032"];
print "unbound_histogram_seconds{bucket=\"000000.000032.to.000000.000064\"} " val["histogram.000000.000032.to.000000.000064"];
print "unbound_histogram_seconds{bucket=\"000000.000064.to.000000.000128\"} " val["histogram.000000.000064.to.000000.000128"];
print "unbound_histogram_seconds{bucket=\"000000.000128.to.000000.000256\"} " val["histogram.000000.000128.to.000000.000256"];
print "unbound_histogram_seconds{bucket=\"000000.000256.to.000000.000512\"} " val["histogram.000000.000256.to.000000.000512"];
print "unbound_histogram_seconds{bucket=\"000000.000512.to.000000.001024\"} " val["histogram.000000.000512.to.000000.001024"];
print "unbound_histogram_seconds{bucket=\"000000.001024.to.000000.002048\"} " val["histogram.000000.001024.to.000000.002048"];
print "unbound_histogram_seconds{bucket=\"000000.002048.to.000000.004096\"} " val["histogram.000000.002048.to.000000.004096"];
print "unbound_histogram_seconds{bucket=\"000000.004096.to.000000.008192\"} " val["histogram.000000.004096.to.000000.008192"];
print "unbound_histogram_seconds{bucket=\"000000.008192.to.000000.016384\"} " val["histogram.000000.008192.to.000000.016384"];
print "unbound_histogram_seconds{bucket=\"000000.016384.to.000000.032768\"} " val["histogram.000000.016384.to.000000.032768"];
print "unbound_histogram_seconds{bucket=\"000000.032768.to.000000.065536\"} " val["histogram.000000.032768.to.000000.065536"];
print "unbound_histogram_seconds{bucket=\"000000.065536.to.000000.131072\"} " val["histogram.000000.065536.to.000000.131072"];
print "unbound_histogram_seconds{bucket=\"000000.131072.to.000000.262144\"} " val["histogram.000000.131072.to.000000.262144"];
print "unbound_histogram_seconds{bucket=\"000000.262144.to.000000.524288\"} " val["histogram.000000.262144.to.000000.524288"];
print "unbound_histogram_seconds{bucket=\"000000.524288.to.000001.000000\"} " val["histogram.000000.524288.to.000001.000000"];
print "unbound_histogram_seconds{bucket=\"000001.000000.to.000002.000000\"} " val["histogram.000001.000000.to.000002.000000"];
print "unbound_histogram_seconds{bucket=\"000002.000000.to.000004.000000\"} " val["histogram.000002.000000.to.000004.000000"];
print "unbound_histogram_seconds{bucket=\"000004.000000.to.000008.000000\"} " val["histogram.000004.000000.to.000008.000000"];
print "unbound_histogram_seconds{bucket=\"000008.000000.to.000016.000000\"} " val["histogram.000008.000000.to.000016.000000"];
print "unbound_histogram_seconds{bucket=\"000016.000000.to.000032.000000\"} " val["histogram.000016.000000.to.000032.000000"];
print "unbound_histogram_seconds{bucket=\"000032.000000.to.000064.000000\"} " val["histogram.000032.000000.to.000064.000000"];
print "unbound_histogram_seconds{bucket=\"000064.000000.to.000128.000000\"} " val["histogram.000064.000000.to.000128.000000"];
print "unbound_histogram_seconds{bucket=\"000128.000000.to.000256.000000\"} " val["histogram.000128.000000.to.000256.000000"];
print "unbound_histogram_seconds{bucket=\"000256.000000.to.000512.000000\"} " val["histogram.000256.000000.to.000512.000000"];
print "unbound_histogram_seconds{bucket=\"000512.000000.to.001024.000000\"} " val["histogram.000512.000000.to.001024.000000"];
print "unbound_histogram_seconds{bucket=\"001024.000000.to.002048.000000\"} " val["histogram.001024.000000.to.002048.000000"];
print "unbound_histogram_seconds{bucket=\"002048.000000.to.004096.000000\"} " val["histogram.002048.000000.to.004096.000000"];
print "unbound_histogram_seconds{bucket=\"004096.000000.to.008192.000000\"} " val["histogram.004096.000000.to.008192.000000"];
print "unbound_histogram_seconds{bucket=\"008192.000000.to.016384.000000\"} " val["histogram.008192.000000.to.016384.000000"];
print "unbound_histogram_seconds{bucket=\"016384.000000.to.032768.000000\"} " val["histogram.016384.000000.to.032768.000000"];
print "unbound_histogram_seconds{bucket=\"032768.000000.to.065536.000000\"} " val["histogram.032768.000000.to.065536.000000"];
print "unbound_histogram_seconds{bucket=\"065536.000000.to.131072.000000\"} " val["histogram.065536.000000.to.131072.000000"];
print "unbound_histogram_seconds{bucket=\"131072.000000.to.262144.000000\"} " val["histogram.131072.000000.to.262144.000000"];
print "unbound_histogram_seconds{bucket=\"262144.000000.to.524288.000000\"} " val["histogram.262144.000000.to.524288.000000"];
print ""
}

View file

@ -42,9 +42,9 @@
[Unit] [Unit]
Description=Validating, recursive, and caching DNS resolver Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8) Documentation=man:unbound(8)
After=network.target After=network-online.target
Before=network-online.target nss-lookup.target Before=nss-lookup.target
Wants=nss-lookup.target Wants=network-online.target nss-lookup.target
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -66,7 +66,7 @@ ProtectSystem=strict
RuntimeDirectory=unbound RuntimeDirectory=unbound
ConfigurationDirectory=unbound ConfigurationDirectory=unbound
StateDirectory=unbound StateDirectory=unbound
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictRealtime=true RestrictRealtime=true
SystemCallArchitectures=native SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources

View file

@ -174,11 +174,11 @@ get_state ( ) {
if test "$1" = "autoconf" ; then if test "$1" = "autoconf" ; then
if test ! -f $conf; then if test ! -f $conf; then
echo no "($conf does not exist)" echo no "($conf does not exist)"
exit 1 exit 0
fi fi
if test ! -d `dirname $state`; then if test ! -d `dirname $state`; then
echo no "(`dirname $state` directory does not exist)" echo no "(`dirname $state` directory does not exist)"
exit 1 exit 0
fi fi
echo yes echo yes
exit 0 exit 0

View file

@ -38,7 +38,7 @@ ProtectSystem=strict
RuntimeDirectory=unbound RuntimeDirectory=unbound
ConfigurationDirectory=unbound ConfigurationDirectory=unbound
StateDirectory=unbound StateDirectory=unbound
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictRealtime=true RestrictRealtime=true
SystemCallArchitectures=native SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources

View file

@ -273,7 +273,7 @@ check_data(const char* data, const struct config_strlist* head)
if(res == 0) if(res == 0)
return 1; return 1;
log_err("rr data [char %d] parse error %s", log_err("rr data [char %d] parse error %s",
(int)LDNS_WIREPARSE_OFFSET(res)-13, (int)LDNS_WIREPARSE_OFFSET(res)-2,
sldns_get_errorstr_parse(res)); sldns_get_errorstr_parse(res));
return 0; return 0;
} }

View file

@ -77,6 +77,7 @@
#include "util/storage/lookup3.h" #include "util/storage/lookup3.h"
#include "util/storage/slabhash.h" #include "util/storage/slabhash.h"
#include "util/tcp_conn_limit.h" #include "util/tcp_conn_limit.h"
#include "util/edns.h"
#include "services/listen_dnsport.h" #include "services/listen_dnsport.h"
#include "services/cache/rrset.h" #include "services/cache/rrset.h"
#include "services/cache/infra.h" #include "services/cache/infra.h"
@ -290,6 +291,15 @@ daemon_init(void)
free(daemon); free(daemon);
return NULL; return NULL;
} }
if(!(daemon->env->edns_strings = edns_strings_create())) {
auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
return daemon; return daemon;
} }
@ -298,6 +308,8 @@ daemon_open_shared_ports(struct daemon* daemon)
{ {
log_assert(daemon); log_assert(daemon);
if(daemon->cfg->port != daemon->listening_port) { if(daemon->cfg->port != daemon->listening_port) {
char** resif = NULL;
int num_resif = 0;
size_t i; size_t i;
struct listen_port* p0; struct listen_port* p0;
daemon->reuseport = 0; daemon->reuseport = 0;
@ -308,15 +320,18 @@ daemon_open_shared_ports(struct daemon* daemon)
free(daemon->ports); free(daemon->ports);
daemon->ports = NULL; daemon->ports = NULL;
} }
if(!resolve_interface_names(daemon->cfg, &resif, &num_resif))
return 0;
/* see if we want to reuseport */ /* see if we want to reuseport */
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0) if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0)
daemon->reuseport = 1; daemon->reuseport = 1;
#endif #endif
/* try to use reuseport */ /* try to use reuseport */
p0 = listening_ports_open(daemon->cfg, &daemon->reuseport); p0 = listening_ports_open(daemon->cfg, resif, num_resif, &daemon->reuseport);
if(!p0) { if(!p0) {
listening_ports_free(p0); listening_ports_free(p0);
config_del_strarray(resif, num_resif);
return 0; return 0;
} }
if(daemon->reuseport) { if(daemon->reuseport) {
@ -330,6 +345,7 @@ daemon_open_shared_ports(struct daemon* daemon)
if(!(daemon->ports = (struct listen_port**)calloc( if(!(daemon->ports = (struct listen_port**)calloc(
daemon->num_ports, sizeof(*daemon->ports)))) { daemon->num_ports, sizeof(*daemon->ports)))) {
listening_ports_free(p0); listening_ports_free(p0);
config_del_strarray(resif, num_resif);
return 0; return 0;
} }
daemon->ports[0] = p0; daemon->ports[0] = p0;
@ -338,16 +354,19 @@ daemon_open_shared_ports(struct daemon* daemon)
for(i=1; i<daemon->num_ports; i++) { for(i=1; i<daemon->num_ports; i++) {
if(!(daemon->ports[i]= if(!(daemon->ports[i]=
listening_ports_open(daemon->cfg, listening_ports_open(daemon->cfg,
resif, num_resif,
&daemon->reuseport)) &daemon->reuseport))
|| !daemon->reuseport ) { || !daemon->reuseport ) {
for(i=0; i<daemon->num_ports; i++) for(i=0; i<daemon->num_ports; i++)
listening_ports_free(daemon->ports[i]); listening_ports_free(daemon->ports[i]);
free(daemon->ports); free(daemon->ports);
daemon->ports = NULL; daemon->ports = NULL;
config_del_strarray(resif, num_resif);
return 0; return 0;
} }
} }
} }
config_del_strarray(resif, num_resif);
daemon->listening_port = daemon->cfg->port; daemon->listening_port = daemon->cfg->port;
} }
if(!daemon->cfg->remote_control_enable && daemon->rc_port) { if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
@ -635,6 +654,10 @@ daemon_fork(struct daemon* daemon)
&daemon->use_rpz)) &daemon->use_rpz))
fatal_exit("auth_zones could not be setup"); fatal_exit("auth_zones could not be setup");
/* Set-up EDNS strings */
if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
fatal_exit("Could not set up EDNS strings");
/* setup modules */ /* setup modules */
daemon_setup_modules(daemon); daemon_setup_modules(daemon);
@ -766,6 +789,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache); rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache); infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env); edns_known_options_delete(daemon->env);
edns_strings_delete(daemon->env->edns_strings);
auth_zones_delete(daemon->env->auth_zones); auth_zones_delete(daemon->env->auth_zones);
} }
ub_randfree(daemon->rand); ub_randfree(daemon->rand);

View file

@ -329,7 +329,8 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* open fd */ /* open fd */
fd = create_tcp_accept_sock(res, 1, &noproto, 0, fd = create_tcp_accept_sock(res, 1, &noproto, 0,
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd, cfg->ip_dscp); cfg->ip_transparent, 0, 0, cfg->ip_freebind,
cfg->use_systemd, cfg->ip_dscp);
freeaddrinfo(res); freeaddrinfo(res);
} }
@ -348,11 +349,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* alloc */ /* alloc */
n = (struct listen_port*)calloc(1, sizeof(*n)); n = (struct listen_port*)calloc(1, sizeof(*n));
if(!n) { if(!n) {
#ifndef USE_WINSOCK sock_close(fd);
close(fd);
#else
closesocket(fd);
#endif
log_err("out of memory"); log_err("out of memory");
return 0; return 0;
} }
@ -461,11 +458,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
if(rc->active >= rc->max_active) { if(rc->active >= rc->max_active) {
log_warn("drop incoming remote control: too many connections"); log_warn("drop incoming remote control: too many connections");
close_exit: close_exit:
#ifndef USE_WINSOCK sock_close(newfd);
close(newfd);
#else
closesocket(newfd);
#endif
return 0; return 0;
} }
@ -574,11 +567,8 @@ ssl_print_text(RES* res, const char* text)
if(r == -1) { if(r == -1) {
if(errno == EAGAIN || errno == EINTR) if(errno == EAGAIN || errno == EINTR)
continue; continue;
#ifndef USE_WINSOCK log_err("could not send: %s",
log_err("could not send: %s", strerror(errno)); sock_strerror(errno));
#else
log_err("could not send: %s", wsa_strerror(WSAGetLastError()));
#endif
return 0; return 0;
} }
at += r; at += r;
@ -635,11 +625,8 @@ ssl_read_line(RES* res, char* buf, size_t max)
} }
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
continue; continue;
#ifndef USE_WINSOCK log_err("could not recv: %s",
log_err("could not recv: %s", strerror(errno)); sock_strerror(errno));
#else
log_err("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
return 0; return 0;
} }
break; break;
@ -804,6 +791,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
size_t dnscrypt_shared_secret = 0; size_t dnscrypt_shared_secret = 0;
size_t dnscrypt_nonce = 0; size_t dnscrypt_nonce = 0;
#endif /* USE_DNSCRYPT */ #endif /* USE_DNSCRYPT */
#ifdef WITH_DYNLIBMODULE
size_t dynlib = 0;
#endif /* WITH_DYNLIBMODULE */
msg = slabhash_get_mem(daemon->env->msg_cache); msg = slabhash_get_mem(daemon->env->msg_cache);
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table); rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
val = mod_get_mem(&worker->env, "validator"); val = mod_get_mem(&worker->env, "validator");
@ -822,6 +812,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache); dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
} }
#endif /* USE_DNSCRYPT */ #endif /* USE_DNSCRYPT */
#ifdef WITH_DYNLIBMODULE
dynlib = mod_get_mem(&worker->env, "dynlib");
#endif /* WITH_DYNLIBMODULE */
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset)) if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
return 0; return 0;
@ -849,9 +842,19 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
dnscrypt_nonce)) dnscrypt_nonce))
return 0; return 0;
#endif /* USE_DNSCRYPT */ #endif /* USE_DNSCRYPT */
#ifdef WITH_DYNLIBMODULE
if(!print_longnum(ssl, "mem.mod.dynlibmod"SQ, dynlib))
return 0;
#endif /* WITH_DYNLIBMODULE */
if(!print_longnum(ssl, "mem.streamwait"SQ, if(!print_longnum(ssl, "mem.streamwait"SQ,
(size_t)s->svr.mem_stream_wait)) (size_t)s->svr.mem_stream_wait))
return 0; return 0;
if(!print_longnum(ssl, "mem.http.query_buffer"SQ,
(size_t)s->svr.mem_http2_query_buffer))
return 0;
if(!print_longnum(ssl, "mem.http.response_buffer"SQ,
(size_t)s->svr.mem_http2_response_buffer))
return 0;
return 1; return 1;
} }
@ -978,6 +981,8 @@ print_ext(RES* ssl, struct ub_stats_info* s)
(unsigned long)s->svr.qtls_resume)) return 0; (unsigned long)s->svr.qtls_resume)) return 0;
if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n", if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n",
(unsigned long)s->svr.qipv6)) return 0; (unsigned long)s->svr.qipv6)) return 0;
if(!ssl_printf(ssl, "num.query.https"SQ"%lu\n",
(unsigned long)s->svr.qhttps)) return 0;
/* flags */ /* flags */
if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%lu\n", if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%lu\n",
(unsigned long)s->svr.qbit_QR)) return 0; (unsigned long)s->svr.qbit_QR)) return 0;
@ -2855,6 +2860,57 @@ do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a); slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a);
} }
/** do the rpz_enable/disable command */
static void
do_rpz_enable_disable(RES* ssl, struct worker* worker, char* arg, int enable) {
size_t nmlen;
int nmlabs;
uint8_t *nm = NULL;
struct auth_zones *az = worker->env.auth_zones;
struct auth_zone *z = NULL;
if (!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
return;
if (az) {
lock_rw_rdlock(&az->lock);
z = auth_zone_find(az, nm, nmlen, LDNS_RR_CLASS_IN);
if (z) {
lock_rw_wrlock(&z->lock);
}
lock_rw_unlock(&az->lock);
}
free(nm);
if (!z) {
(void) ssl_printf(ssl, "error no auth-zone %s\n", arg);
return;
}
if (!z->rpz) {
(void) ssl_printf(ssl, "error auth-zone %s not RPZ\n", arg);
lock_rw_unlock(&z->lock);
return;
}
if (enable) {
rpz_enable(z->rpz);
} else {
rpz_disable(z->rpz);
}
lock_rw_unlock(&z->lock);
send_ok(ssl);
}
/** do the rpz_enable command */
static void
do_rpz_enable(RES* ssl, struct worker* worker, char* arg)
{
do_rpz_enable_disable(ssl, worker, arg, 1);
}
/** do the rpz_disable command */
static void
do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
{
do_rpz_enable_disable(ssl, worker, arg, 0);
}
/** tell other processes to execute the command */ /** tell other processes to execute the command */
static void static void
distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd) distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
@ -3055,6 +3111,10 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_flush_bogus(ssl, worker); do_flush_bogus(ssl, worker);
} else if(cmdcmp(p, "flush_negative", 14)) { } else if(cmdcmp(p, "flush_negative", 14)) {
do_flush_negative(ssl, worker); do_flush_negative(ssl, worker);
} else if(cmdcmp(p, "rpz_enable", 10)) {
do_rpz_enable(ssl, worker, skipwhite(p+10));
} else if(cmdcmp(p, "rpz_disable", 11)) {
do_rpz_disable(ssl, worker, skipwhite(p+11));
} else { } else {
(void)ssl_printf(ssl, "error unknown command '%s'\n", p); (void)ssl_printf(ssl, "error unknown command '%s'\n", p);
} }
@ -3106,11 +3166,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
if(rr == 0) return; if(rr == 0) return;
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
continue; continue;
#ifndef USE_WINSOCK log_err("could not recv: %s", sock_strerror(errno));
log_err("could not recv: %s", strerror(errno));
#else
log_err("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
return; return;
} }
r = (int)rr; r = (int)rr;

View file

@ -271,6 +271,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure; s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus; s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata; s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
s->svr.ans_expired += (long long)worker->env.mesh->ans_expired;
for(i=0; i<UB_STATS_RCODE_NUM; i++) for(i=0; i<UB_STATS_RCODE_NUM; i++)
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i]; s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
@ -335,6 +336,10 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
} }
s->svr.mem_stream_wait = s->svr.mem_stream_wait =
(long long)tcp_req_info_get_stream_buffer_size(); (long long)tcp_req_info_get_stream_buffer_size();
s->svr.mem_http2_query_buffer =
(long long)http2_get_query_buffer_size();
s->svr.mem_http2_response_buffer =
(long long)http2_get_response_buffer_size();
/* Set neg cache usage numbers */ /* Set neg cache usage numbers */
set_neg_cache_stats(worker, &s->svr, reset); set_neg_cache_stats(worker, &s->svr, reset);
@ -421,6 +426,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing; total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
total->svr.qtls += a->svr.qtls; total->svr.qtls += a->svr.qtls;
total->svr.qtls_resume += a->svr.qtls_resume; total->svr.qtls_resume += a->svr.qtls_resume;
total->svr.qhttps += a->svr.qhttps;
total->svr.qipv6 += a->svr.qipv6; total->svr.qipv6 += a->svr.qipv6;
total->svr.qbit_QR += a->svr.qbit_QR; total->svr.qbit_QR += a->svr.qbit_QR;
total->svr.qbit_AA += a->svr.qbit_AA; total->svr.qbit_AA += a->svr.qbit_AA;
@ -484,6 +490,8 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
if(SSL_session_reused(c->ssl)) if(SSL_session_reused(c->ssl))
stats->qtls_resume++; stats->qtls_resume++;
#endif #endif
if(c->type == comm_http)
stats->qhttps++;
} }
} }
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen)) if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))

View file

@ -92,7 +92,7 @@
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH) #if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
#undef HAVE_FORK #undef HAVE_FORK
#endif #endif
@ -337,22 +337,44 @@ readpid (const char* file)
/** write pid to file. /** write pid to file.
* @param pidfile: file name of pid file. * @param pidfile: file name of pid file.
* @param pid: pid to write to file. * @param pid: pid to write to file.
* @return false on failure
*/ */
static void static int
writepid (const char* pidfile, pid_t pid) writepid (const char* pidfile, pid_t pid)
{ {
FILE* f; int fd;
char pidbuf[32];
size_t count = 0;
snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid);
if ((f = fopen(pidfile, "w")) == NULL ) { if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC
#ifdef O_NOFOLLOW
| O_NOFOLLOW
#endif
, 0644)) == -1) {
log_err("cannot open pidfile %s: %s", log_err("cannot open pidfile %s: %s",
pidfile, strerror(errno)); pidfile, strerror(errno));
return; return 0;
} }
if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) { while(count < strlen(pidbuf)) {
log_err("cannot write to pidfile %s: %s", ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
pidfile, strerror(errno)); if(r == -1) {
if(errno == EAGAIN || errno == EINTR)
continue;
log_err("cannot write to pidfile %s: %s",
pidfile, strerror(errno));
close(fd);
return 0;
} else if(r == 0) {
log_err("cannot write any bytes to pidfile %s: "
"write returns 0 bytes written", pidfile);
close(fd);
return 0;
}
count += r;
} }
fclose(f); close(fd);
return 1;
} }
/** /**
@ -506,16 +528,17 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
/* write new pidfile (while still root, so can be outside chroot) */ /* write new pidfile (while still root, so can be outside chroot) */
#ifdef HAVE_KILL #ifdef HAVE_KILL
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) { if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
writepid(daemon->pidfile, getpid()); if(writepid(daemon->pidfile, getpid())) {
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 && if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
pidinchroot) { pidinchroot) {
# ifdef HAVE_CHOWN # ifdef HAVE_CHOWN
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) { if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s", verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
(unsigned)cfg_uid, (unsigned)cfg_gid, (unsigned)cfg_uid, (unsigned)cfg_gid,
daemon->pidfile, strerror(errno)); daemon->pidfile, strerror(errno));
} }
# endif /* HAVE_CHOWN */ # endif /* HAVE_CHOWN */
}
} }
} }
#else #else
@ -534,6 +557,8 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0) LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
log_warn("unable to setusercontext %s: %s", log_warn("unable to setusercontext %s: %s",
cfg->username, strerror(errno)); cfg->username, strerror(errno));
#else
(void)pwd;
#endif /* HAVE_SETUSERCONTEXT */ #endif /* HAVE_SETUSERCONTEXT */
} }
#endif /* HAVE_GETPWNAM */ #endif /* HAVE_GETPWNAM */

View file

@ -513,7 +513,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
edns->ext_rcode = 0; edns->ext_rcode = 0;
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
return 0; return 0;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns); &msg->qinfo, id, flags, edns);
@ -544,7 +545,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
edns->ext_rcode = 0; edns->ext_rcode = 0;
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep, if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad,
worker->env.now_tv))
return 0; return 0;
msg->rep->flags |= BIT_QR|BIT_RA; msg->rep->flags |= BIT_QR|BIT_RA;
if(!apply_edns_options(edns, &edns_bak, worker->env.cfg, if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
@ -553,7 +555,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
repinfo->c->buffer, 0, 1, worker->scratchpad, repinfo->c->buffer, 0, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) { udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL, if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns); &msg->qinfo, id, flags, edns);
@ -576,7 +579,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset, struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
struct reply_info** encode_repp, struct auth_zones* az) struct reply_info** encode_repp, struct auth_zones* az)
{ {
struct respip_action_info actinfo = {0}; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
actinfo.action = respip_none; actinfo.action = respip_none;
if(qinfo->qtype != LDNS_RR_TYPE_A && if(qinfo->qtype != LDNS_RR_TYPE_A &&
@ -684,7 +687,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
edns->ext_rcode = 0; edns->ext_rcode = 0;
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep, if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
goto bail_out; goto bail_out;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns); qinfo, id, flags, edns);
@ -718,7 +722,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
edns->ext_rcode = 0; edns->ext_rcode = 0;
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep, if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad,
worker->env.now_tv))
goto bail_out; goto bail_out;
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */ *alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) && if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
@ -754,7 +759,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
repinfo->c->buffer, timenow, 1, worker->scratchpad, repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) { udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL, if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns); qinfo, id, flags, edns);
@ -842,7 +848,8 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
edns->udp_size = EDNS_ADVERTISED_SIZE; edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL, if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad)) LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
if(sldns_buffer_capacity(pkt) >= if(sldns_buffer_capacity(pkt) >=
sldns_buffer_limit(pkt)+calc_edns_field_size(edns)) sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
@ -1109,7 +1116,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
struct respip_client_info* cinfo = NULL, cinfo_tmp; struct respip_client_info* cinfo = NULL, cinfo_tmp;
memset(&qinfo, 0, sizeof(qinfo)); memset(&qinfo, 0, sizeof(qinfo));
if(error != NETEVENT_NOERROR || !repinfo) { if((error != NETEVENT_NOERROR && error != NETEVENT_DONE)|| !repinfo) {
/* some bad tcp query DNS formats give these error calls */ /* some bad tcp query DNS formats give these error calls */
verbose(VERB_ALGO, "handle request called with err=%d", error); verbose(VERB_ALGO, "handle request called with err=%d", error);
return 0; return 0;
@ -1219,7 +1226,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_QR_SET(sldns_buffer_begin(c->buffer)); LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR); LDNS_RCODE_FORMERR);
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply; goto send_reply;
} }
if(worker->env.cfg->log_queries) { if(worker->env.cfg->log_queries) {
@ -1237,7 +1243,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_RCODE_REFUSED); LDNS_RCODE_REFUSED);
if(worker->stats.extended) { if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++; worker->stats.qtype[qinfo.qtype]++;
server_stats_insrcode(&worker->stats, c->buffer);
} }
goto send_reply; goto send_reply;
} }
@ -1259,7 +1264,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_RCODE_FORMERR); LDNS_RCODE_FORMERR);
if(worker->stats.extended) { if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++; worker->stats.qtype[qinfo.qtype]++;
server_stats_insrcode(&worker->stats, c->buffer);
} }
goto send_reply; goto send_reply;
} }
@ -1275,7 +1279,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer), *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns); sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns);
regional_free_all(worker->scratchpad); regional_free_all(worker->scratchpad);
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply; goto send_reply;
} }
if(edns.edns_present) { if(edns.edns_present) {
@ -1286,6 +1289,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
edns.udp_size = EDNS_ADVERTISED_SIZE; edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO; edns.bits &= EDNS_DO;
edns.opt_list = NULL; edns.opt_list = NULL;
edns.padding_block_size = 0;
verbose(VERB_ALGO, "query with bad edns version."); verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo, error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
@ -1354,7 +1358,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
edns.udp_size = 65535; /* max size for TCP replies */ edns.udp_size = 65535; /* max size for TCP replies */
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo, if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
&edns, repinfo, c->buffer)) { &edns, repinfo, c->buffer)) {
server_stats_insrcode(&worker->stats, c->buffer);
regional_free_all(worker->scratchpad); regional_free_all(worker->scratchpad);
goto send_reply; goto send_reply;
} }
@ -1375,7 +1378,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo); comm_point_drop_reply(repinfo);
return 0; return 0;
} }
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply; goto send_reply;
} }
if(worker->env.auth_zones && if(worker->env.auth_zones &&
@ -1387,7 +1389,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo); comm_point_drop_reply(repinfo);
return 0; return 0;
} }
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply; goto send_reply;
} }
if(worker->env.auth_zones && if(worker->env.auth_zones &&
@ -1403,7 +1404,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) && if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) &&
acl != acl_deny_non_local && acl != acl_refuse_non_local) acl != acl_deny_non_local && acl != acl_refuse_non_local)
LDNS_RA_SET(sldns_buffer_begin(c->buffer)); LDNS_RA_SET(sldns_buffer_begin(c->buffer));
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply; goto send_reply;
} }
@ -1432,7 +1432,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer), *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL); sldns_buffer_read_u16_at(c->buffer, 2), NULL);
regional_free_all(worker->scratchpad); regional_free_all(worker->scratchpad);
server_stats_insrcode(&worker->stats, c->buffer);
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from", log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen); &repinfo->addr, repinfo->addrlen);
goto send_reply; goto send_reply;
@ -1588,9 +1587,9 @@ send_reply_rc:
if(is_expired_answer) { if(is_expired_answer) {
worker->stats.ans_expired++; worker->stats.ans_expired++;
} }
server_stats_insrcode(&worker->stats, c->buffer);
if(worker->stats.extended) { if(worker->stats.extended) {
if(is_secure_answer) worker->stats.ans_secure++; if(is_secure_answer) worker->stats.ans_secure++;
server_stats_insrcode(&worker->stats, repinfo->c->buffer);
} }
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
if(worker->dtenv.log_client_response_messages) if(worker->dtenv.log_client_response_messages)
@ -1726,14 +1725,6 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
return NULL; return NULL;
} }
explicit_bzero(&seed, sizeof(seed)); explicit_bzero(&seed, sizeof(seed));
#ifdef USE_DNSTAP
if(daemon->cfg->dnstap) {
log_assert(daemon->dtenv != NULL);
memcpy(&worker->dtenv, daemon->dtenv, sizeof(struct dt_env));
if(!dt_init(&worker->dtenv))
fatal_exit("dt_init failed");
}
#endif
return worker; return worker;
} }
@ -1792,13 +1783,22 @@ worker_init(struct worker* worker, struct config_file *cfg,
} else { /* !do_sigs */ } else { /* !do_sigs */
worker->comsig = NULL; worker->comsig = NULL;
} }
#ifdef USE_DNSTAP
if(cfg->dnstap) {
log_assert(worker->daemon->dtenv != NULL);
memcpy(&worker->dtenv, worker->daemon->dtenv, sizeof(struct dt_env));
if(!dt_init(&worker->dtenv, worker->base))
fatal_exit("dt_init failed");
}
#endif
worker->front = listen_create(worker->base, ports, worker->front = listen_create(worker->base, ports,
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp, cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
cfg->do_tcp_keepalive cfg->do_tcp_keepalive
? cfg->tcp_keepalive_timeout ? cfg->tcp_keepalive_timeout
: cfg->tcp_idle_timeout, : cfg->tcp_idle_timeout,
worker->daemon->tcl, cfg->harden_large_queries, cfg->http_max_streams,
worker->daemon->listen_sslctx, cfg->http_endpoint, cfg->http_notls_downstream,
worker->daemon->tcl, worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker); dtenv, worker_handle_request, worker);
if(!worker->front) { if(!worker->front) {
log_err("could not create listening sockets"); log_err("could not create listening sockets");
@ -1815,7 +1815,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
&worker_alloc_cleanup, worker, &worker_alloc_cleanup, worker,
cfg->do_udp || cfg->udp_upstream_without_downstream, cfg->do_udp || cfg->udp_upstream_without_downstream,
worker->daemon->connect_sslctx, cfg->delay_close, worker->daemon->connect_sslctx, cfg->delay_close,
cfg->tls_use_sni, dtenv); cfg->tls_use_sni, dtenv, cfg->udp_connect);
if(!worker->back) { if(!worker->back) {
log_err("could not create outgoing sockets"); log_err("could not create outgoing sockets");
worker_delete(worker); worker_delete(worker);

View file

@ -198,14 +198,17 @@ uitoa(unsigned n, char* s)
static uint32_t static uint32_t
extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset) extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset)
{ {
uint32_t ipv4; uint32_t ipv4 = 0;
int i, pos;
log_assert(ipv6_len == 16); (void)ipv6_len; log_assert(ipv6_len == 16); (void)ipv6_len;
ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8)) log_assert(offset == 32 || offset == 40 || offset == 48 || offset == 56 ||
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8)) offset == 64 || offset == 96);
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8)) for(i = 0, pos = offset / 8; i < 4; i++, pos++) {
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8)); if (pos == 8)
if (offset/8+4 < 16) pos++;
ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8); ipv4 = ipv4 << 8;
ipv4 |= ipv6[pos];
}
return ipv4; return ipv4;
} }
@ -296,18 +299,18 @@ synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len,
int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[], int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[],
size_t aaaa_len) size_t aaaa_len)
{ {
size_t i;
int pos;
log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16); log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16);
log_assert(prefix_net == 32 || prefix_net == 40 || prefix_net == 48 ||
prefix_net == 56 || prefix_net == 64 || prefix_net == 96);
(void)prefix_addr_len; (void)a_len; (void)aaaa_len; (void)prefix_addr_len; (void)a_len; (void)aaaa_len;
memcpy(aaaa, prefix_addr, 16); memcpy(aaaa, prefix_addr, 16);
aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8); for(i = 0, pos = prefix_net / 8; i < a_len; i++, pos++) {
aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8); if(pos == 8)
aaaa[prefix_net/8+1] |= a[1] >> (0+prefix_net%8); aaaa[pos++] = 0;
aaaa[prefix_net/8+2] |= a[1] << (8-prefix_net%8); aaaa[pos] = a[i];
aaaa[prefix_net/8+2] |= a[2] >> (0+prefix_net%8); }
aaaa[prefix_net/8+3] |= a[2] << (8-prefix_net%8);
aaaa[prefix_net/8+3] |= a[3] >> (0+prefix_net%8);
if (prefix_net/8+4 < 16) /* <-- my beautiful symmetry is destroyed! */
aaaa[prefix_net/8+4] |= a[3] << (8-prefix_net%8);
} }
@ -374,8 +377,10 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix); log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
return 0; return 0;
} }
if (dns64_env->prefix_net < 0 || dns64_env->prefix_net > 96) { if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
log_err("dns64-prefix length it not between 0 and 96: %s", dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
cfg->dns64_prefix); cfg->dns64_prefix);
return 0; return 0;
} }
@ -722,7 +727,7 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
*dd_out = NULL; *dd_out = NULL;
return; /* integer overflow protection in alloc */ return; /* integer overflow protection in alloc */
} }
if (!(dd = *dd_out = regional_alloc(region, if (!(dd = *dd_out = regional_alloc_zero(region,
sizeof(struct packed_rrset_data) sizeof(struct packed_rrset_data)
+ fd->count * (sizeof(size_t) + sizeof(time_t) + + fd->count * (sizeof(size_t) + sizeof(time_t) +
sizeof(uint8_t*) + 2 + 16)))) { sizeof(uint8_t*) + 2 + 16)))) {

View file

@ -11,7 +11,7 @@ AC_DEFUN([dnsc_DNSCRYPT],
[opt_dnscrypt=$enableval], [opt_dnscrypt=no]) [opt_dnscrypt=$enableval], [opt_dnscrypt=no])
if test "x$opt_dnscrypt" != "xno"; then if test "x$opt_dnscrypt" != "xno"; then
AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path], AC_ARG_WITH([libsodium], AS_HELP_STRING([--with-libsodium=path],
[Path where libsodium is installed, for dnscrypt]), [ [Path where libsodium is installed, for dnscrypt]), [
CFLAGS="$CFLAGS -I$withval/include" CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib" LDFLAGS="$LDFLAGS -L$withval/lib"

View file

@ -134,9 +134,13 @@ dt_create(struct config_file* cfg)
if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] && if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] &&
(cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) { (cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) {
char* p = cfg->dnstap_socket_path;
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(p,
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
p += strlen(cfg->chrootdir);
verbose(VERB_OPS, "attempting to connect to dnstap socket %s", verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
cfg->dnstap_socket_path); p);
check_socket_file(cfg->dnstap_socket_path); check_socket_file(p);
} }
env = (struct dt_env *) calloc(1, sizeof(struct dt_env)); env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
@ -240,9 +244,9 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
} }
int int
dt_init(struct dt_env *env) dt_init(struct dt_env *env, struct comm_base* base)
{ {
env->msgqueue = dt_msg_queue_create(); env->msgqueue = dt_msg_queue_create(base);
if(!env->msgqueue) { if(!env->msgqueue) {
log_err("malloc failure"); log_err("malloc failure");
return 0; return 0;

View file

@ -101,10 +101,11 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
/** /**
* Initialize per-worker state in dnstap environment object. * Initialize per-worker state in dnstap environment object.
* @param env: dnstap environment object to initialize, created with dt_create(). * @param env: dnstap environment object to initialize, created with dt_create().
* @param base: event base for wakeup timer.
* @return: true on success, false on failure. * @return: true on success, false on failure.
*/ */
int int
dt_init(struct dt_env *env); dt_init(struct dt_env *env, struct comm_base* base);
/** /**
* Deletes the per-worker state created by dt_init * Deletes the per-worker state created by dt_init

View file

@ -20,7 +20,7 @@ AC_DEFUN([dt_DNSTAP],
if test -z "$PROTOC_C"; then if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!]) AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
fi fi
AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path], AC_ARG_WITH([protobuf-c], AS_HELP_STRING([--with-protobuf-c=path],
[Path where protobuf-c is installed, for dnstap]), [ [Path where protobuf-c is installed, for dnstap]), [
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0 # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then if test -f $withval/include/google/protobuf-c/protobuf-c.h; then

View file

@ -92,6 +92,34 @@ void* fstrm_create_control_frame_stop(size_t* len)
return control; return control;
} }
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len)
{
uint32_t* control;
size_t n;
/* start bidirectional stream:
* 4 bytes 0 escape
* 4 bytes bigendian length of frame
* 4 bytes bigendian type READY
* 4 bytes bigendian frame option content type
* 4 bytes bigendian length of string
* string of content type.
*/
/* len includes the escape and framelength */
n = 4+4+4+4+4+strlen(contenttype);
control = malloc(n);
if(!control) {
return NULL;
}
control[0] = 0;
control[1] = htonl(4+4+4+strlen(contenttype));
control[2] = htonl(FSTRM_CONTROL_FRAME_READY);
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
control[4] = htonl(strlen(contenttype));
memmove(&control[5], contenttype, strlen(contenttype));
*len = n;
return control;
}
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len) void* fstrm_create_control_frame_accept(char* contenttype, size_t* len)
{ {
uint32_t* control; uint32_t* control;

View file

@ -127,6 +127,21 @@
*/ */
void* fstrm_create_control_frame_start(char* contenttype, size_t* len); void* fstrm_create_control_frame_start(char* contenttype, size_t* len);
/**
* This creates an FSTRM control frame of type READY.
* @param contenttype: a zero delimited string with the content type.
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
* @param len: if a buffer is returned this is the length of that buffer.
* @return NULL on malloc failure. Returns a malloced buffer with the
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
* a control frame. The buffer should be sent without preceding it with
* the 'len' variable (like data frames are), but straight the content of the
* buffer, because the lengths are included in the buffer. This is so that
* the zero control indicator can be included before the control frame length.
*/
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len);
/** /**
* This creates an FSTRM control frame of type STOP. * This creates an FSTRM control frame of type STOP.
* @param len: if a buffer is returned this is the length of that buffer. * @param len: if a buffer is returned this is the length of that buffer.

View file

@ -48,6 +48,7 @@
#include "util/ub_event.h" #include "util/ub_event.h"
#include "util/net_help.h" #include "util/net_help.h"
#include "services/outside_network.h" #include "services/outside_network.h"
#include "sldns/sbuffer.h"
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
#include <sys/un.h> #include <sys/un.h>
#endif #endif
@ -67,6 +68,11 @@
#define DTIO_RECONNECT_TIMEOUT_MAX 1000 #define DTIO_RECONNECT_TIMEOUT_MAX 1000
/** the msec to wait for reconnect slow, to stop busy spinning on reconnect */ /** the msec to wait for reconnect slow, to stop busy spinning on reconnect */
#define DTIO_RECONNECT_TIMEOUT_SLOW 1000 #define DTIO_RECONNECT_TIMEOUT_SLOW 1000
/** number of messages before wakeup of thread */
#define DTIO_MSG_FOR_WAKEUP 32
/** maximum length of received frame */
#define DTIO_RECV_FRAME_MAX_LEN 1000
struct stop_flush_info; struct stop_flush_info;
/** DTIO command channel commands */ /** DTIO command channel commands */
@ -85,19 +91,28 @@ static int dtio_add_output_event_write(struct dt_io_thread* dtio);
static void dtio_reconnect_enable(struct dt_io_thread* dtio); static void dtio_reconnect_enable(struct dt_io_thread* dtio);
/** stop from stop_flush event loop */ /** stop from stop_flush event loop */
static void dtio_stop_flush_exit(struct stop_flush_info* info); static void dtio_stop_flush_exit(struct stop_flush_info* info);
/** setup a start control message */
static int dtio_control_start_send(struct dt_io_thread* dtio);
#ifdef HAVE_SSL #ifdef HAVE_SSL
/** enable briefly waiting for a read event, for SSL negotiation */ /** enable briefly waiting for a read event, for SSL negotiation */
static int dtio_enable_brief_read(struct dt_io_thread* dtio); static int dtio_enable_brief_read(struct dt_io_thread* dtio);
/** enable briefly waiting for a write event, for SSL negotiation */
static int dtio_enable_brief_write(struct dt_io_thread* dtio);
#endif #endif
struct dt_msg_queue* struct dt_msg_queue*
dt_msg_queue_create(void) dt_msg_queue_create(struct comm_base* base)
{ {
struct dt_msg_queue* mq = calloc(1, sizeof(*mq)); struct dt_msg_queue* mq = calloc(1, sizeof(*mq));
if(!mq) return NULL; if(!mq) return NULL;
mq->maxsize = 1*1024*1024; /* set max size of buffer, per worker, mq->maxsize = 1*1024*1024; /* set max size of buffer, per worker,
about 1 M should contain 64K messages with some overhead, about 1 M should contain 64K messages with some overhead,
or a whole bunch smaller ones */ or a whole bunch smaller ones */
mq->wakeup_timer = comm_timer_create(base, mq_wakeup_cb, mq);
if(!mq->wakeup_timer) {
free(mq);
return NULL;
}
lock_basic_init(&mq->lock); lock_basic_init(&mq->lock);
lock_protect(&mq->lock, mq, sizeof(*mq)); lock_protect(&mq->lock, mq, sizeof(*mq));
return mq; return mq;
@ -117,6 +132,7 @@ dt_msg_queue_clear(struct dt_msg_queue* mq)
mq->first = NULL; mq->first = NULL;
mq->last = NULL; mq->last = NULL;
mq->cursize = 0; mq->cursize = 0;
mq->msgcount = 0;
} }
void void
@ -125,6 +141,7 @@ dt_msg_queue_delete(struct dt_msg_queue* mq)
if(!mq) return; if(!mq) return;
lock_basic_destroy(&mq->lock); lock_basic_destroy(&mq->lock);
dt_msg_queue_clear(mq); dt_msg_queue_clear(mq);
comm_timer_delete(mq->wakeup_timer);
free(mq); free(mq);
} }
@ -141,25 +158,71 @@ static void dtio_wakeup(struct dt_io_thread* dtio)
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
continue; continue;
log_err("dnstap io wakeup: write: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS) if(WSAGetLastError() == WSAEINPROGRESS)
continue; continue;
if(WSAGetLastError() == WSAEWOULDBLOCK) if(WSAGetLastError() == WSAEWOULDBLOCK)
continue; continue;
log_err("dnstap io stop: write: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("dnstap io wakeup: write: %s",
sock_strerror(errno));
break; break;
} }
break; break;
} }
} }
void
mq_wakeup_cb(void* arg)
{
struct dt_msg_queue* mq = (struct dt_msg_queue*)arg;
/* even if the dtio is already active, because perhaps much
* traffic suddenly, we leave the timer running to save on
* managing it, the once a second timer is less work then
* starting and stopping the timer frequently */
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
mq->dtio->wakeup_timer_enabled = 0;
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
dtio_wakeup(mq->dtio);
}
/** start timer to wakeup dtio because there is content in the queue */
static void
dt_msg_queue_start_timer(struct dt_msg_queue* mq)
{
struct timeval tv;
/* Start a timer to process messages to be logged.
* If we woke up the dtio thread for every message, the wakeup
* messages take up too much processing power. If the queue
* fills up the wakeup happens immediately. The timer wakes it up
* if there are infrequent messages to log. */
/* we cannot start a timer in dtio thread, because it is a different
* thread and its event base is in use by the other thread, it would
* give race conditions if we tried to modify its event base,
* and locks would wait until it woke up, and this is what we do. */
/* do not start the timer if a timer already exists, perhaps
* in another worker. So this variable is protected by a lock in
* dtio */
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
if(mq->dtio->wakeup_timer_enabled) {
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
return;
}
mq->dtio->wakeup_timer_enabled = 1; /* we are going to start one */
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
/* start the timer, in mq, in the event base of our worker */
tv.tv_sec = 1;
tv.tv_usec = 0;
comm_timer_set(mq->wakeup_timer, &tv);
}
void void
dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
{ {
int wakeup = 0; int wakeupnow = 0, wakeupstarttimer = 0;
struct dt_msg_entry* entry; struct dt_msg_entry* entry;
/* check conditions */ /* check conditions */
@ -190,9 +253,15 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
/* aqcuire lock */ /* aqcuire lock */
lock_basic_lock(&mq->lock); lock_basic_lock(&mq->lock);
/* list was empty, wakeup dtio */ /* if list was empty, start timer for (eventual) wakeup */
if(mq->first == NULL) if(mq->first == NULL)
wakeup = 1; wakeupstarttimer = 1;
/* if list contains more than wakeupnum elements, wakeup now,
* or if list is (going to be) almost full */
if(mq->msgcount == DTIO_MSG_FOR_WAKEUP ||
(mq->cursize < mq->maxsize * 9 / 10 &&
mq->cursize+len >= mq->maxsize * 9 / 10))
wakeupnow = 1;
/* see if it is going to fit */ /* see if it is going to fit */
if(mq->cursize + len > mq->maxsize) { if(mq->cursize + len > mq->maxsize) {
/* buffer full, or congested. */ /* buffer full, or congested. */
@ -203,6 +272,7 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
return; return;
} }
mq->cursize += len; mq->cursize += len;
mq->msgcount ++;
/* append to list */ /* append to list */
if(mq->last) { if(mq->last) {
mq->last->next = entry; mq->last->next = entry;
@ -213,13 +283,19 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
/* release lock */ /* release lock */
lock_basic_unlock(&mq->lock); lock_basic_unlock(&mq->lock);
if(wakeup) if(wakeupnow) {
dtio_wakeup(mq->dtio); dtio_wakeup(mq->dtio);
} else if(wakeupstarttimer) {
dt_msg_queue_start_timer(mq);
}
} }
struct dt_io_thread* dt_io_thread_create(void) struct dt_io_thread* dt_io_thread_create(void)
{ {
struct dt_io_thread* dtio = calloc(1, sizeof(*dtio)); struct dt_io_thread* dtio = calloc(1, sizeof(*dtio));
lock_basic_init(&dtio->wakeup_timer_lock);
lock_protect(&dtio->wakeup_timer_lock, &dtio->wakeup_timer_enabled,
sizeof(dtio->wakeup_timer_enabled));
return dtio; return dtio;
} }
@ -227,6 +303,7 @@ void dt_io_thread_delete(struct dt_io_thread* dtio)
{ {
struct dt_io_list_item* item, *nextitem; struct dt_io_list_item* item, *nextitem;
if(!dtio) return; if(!dtio) return;
lock_basic_destroy(&dtio->wakeup_timer_lock);
item=dtio->io_list; item=dtio->io_list;
while(item) { while(item) {
nextitem = item->next; nextitem = item->next;
@ -261,16 +338,22 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
} else { } else {
dtio->upstream_is_unix = 1; dtio->upstream_is_unix = 1;
} }
dtio->is_bidirectional = cfg->dnstap_bidirectional;
if(dtio->upstream_is_unix) { if(dtio->upstream_is_unix) {
char* nm;
if(!cfg->dnstap_socket_path || if(!cfg->dnstap_socket_path ||
cfg->dnstap_socket_path[0]==0) { cfg->dnstap_socket_path[0]==0) {
log_err("dnstap setup: no dnstap-socket-path for " log_err("dnstap setup: no dnstap-socket-path for "
"socket connect"); "socket connect");
return 0; return 0;
} }
nm = cfg->dnstap_socket_path;
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
nm += strlen(cfg->chrootdir);
free(dtio->socket_path); free(dtio->socket_path);
dtio->socket_path = strdup(cfg->dnstap_socket_path); dtio->socket_path = strdup(nm);
if(!dtio->socket_path) { if(!dtio->socket_path) {
log_err("dnstap setup: malloc failure"); log_err("dnstap setup: malloc failure");
return 0; return 0;
@ -407,6 +490,7 @@ static int dt_msg_queue_pop(struct dt_msg_queue* mq, void** buf,
mq->first = entry->next; mq->first = entry->next;
if(!entry->next) mq->last = NULL; if(!entry->next) mq->last = NULL;
mq->cursize -= entry->len; mq->cursize -= entry->len;
mq->msgcount --;
lock_basic_unlock(&mq->lock); lock_basic_unlock(&mq->lock);
*buf = entry->buf; *buf = entry->buf;
@ -551,6 +635,20 @@ static void dtio_cur_msg_free(struct dt_io_thread* dtio)
dtio->cur_msg_len_done = 0; dtio->cur_msg_len_done = 0;
} }
/** delete the buffer and counters used to read frame */
static void dtio_read_frame_free(struct dt_frame_read_buf* rb)
{
if(rb->buf) {
free(rb->buf);
rb->buf = NULL;
}
rb->buf_count = 0;
rb->buf_cap = 0;
rb->frame_len = 0;
rb->frame_len_done = 0;
rb->control_frame = 0;
}
/** del the output file descriptor event for listening */ /** del the output file descriptor event for listening */
static void dtio_del_output_event(struct dt_io_thread* dtio) static void dtio_del_output_event(struct dt_io_thread* dtio)
{ {
@ -564,11 +662,7 @@ static void dtio_del_output_event(struct dt_io_thread* dtio)
/** close dtio socket and set it to -1 */ /** close dtio socket and set it to -1 */
static void dtio_close_fd(struct dt_io_thread* dtio) static void dtio_close_fd(struct dt_io_thread* dtio)
{ {
#ifndef USE_WINSOCK sock_close(dtio->fd);
close(dtio->fd);
#else
closesocket(dtio->fd);
#endif
dtio->fd = -1; dtio->fd = -1;
} }
@ -594,6 +688,11 @@ static void dtio_close_output(struct dt_io_thread* dtio)
if(dtio->cur_msg) { if(dtio->cur_msg) {
dtio_cur_msg_free(dtio); dtio_cur_msg_free(dtio);
} }
dtio->ready_frame_sent = 0;
dtio->accept_frame_received = 0;
dtio_read_frame_free(&dtio->read_frame);
dtio_reconnect_enable(dtio); dtio_reconnect_enable(dtio);
} }
@ -631,13 +730,8 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio)
char* to = dtio->socket_path; char* to = dtio->socket_path;
if(!to) to = dtio->ip_str; if(!to) to = dtio->ip_str;
if(!to) to = ""; if(!to) to = "";
#ifndef USE_WINSOCK
log_err("dnstap io: failed to connect to \"%s\": %s", log_err("dnstap io: failed to connect to \"%s\": %s",
to, strerror(error)); to, sock_strerror(error));
#else
log_err("dnstap io: failed to connect to \"%s\": %s",
to, wsa_strerror(error));
#endif
return -1; /* error, close it */ return -1; /* error, close it */
} }
@ -714,7 +808,6 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
return 0; return 0;
log_err("dnstap io: failed send: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS) if(WSAGetLastError() == WSAEINPROGRESS)
return 0; return 0;
@ -724,9 +817,8 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf,
UB_EV_WRITE); UB_EV_WRITE);
return 0; return 0;
} }
log_err("dnstap io: failed send: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("dnstap io: failed send: %s", sock_strerror(errno));
return -1; return -1;
} }
return ret; return ret;
@ -750,7 +842,6 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio)
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
return 0; return 0;
log_err("dnstap io: failed writev: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS) if(WSAGetLastError() == WSAEINPROGRESS)
return 0; return 0;
@ -760,9 +851,8 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio)
UB_EV_WRITE); UB_EV_WRITE);
return 0; return 0;
} }
log_err("dnstap io: failed writev: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("dnstap io: failed writev: %s", sock_strerror(errno));
/* close the channel */ /* close the channel */
dtio_del_output_event(dtio); dtio_del_output_event(dtio);
dtio_close_output(dtio); dtio_close_output(dtio);
@ -855,6 +945,94 @@ static int dtio_write_more(struct dt_io_thread* dtio)
return 1; return 1;
} }
/** Receive bytes from dtio->fd, store in buffer. Returns 0: closed,
* -1: continue, >0: number of bytes read into buffer */
static ssize_t receive_bytes(struct dt_io_thread* dtio, void* buf, size_t len) {
ssize_t r;
r = recv(dtio->fd, (void*)buf, len, 0);
if(r == -1) {
char* to = dtio->socket_path;
if(!to) to = dtio->ip_str;
if(!to) to = "";
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return -1; /* try later */
#else
if(WSAGetLastError() == WSAEINPROGRESS) {
return -1; /* try later */
} else if(WSAGetLastError() == WSAEWOULDBLOCK) {
ub_winsock_tcp_wouldblock(
(dtio->stop_flush_event?
dtio->stop_flush_event:dtio->event),
UB_EV_READ);
return -1; /* try later */
}
#endif
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4)
return 0; /* no log retries on low verbosity */
log_err("dnstap io: output closed, recv %s: %s", to,
strerror(errno));
/* and close below */
return 0;
}
if(r == 0) {
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4)
return 0; /* no log retries on low verbosity */
verbose(VERB_DETAIL, "dnstap io: output closed by the other side");
/* and close below */
return 0;
}
/* something was received */
return r;
}
#ifdef HAVE_SSL
/** Receive bytes over TLS from dtio->fd, store in buffer. Returns 0: closed,
* -1: continue, >0: number of bytes read into buffer */
static int ssl_read_bytes(struct dt_io_thread* dtio, void* buf, size_t len)
{
int r;
ERR_clear_error();
r = SSL_read(dtio->ssl, buf, len);
if(r <= 0) {
int want = SSL_get_error(dtio->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4)
return 0; /* no log retries on low verbosity */
verbose(VERB_DETAIL, "dnstap io: output closed by the "
"other side");
return 0;
} else if(want == SSL_ERROR_WANT_READ) {
/* continue later */
return -1;
} else if(want == SSL_ERROR_WANT_WRITE) {
(void)dtio_enable_brief_write(dtio);
return -1;
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef ECONNRESET
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
errno == ECONNRESET && verbosity < 4)
return 0; /* silence reset by peer */
#endif
if(errno != 0)
log_err("SSL_read syscall: %s",
strerror(errno));
verbose(VERB_DETAIL, "dnstap io: output closed by the "
"other side");
return 0;
}
log_crypto_err("could not SSL_read");
verbose(VERB_DETAIL, "dnstap io: output closed by the "
"other side");
return 0;
}
return r;
}
#endif /* HAVE_SSL */
/** check if the output fd has been closed, /** check if the output fd has been closed,
* it returns false if the stream is closed. */ * it returns false if the stream is closed. */
static int dtio_check_close(struct dt_io_thread* dtio) static int dtio_check_close(struct dt_io_thread* dtio)
@ -864,44 +1042,17 @@ static int dtio_check_close(struct dt_io_thread* dtio)
* packets is okay for the framestream protocol. And also, the * packets is okay for the framestream protocol. And also, the
* read call can return that the stream has been closed by the * read call can return that the stream has been closed by the
* other side. */ * other side. */
ssize_t r;
uint8_t buf[1024]; uint8_t buf[1024];
int r = -1;
if(dtio->fd == -1) return 0; if(dtio->fd == -1) return 0;
while(1) {
r = recv(dtio->fd, (void*)buf, sizeof(buf), 0); while(r != 0) {
if(r == -1) { /* not interested in buffer content, overwrite */
char* to = dtio->socket_path; r = receive_bytes(dtio, (void*)buf, sizeof(buf));
if(!to) to = dtio->ip_str; if(r == -1)
if(!to) to = ""; return 1;
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1; /* try later */
#else
if(WSAGetLastError() == WSAEINPROGRESS) {
return 1; /* try later */
} else if(WSAGetLastError() == WSAEWOULDBLOCK) {
ub_winsock_tcp_wouldblock(
(dtio->stop_flush_event?
dtio->stop_flush_event:dtio->event),
UB_EV_READ);
return 1; /* try later */
}
#endif
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN && verbosity < 4)
break; /* no log retries on low verbosity */
log_err("dnstap io: output closed, recv %s: %s", to,
strerror(errno));
/* and close below */
break;
}
if(r == 0) {
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN && verbosity < 4)
break; /* no log retries on low verbosity */
verbose(VERB_DETAIL, "dnstap io: output closed by the other side");
/* and close below */
break;
}
/* something was received, ignore it */
} }
/* the other end has been closed */ /* the other end has been closed */
/* close the channel */ /* close the channel */
@ -910,6 +1061,145 @@ static int dtio_check_close(struct dt_io_thread* dtio)
return 0; return 0;
} }
/** Read accept frame. Returns -1: continue reading, 0: closed,
* 1: valid accept received. */
static int dtio_read_accept_frame(struct dt_io_thread* dtio)
{
int r;
size_t read_frame_done;
while(dtio->read_frame.frame_len_done < 4) {
#ifdef HAVE_SSL
if(dtio->ssl) {
r = ssl_read_bytes(dtio,
(uint8_t*)&dtio->read_frame.frame_len+
dtio->read_frame.frame_len_done,
4-dtio->read_frame.frame_len_done);
} else {
#endif
r = receive_bytes(dtio,
(uint8_t*)&dtio->read_frame.frame_len+
dtio->read_frame.frame_len_done,
4-dtio->read_frame.frame_len_done);
#ifdef HAVE_SSL
}
#endif
if(r == -1)
return -1; /* continue reading */
if(r == 0) {
/* connection closed */
goto close_connection;
}
dtio->read_frame.frame_len_done += r;
if(dtio->read_frame.frame_len_done < 4)
return -1; /* continue reading */
if(dtio->read_frame.frame_len == 0) {
dtio->read_frame.frame_len_done = 0;
dtio->read_frame.control_frame = 1;
continue;
}
dtio->read_frame.frame_len = ntohl(dtio->read_frame.frame_len);
if(dtio->read_frame.frame_len > DTIO_RECV_FRAME_MAX_LEN) {
verbose(VERB_OPS, "dnstap: received frame exceeds max "
"length of %d bytes, closing connection",
DTIO_RECV_FRAME_MAX_LEN);
goto close_connection;
}
dtio->read_frame.buf = calloc(1, dtio->read_frame.frame_len);
dtio->read_frame.buf_cap = dtio->read_frame.frame_len;
if(!dtio->read_frame.buf) {
log_err("dnstap io: out of memory (creating read "
"buffer)");
goto close_connection;
}
}
if(dtio->read_frame.buf_count < dtio->read_frame.frame_len) {
#ifdef HAVE_SSL
if(dtio->ssl) {
r = ssl_read_bytes(dtio, dtio->read_frame.buf+
dtio->read_frame.buf_count,
dtio->read_frame.buf_cap-
dtio->read_frame.buf_count);
} else {
#endif
r = receive_bytes(dtio, dtio->read_frame.buf+
dtio->read_frame.buf_count,
dtio->read_frame.buf_cap-
dtio->read_frame.buf_count);
#ifdef HAVE_SSL
}
#endif
if(r == -1)
return -1; /* continue reading */
if(r == 0) {
/* connection closed */
goto close_connection;
}
dtio->read_frame.buf_count += r;
if(dtio->read_frame.buf_count < dtio->read_frame.frame_len)
return -1; /* continue reading */
}
/* Complete frame received, check if this is a valid ACCEPT control
* frame. */
if(dtio->read_frame.frame_len < 4) {
verbose(VERB_OPS, "dnstap: invalid data received");
goto close_connection;
}
if(sldns_read_uint32(dtio->read_frame.buf) !=
FSTRM_CONTROL_FRAME_ACCEPT) {
verbose(VERB_ALGO, "dnstap: invalid control type received, "
"ignored");
dtio->ready_frame_sent = 0;
dtio->accept_frame_received = 0;
dtio_read_frame_free(&dtio->read_frame);
return -1;
}
read_frame_done = 4; /* control frame type */
/* Iterate over control fields, ignore unknown types.
* Need to be able to read at least 8 bytes (control field type +
* length). */
while(read_frame_done+8 < dtio->read_frame.frame_len) {
uint32_t type = sldns_read_uint32(dtio->read_frame.buf +
read_frame_done);
uint32_t len = sldns_read_uint32(dtio->read_frame.buf +
read_frame_done + 4);
if(type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) {
if(len == strlen(DNSTAP_CONTENT_TYPE) &&
read_frame_done+8+len <=
dtio->read_frame.frame_len &&
memcmp(dtio->read_frame.buf + read_frame_done +
+ 8, DNSTAP_CONTENT_TYPE, len) == 0) {
if(!dtio_control_start_send(dtio)) {
verbose(VERB_OPS, "dnstap io: out of "
"memory while sending START frame");
goto close_connection;
}
dtio->accept_frame_received = 1;
if(!dtio_add_output_event_write(dtio))
goto close_connection;
return 1;
} else {
/* unknow content type */
verbose(VERB_ALGO, "dnstap: ACCEPT frame "
"contains unknown content type, "
"closing connection");
goto close_connection;
}
}
/* unknown option, try next */
read_frame_done += 8+len;
}
close_connection:
dtio_del_output_event(dtio);
dtio_reconnect_slow(dtio, DTIO_RECONNECT_TIMEOUT_SLOW);
dtio_close_output(dtio);
return 0;
}
/** add the output file descriptor event for listening, read only */ /** add the output file descriptor event for listening, read only */
static int dtio_add_output_event_read(struct dt_io_thread* dtio) static int dtio_add_output_event_read(struct dt_io_thread* dtio)
{ {
@ -1002,6 +1292,24 @@ static int dtio_disable_brief_read(struct dt_io_thread* dtio)
} }
#endif /* HAVE_SSL */ #endif /* HAVE_SSL */
#ifdef HAVE_SSL
/** enable the brief write condition */
static int dtio_enable_brief_write(struct dt_io_thread* dtio)
{
dtio->ssl_brief_write = 1;
return dtio_add_output_event_write(dtio);
}
#endif /* HAVE_SSL */
#ifdef HAVE_SSL
/** disable the brief write condition */
static int dtio_disable_brief_write(struct dt_io_thread* dtio)
{
dtio->ssl_brief_write = 0;
return dtio_add_output_event_read(dtio);
}
#endif /* HAVE_SSL */
#ifdef HAVE_SSL #ifdef HAVE_SSL
/** check peer verification after ssl handshake connection, false if closed*/ /** check peer verification after ssl handshake connection, false if closed*/
static int dtio_ssl_check_peer(struct dt_io_thread* dtio) static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
@ -1175,8 +1483,13 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
} }
#endif #endif
if((bits&UB_EV_READ)) { if((bits&UB_EV_READ || dtio->ssl_brief_write)) {
if(!dtio_check_close(dtio)) if(dtio->ssl_brief_write)
(void)dtio_disable_brief_write(dtio);
if(dtio->ready_frame_sent && !dtio->accept_frame_received) {
if(dtio_read_accept_frame(dtio) <= 0)
return;
} else if(!dtio_check_close(dtio))
return; return;
} }
@ -1208,6 +1521,15 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
/* done with the current message */ /* done with the current message */
dtio_cur_msg_free(dtio); dtio_cur_msg_free(dtio);
/* If this is a bidirectional stream the first message will be
* the READY control frame. We can only continue writing after
* receiving an ACCEPT control frame. */
if(dtio->is_bidirectional && !dtio->ready_frame_sent) {
dtio->ready_frame_sent = 1;
(void)dtio_add_output_event_read(dtio);
break;
}
} }
} }
@ -1224,15 +1546,13 @@ void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg)
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
return; /* ignore this */ return; /* ignore this */
log_err("dnstap io: failed to read: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS) if(WSAGetLastError() == WSAEINPROGRESS)
return; return;
if(WSAGetLastError() == WSAEWOULDBLOCK) if(WSAGetLastError() == WSAEWOULDBLOCK)
return; return;
log_err("dnstap io: failed to read: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("dnstap io: failed to read: %s", sock_strerror(errno));
/* and then fall through to quit the thread */ /* and then fall through to quit the thread */
} else if(r == 0) { } else if(r == 0) {
verbose(VERB_ALGO, "dnstap io: cmd channel closed"); verbose(VERB_ALGO, "dnstap io: cmd channel closed");
@ -1240,6 +1560,13 @@ void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg)
verbose(VERB_ALGO, "dnstap io: cmd channel cmd quit"); verbose(VERB_ALGO, "dnstap io: cmd channel cmd quit");
} else if(r == 1 && cmd == DTIO_COMMAND_WAKEUP) { } else if(r == 1 && cmd == DTIO_COMMAND_WAKEUP) {
verbose(VERB_ALGO, "dnstap io: cmd channel cmd wakeup"); verbose(VERB_ALGO, "dnstap io: cmd channel cmd wakeup");
if(dtio->is_bidirectional && !dtio->accept_frame_received) {
verbose(VERB_ALGO, "dnstap io: cmd wakeup ignored, "
"waiting for ACCEPT control frame");
return;
}
/* reregister event */ /* reregister event */
if(!dtio_add_output_event_write(dtio)) if(!dtio_add_output_event_write(dtio))
return; return;
@ -1561,6 +1888,25 @@ static int dtio_control_start_send(struct dt_io_thread* dtio)
return 1; return 1;
} }
/** setup a ready control message */
static int dtio_control_ready_send(struct dt_io_thread* dtio)
{
log_assert(dtio->cur_msg == NULL && dtio->cur_msg_len == 0);
dtio->cur_msg = fstrm_create_control_frame_ready(DNSTAP_CONTENT_TYPE,
&dtio->cur_msg_len);
if(!dtio->cur_msg) {
return 0;
}
/* setup to send the control message */
/* set that the buffer needs to be sent, but the length
* of that buffer is already written, that way the buffer can
* start with 0 length and then the length of the control frame
* in it */
dtio->cur_msg_done = 0;
dtio->cur_msg_len_done = 4;
return 1;
}
/** open the output file descriptor for af_local */ /** open the output file descriptor for af_local */
static int dtio_open_output_local(struct dt_io_thread* dtio) static int dtio_open_output_local(struct dt_io_thread* dtio)
{ {
@ -1568,13 +1914,8 @@ static int dtio_open_output_local(struct dt_io_thread* dtio)
struct sockaddr_un s; struct sockaddr_un s;
dtio->fd = socket(AF_LOCAL, SOCK_STREAM, 0); dtio->fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if(dtio->fd == -1) { if(dtio->fd == -1) {
#ifndef USE_WINSOCK
log_err("dnstap io: failed to create socket: %s", log_err("dnstap io: failed to create socket: %s",
strerror(errno)); sock_strerror(errno));
#else
log_err("dnstap io: failed to create socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
return 0; return 0;
} }
memset(&s, 0, sizeof(s)); memset(&s, 0, sizeof(s));
@ -1589,13 +1930,13 @@ static int dtio_open_output_local(struct dt_io_thread* dtio)
if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s)) if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s))
== -1) { == -1) {
char* to = dtio->socket_path; char* to = dtio->socket_path;
#ifndef USE_WINSOCK if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4) {
dtio_close_fd(dtio);
return 0; /* no log retries on low verbosity */
}
log_err("dnstap io: failed to connect to \"%s\": %s", log_err("dnstap io: failed to connect to \"%s\": %s",
to, strerror(errno)); to, sock_strerror(errno));
#else
log_err("dnstap io: failed to connect to \"%s\": %s",
to, wsa_strerror(WSAGetLastError()));
#endif
dtio_close_fd(dtio); dtio_close_fd(dtio);
return 0; return 0;
} }
@ -1620,18 +1961,18 @@ static int dtio_open_output_tcp(struct dt_io_thread* dtio)
} }
dtio->fd = socket(addr.ss_family, SOCK_STREAM, 0); dtio->fd = socket(addr.ss_family, SOCK_STREAM, 0);
if(dtio->fd == -1) { if(dtio->fd == -1) {
#ifndef USE_WINSOCK log_err("can't create socket: %s", sock_strerror(errno));
log_err("can't create socket: %s", strerror(errno));
#else
log_err("can't create socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
return 0; return 0;
} }
fd_set_nonblock(dtio->fd); fd_set_nonblock(dtio->fd);
if(connect(dtio->fd, (struct sockaddr*)&addr, addrlen) == -1) { if(connect(dtio->fd, (struct sockaddr*)&addr, addrlen) == -1) {
if(errno == EINPROGRESS) if(errno == EINPROGRESS)
return 1; /* wait until connect done*/ return 1; /* wait until connect done*/
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4) {
dtio_close_fd(dtio);
return 0; /* no log retries on low verbosity */
}
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(tcp_connect_errno_needs_log( if(tcp_connect_errno_needs_log(
(struct sockaddr *)&addr, addrlen)) { (struct sockaddr *)&addr, addrlen)) {
@ -1693,7 +2034,8 @@ static void dtio_open_output(struct dt_io_thread* dtio)
} }
dtio->check_nb_connect = 1; dtio->check_nb_connect = 1;
/* the EV_READ is to catch channel close, write to write packets */ /* the EV_READ is to read ACCEPT control messages, and catch channel
* close. EV_WRITE is to write packets */
ev = ub_event_new(dtio->event_base, dtio->fd, ev = ub_event_new(dtio->event_base, dtio->fd,
UB_EV_READ | UB_EV_WRITE | UB_EV_PERSIST, &dtio_output_cb, UB_EV_READ | UB_EV_WRITE | UB_EV_PERSIST, &dtio_output_cb,
dtio); dtio);
@ -1712,7 +2054,8 @@ static void dtio_open_output(struct dt_io_thread* dtio)
dtio->event = ev; dtio->event = ev;
/* setup protocol control message to start */ /* setup protocol control message to start */
if(!dtio_control_start_send(dtio)) { if((!dtio->is_bidirectional && !dtio_control_start_send(dtio)) ||
(dtio->is_bidirectional && !dtio_control_ready_send(dtio)) ) {
log_err("dnstap io: out of memory"); log_err("dnstap io: out of memory");
ub_event_free(dtio->event); ub_event_free(dtio->event);
dtio->event = NULL; dtio->event = NULL;
@ -1811,15 +2154,14 @@ void dt_io_thread_stop(struct dt_io_thread* dtio)
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
continue; continue;
log_err("dnstap io stop: write: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS) if(WSAGetLastError() == WSAEINPROGRESS)
continue; continue;
if(WSAGetLastError() == WSAEWOULDBLOCK) if(WSAGetLastError() == WSAEWOULDBLOCK)
continue; continue;
log_err("dnstap io stop: write: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("dnstap io stop: write: %s",
sock_strerror(errno));
break; break;
} }
break; break;

View file

@ -49,6 +49,7 @@ struct dt_msg_entry;
struct dt_io_list_item; struct dt_io_list_item;
struct dt_io_thread; struct dt_io_thread;
struct config_file; struct config_file;
struct comm_base;
/** /**
* A message buffer with dnstap messages queued up. It is per-worker. * A message buffer with dnstap messages queued up. It is per-worker.
@ -68,11 +69,15 @@ struct dt_msg_queue {
/** current size of the buffer, in bytes. data bytes of messages. /** current size of the buffer, in bytes. data bytes of messages.
* If a new message make it more than maxsize, the buffer is full */ * If a new message make it more than maxsize, the buffer is full */
size_t cursize; size_t cursize;
/** number of messages in the queue */
int msgcount;
/** list of messages. The messages are added to the back and taken /** list of messages. The messages are added to the back and taken
* out from the front. */ * out from the front. */
struct dt_msg_entry* first, *last; struct dt_msg_entry* first, *last;
/** reference to the io thread to wakeup */ /** reference to the io thread to wakeup */
struct dt_io_thread* dtio; struct dt_io_thread* dtio;
/** the wakeup timer for dtio, on worker event base */
struct comm_timer* wakeup_timer;
}; };
/** /**
@ -88,6 +93,27 @@ struct dt_msg_entry {
size_t len; size_t len;
}; };
/**
* Containing buffer and counter for reading DNSTAP frames.
*/
struct dt_frame_read_buf {
/** Buffer containing frame, except length counter(s). */
void* buf;
/** Number of bytes written to buffer. */
size_t buf_count;
/** Capacity of the buffer. */
size_t buf_cap;
/** Frame length field. Will contain the 2nd length field for control
* frames. */
uint32_t frame_len;
/** Number of bytes that have been written to the frame_length field. */
size_t frame_len_done;
/** Set to 1 if this is a control frame, 0 otherwise (ie data frame). */
int control_frame;
};
/** /**
* IO thread that reads from the queues and writes them. * IO thread that reads from the queues and writes them.
*/ */
@ -130,6 +156,9 @@ struct dt_io_thread {
* This happens during negotiation, we then do not want to write, * This happens during negotiation, we then do not want to write,
* but wait for a read event. */ * but wait for a read event. */
int ssl_brief_read; int ssl_brief_read;
/** true if SSL_read is waiting for a write event. Set back to 0 after
* single write event is handled. */
int ssl_brief_write;
/** the buffer that currently getting written, or NULL if no /** the buffer that currently getting written, or NULL if no
* (partial) message written now */ * (partial) message written now */
@ -142,6 +171,10 @@ struct dt_io_thread {
* for the current message length that precedes the frame */ * for the current message length that precedes the frame */
size_t cur_msg_len_done; size_t cur_msg_len_done;
/** lock on wakeup_timer_enabled */
lock_basic_type wakeup_timer_lock;
/** if wakeup timer is enabled in some thread */
int wakeup_timer_enabled;
/** command pipe that stops the pipe if closed. Used to quit /** command pipe that stops the pipe if closed. Used to quit
* the program. [0] is read, [1] is written to. */ * the program. [0] is read, [1] is written to. */
int commandpipe[2]; int commandpipe[2];
@ -171,6 +204,16 @@ struct dt_io_thread {
* and client certificates can be used for authentication. */ * and client certificates can be used for authentication. */
int upstream_is_tls; int upstream_is_tls;
/** Perform bidirectional Frame Streams handshake before sending
* messages. */
int is_bidirectional;
/** Set if the READY control frame has been sent. */
int ready_frame_sent;
/** Set if valid ACCEPT frame is received. */
int accept_frame_received;
/** (partially) read frame */
struct dt_frame_read_buf read_frame;
/** the file path for unix socket (or NULL) */ /** the file path for unix socket (or NULL) */
char* socket_path; char* socket_path;
/** the ip address and port number (or NULL) */ /** the ip address and port number (or NULL) */
@ -199,9 +242,10 @@ struct dt_io_list_item {
/** /**
* Create new (empty) worker message queue. Limit set to default on max. * Create new (empty) worker message queue. Limit set to default on max.
* @param base: event base for wakeup timer.
* @return NULL on malloc failure or a new queue (not locked). * @return NULL on malloc failure or a new queue (not locked).
*/ */
struct dt_msg_queue* dt_msg_queue_create(void); struct dt_msg_queue* dt_msg_queue_create(struct comm_base* base);
/** /**
* Delete a worker message queue. It has to be unlinked from access, * Delete a worker message queue. It has to be unlinked from access,
@ -224,6 +268,9 @@ void dt_msg_queue_delete(struct dt_msg_queue* mq);
*/ */
void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len); void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len);
/** timer callback to wakeup dtio thread to process messages */
void mq_wakeup_cb(void* arg);
/** /**
* Create IO thread. * Create IO thread.
* @return new io thread object. not yet started. or NULL malloc failure. * @return new io thread object. not yet started. or NULL malloc failure.

View file

@ -278,57 +278,31 @@ static int make_tcp_accept(char* ip)
} }
if((s = socket(addr.ss_family, SOCK_STREAM, 0)) == -1) { if((s = socket(addr.ss_family, SOCK_STREAM, 0)) == -1) {
#ifndef USE_WINSOCK log_err("can't create socket: %s", sock_strerror(errno));
log_err("can't create socket: %s", strerror(errno));
#else
log_err("can't create socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
return -1; return -1;
} }
#ifdef SO_REUSEADDR #ifdef SO_REUSEADDR
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0) { (socklen_t)sizeof(on)) < 0) {
#ifndef USE_WINSOCK
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
strerror(errno)); sock_strerror(errno));
close(s); sock_close(s);
#else
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
wsa_strerror(WSAGetLastError()));
closesocket(s);
#endif
return -1; return -1;
} }
#endif /* SO_REUSEADDR */ #endif /* SO_REUSEADDR */
if(bind(s, (struct sockaddr*)&addr, len) != 0) { if(bind(s, (struct sockaddr*)&addr, len) != 0) {
#ifndef USE_WINSOCK log_err_addr("can't bind socket", sock_strerror(errno),
log_err_addr("can't bind socket", strerror(errno),
&addr, len); &addr, len);
close(s); sock_close(s);
#else
log_err_addr("can't bind socket",
wsa_strerror(WSAGetLastError()), &addr, len);
closesocket(s);
#endif
return -1; return -1;
} }
if(!fd_set_nonblock(s)) { if(!fd_set_nonblock(s)) {
#ifndef USE_WINSOCK sock_close(s);
close(s);
#else
closesocket(s);
#endif
return -1; return -1;
} }
if(listen(s, LISTEN_BACKLOG) == -1) { if(listen(s, LISTEN_BACKLOG) == -1) {
#ifndef USE_WINSOCK log_err("can't listen: %s", sock_strerror(errno));
log_err("can't listen: %s", strerror(errno)); sock_close(s);
close(s);
#else
log_err("can't listen: %s", wsa_strerror(WSAGetLastError()));
closesocket(s);
#endif
return -1; return -1;
} }
return s; return s;
@ -654,7 +628,6 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
return -1; return -1;
log_err("could not recv: %s", strerror(errno));
#else /* USE_WINSOCK */ #else /* USE_WINSOCK */
if(WSAGetLastError() == WSAEINPROGRESS) if(WSAGetLastError() == WSAEINPROGRESS)
return -1; return -1;
@ -662,9 +635,8 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
ub_winsock_tcp_wouldblock(data->ev, UB_EV_READ); ub_winsock_tcp_wouldblock(data->ev, UB_EV_READ);
return -1; return -1;
} }
log_err("could not recv: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("could not recv: %s", sock_strerror(errno));
if(verbosity) log_info("dnstap client stream closed from %s", if(verbosity) log_info("dnstap client stream closed from %s",
(data->id?data->id:"")); (data->id?data->id:""));
return 0; return 0;
@ -755,7 +727,7 @@ static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len)
} }
/** delete the tap structure */ /** delete the tap structure */
void tap_data_free(struct tap_data* data) static void tap_data_free(struct tap_data* data)
{ {
ub_event_del(data->ev); ub_event_del(data->ev);
ub_event_free(data->ev); ub_event_free(data->ev);
@ -770,10 +742,11 @@ void tap_data_free(struct tap_data* data)
/** reply with ACCEPT control frame to bidirectional client, /** reply with ACCEPT control frame to bidirectional client,
* returns 0 on error */ * returns 0 on error */
static int reply_with_accept(int fd) static int reply_with_accept(struct tap_data* data)
{ {
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* len includes the escape and framelength */ /* len includes the escape and framelength */
int r;
size_t len = 0; size_t len = 0;
void* acceptframe = fstrm_create_control_frame_accept( void* acceptframe = fstrm_create_control_frame_accept(
DNSTAP_CONTENT_TYPE, &len); DNSTAP_CONTENT_TYPE, &len);
@ -782,26 +755,34 @@ static int reply_with_accept(int fd)
return 0; return 0;
} }
fd_set_block(fd); fd_set_block(data->fd);
if(send(fd, acceptframe, len, 0) == -1) { if(data->ssl) {
#ifndef USE_WINSOCK if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
log_err("send failed: %s", strerror(errno)); if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
#else log_err("SSL_write, peer closed connection");
log_err("send failed: %s", wsa_strerror(WSAGetLastError())); else
#endif log_err("could not SSL_write");
fd_set_nonblock(fd); fd_set_nonblock(data->fd);
free(acceptframe); free(acceptframe);
return 0; return 0;
}
} else {
if(send(data->fd, acceptframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
fd_set_nonblock(data->fd);
free(acceptframe);
return 0;
}
} }
if(verbosity) log_info("sent control frame(accept) content-type:(%s)", if(verbosity) log_info("sent control frame(accept) content-type:(%s)",
DNSTAP_CONTENT_TYPE); DNSTAP_CONTENT_TYPE);
fd_set_nonblock(fd); fd_set_nonblock(data->fd);
free(acceptframe); free(acceptframe);
return 1; return 1;
#else #else
log_err("no dnstap compiled, no reply"); log_err("no dnstap compiled, no reply");
(void)fd; (void)data;
return 0; return 0;
#endif #endif
} }
@ -820,11 +801,7 @@ static int reply_with_finish(int fd)
fd_set_block(fd); fd_set_block(fd);
if(send(fd, finishframe, len, 0) == -1) { if(send(fd, finishframe, len, 0) == -1) {
#ifndef USE_WINSOCK log_err("send failed: %s", sock_strerror(errno));
log_err("send failed: %s", strerror(errno));
#else
log_err("send failed: %s", wsa_strerror(WSAGetLastError()));
#endif
fd_set_nonblock(fd); fd_set_nonblock(fd);
free(finishframe); free(finishframe);
return 0; return 0;
@ -1033,7 +1010,7 @@ void dtio_tap_callback(int fd, short ATTR_UNUSED(bits), void* arg)
FSTRM_CONTROL_FRAME_READY) { FSTRM_CONTROL_FRAME_READY) {
data->is_bidirectional = 1; data->is_bidirectional = 1;
if(verbosity) log_info("bidirectional stream"); if(verbosity) log_info("bidirectional stream");
if(!reply_with_accept(fd)) { if(!reply_with_accept(data)) {
tap_data_free(data); tap_data_free(data);
} }
} else if(data->len >= 4 && sldns_read_uint32(data->frame) == } else if(data->len >= 4 && sldns_read_uint32(data->frame) ==
@ -1080,7 +1057,6 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
#endif /* EPROTO */ #endif /* EPROTO */
) )
return; return;
log_err_addr("accept failed", strerror(errno), &addr, addrlen);
#else /* USE_WINSOCK */ #else /* USE_WINSOCK */
if(WSAGetLastError() == WSAEINPROGRESS || if(WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAECONNRESET) WSAGetLastError() == WSAECONNRESET)
@ -1089,9 +1065,9 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ); ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ);
return; return;
} }
log_err_addr("accept failed", wsa_strerror(WSAGetLastError()),
&addr, addrlen);
#endif #endif
log_err_addr("accept failed", sock_strerror(errno), &addr,
addrlen);
return; return;
} }
fd_set_nonblock(s); fd_set_nonblock(s);
@ -1190,9 +1166,12 @@ int sig_quit = 0;
/** signal handler for user quit */ /** signal handler for user quit */
static RETSIGTYPE main_sigh(int sig) static RETSIGTYPE main_sigh(int sig)
{ {
verbose(VERB_ALGO, "exit on signal %d\n", sig); if(!sig_quit)
if(sig_base) fprintf(stderr, "exit on signal %d\n", sig);
if(sig_base) {
ub_event_base_loopexit(sig_base); ub_event_base_loopexit(sig_base);
sig_base = NULL;
}
sig_quit = 1; sig_quit = 1;
} }
@ -1233,9 +1212,9 @@ setup_and_run(struct config_strlist_head* local_list,
if(verbosity) log_info("start of service"); if(verbosity) log_info("start of service");
ub_event_base_dispatch(base); ub_event_base_dispatch(base);
sig_base = NULL;
if(verbosity) log_info("end of service"); if(verbosity) log_info("end of service");
sig_base = NULL;
tap_socket_list_delete(maindata->acceptlist); tap_socket_list_delete(maindata->acceptlist);
ub_event_base_free(base); ub_event_base_free(base);
free(maindata); free(maindata);
@ -1376,6 +1355,10 @@ int main(int argc, char** argv)
struct tube; struct tube;
struct query_info; struct query_info;
#include "util/data/packed_rrset.h" #include "util/data/packed_rrset.h"
#include "daemon/worker.h"
#include "daemon/remote.h"
#include "util/fptr_wlist.h"
#include "libunbound/context.h"
void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len), uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),

View file

@ -1,3 +1,539 @@
2 February 2021: Wouter
- branch-1.13.1 is created, with release-1.13.1rc1 tag.
- Fix dynlibmod link on rhel8 for -ldl inclusion.
- Fix windows dependency on libssp.dll because of default stack
protector in mingw.
- Fix indentation of root anchor for use by windows install script.
1 February 2021: George
- Attempt to fix NULL keys in the reuse_tcp tree; relates to #411.
29 January 2021: Wouter
- Fix for doxygen 1.8.20 compatibility.
28 January 2021: Wouter
- Annotate that we ignore the return value of if_indextoname.
- Fix to use correct type for label count in rpz routine.
- Fix empty clause warning in config_file nsid parse.
- Fix to use correct type for label count in ipdnametoaddr rpz routine.
- Fix empty clause warning in edns pass for padding.
- Fix fwd ancil test post script when not supported.
26 January 2021: George
- Merge PR #408 from fobser: Prevent a few more yacc clashes.
- Merge PR #275 from Roland van Rijswijk-Deij: Add feature to return the
original instead of a decrementing TTL ('serve-original-ttl')
- Merge PR #355 from noloader: Make ICANN Update CA and DS Trust Anchor
static data.
- Ignore cache blacklisting when trying to reply with expired data from
cache (#394).
26 January 2021: Wouter
- Fix compile of unbound-dnstap-socket without dnstap installed.
22 January 2021: Willem
- Padding of queries and responses with DNS over TLS as specified in
RFC7830 and RFC8467.
22 January 2021: George
- Fix TTL of SOA record for negative answers (localzone and
authzone data) to be the minimum of the SOA TTL and the SOA.MINIMUM.
19 January 2021: Willem
- Support for RFC5001: DNS Name Server Identifier (NSID) Option
with the nsid: option in unbound.conf
18 January 2021: Wouter
- Fix #404: DNS query with small edns bufsize fail.
- Fix declaration before statement and signed comparison warning in
dns64.
15 January 2021: Wouter
- Merge #402 from fobser: Implement IPv4-Embedded addresses according
to RFC6052.
14 January 2021: Wouter
- Fix for #93: dynlibmodule import library is named libunbound.dll.a.
13 January 2021: Wouter
- Merge #399 from xiangbao227: The lock of lruhash table should
unlocked after markdel entry.
- Fix for #93: dynlibmodule link fix for Windows.
12 January 2021: Wouter
- Fix #397: [Feature request] add new type always_null to local-zone
similar to always_nxdomain.
- Fix so local zone types always_nodata and always_deny can be used
from the config file.
8 January 2021: Wouter
- Merge PR #391 from fhriley: Add start_time to reply callbacks so
modules can compute the response time.
- For #391: use struct timeval* start_time for callback information.
- For #391: fix indentation.
- For #391: more double casts in python start time calculation.
- Add comment documentation.
- Fix clang analysis warning.
6 January 2021: Wouter
- Fix #379: zone loading over HTTP appears to have buffer issues.
- Merge PR #395 from mptre: add missing null check.
- Fix #387: client-subnet-always-forward seems to effectively bypass
any caching?
5 January 2021: Wouter
- Fix #385: autoconf 2.70 impacts unbound build
- Merge PR #375 by fhriley: Add rpz_enable and rpz_disable commands
to unbound-control.
4 January 2021: Wouter
- For #376: Fix that comm point event is not double removed or double
added to event map.
- iana portlist updated.
16 December 2020: George
- Fix error cases when udp-connect is set and send() returns an error
(modified patch from Xin Li @delphij).
11 December 2020: Wouter
- Fix #371: unbound-control timeout when Unbound is not running.
- Fix to squelch permission denied and other errors from remote host,
they are logged at higher verbosity but not on low verbosity.
- Merge PR #335 from fobser: Sprinkle in some static to prevent
missing prototype warnings.
- Merge PR #373 from fobser: Warning: arithmetic on a pointer to void
is a GNU extension.
- Fix missing prototypes in the code.
3 December 2020: Wouter
- make depend.
- iana portlist updated.
2 December 2020: Wouter
- Fix #360: for the additionally reported TCP Fast Open makes TCP
connections fail, in that case we print a hint that this is
happening with the error in the logs.
- Fix #356: deadlock when listening tcp.
- Fix unbound-dnstap-socket to not use log routine from interrupt
handler and not print so frequently when invoked in sequence.
- Fix on windows to ignore connection failure on UDP, unless verbose.
- Fix for #283: fix stream reuse and tcp fast open.
- Fix update, with write event check with streamreuse and fastopen.
1 December 2020: Wouter
- Fix #358: Squelch udp connect 'no route to host' errors on low
verbosity.
30 November 2020: Wouter
- Fix assertion failure on double callback when iterator loses
interest in query at head of line that then has the tcp stream
not kept for reuse.
- tag for the 1.13.0rc4 release. This also became the 1.13.0
release version on 3 dec 2020 with the streamreuse and fastopen
fix from 2 dec 2020. The code repo continues for 1.13.1 in
development.
27 November 2020: Wouter
- Fix compile warning for type cast in http2_submit_dns_response.
- Fix when use free buffer to initialize rbtree for stream reuse.
- Fix compile warnings for windows.
- Fix compile warnings in rpz initialization.
- Fix contrib/metrics.awk for FreeBSD awk compatibility.
- tag for the 1.13.0rc3 release.
26 November 2020: Wouter
- Fix to omit UDP receive errors from log, if verbosity low.
These happen because of udp-connect.
- For #352: contrib/metrics.awk for Prometheus style metrics output.
- Fix that after failed read, the readagain cannot activate.
- Clear readagain upon decommission of pending tcp structure.
25 November 2020: Wouter
- with udp-connect ignore connection refused with UDP timeouts.
- Fix udp-connect on FreeBSD, do send calls on connected UDP socket.
- Better fix for reuse tree comparison for is-tls sockets. Where
the tree key identity is preserved after cleanup of the TLS state.
- Remove debug commands from reuse tests.
- Fix memory leak for edns client tag opcode config element.
- Attempt fix for libevent state in tcp reuse cases after a packet
is written.
- Fix readagain and writeagain callback functions for comm point
cleanup.
- tag for the 1.13.0rc2 release.
24 November 2020: Wouter
- Merge PR #283 : Stream reuse. This implements upstream stream
reuse for performing several queries over the same TCP or TLS
channel.
- set version of main branch to 1.13.0 for upcoming release.
- iana portlist updated.
- Fix one port unit test for udp-connect.
- tag for the 1.13.0rc1 release.
- Fix crash when TLS connection is closed prematurely, when
reuse tree comparison is not properly identical to insertion.
- Fix padding of struct regional for 32bit systems.
23 November 2020: George
- Merge PR #313 from Ralph Dolmans: Replace edns-client-tag with
edns-client-string option.
23 November 2020: Wouter
- Merge #351 from dvzrv: Add AF_NETLINK to set of allowed socket
address families.
- Fix #350: with the AF_NETLINK permission, to fix 1.12.0 error:
failed to list interfaces: getifaddrs: Address family not
supported by protocol.
- Fix #347: IP_DONTFRAG broken on Apple xcode 12.2.
- Option to toggle udp-connect, default is enabled.
- Fix for #303 CVE-2020-28935 : Fix that symlink does not interfere
with chown of pidfile.
- Further fix for it and retvalue 0 fix for it.
12 November 2020: Wouter
- Fix to connect() to UDP destinations, default turned on,
this lowers vulnerability to ICMP side channels.
- Retry for interfaces with unused ports if possible.
10 November 2020: Wouter
- Fix #341: fixing a possible memory leak.
- Fix memory leak after fix for possible memory leak failure.
- Fix #343: Fail to build --with-libnghttp2 with error: 'SSIZE_MAX'
undeclared.
27 October 2020: Wouter
- In man page note that tls-cert-bundle is read before permission
drop and chroot.
22 October 2020: Wouter
- Fix #333: Unbound Segmentation Fault w/ log_info Functions From
Python Mod.
- Fix that minimal-responses does not remove addresses from a priming
query response.
21 October 2020: George
- Fix #327: net/if.h check fails on some darwin versions; contribution by
Joshua Root.
- Fix #320: potential memory corruption due to size miscomputation upton
custom region alloc init.
21 October 2020: Wouter
- Merge PR #228 : infra-keep-probing option to probe hosts that are
down. Add infra-keep-probing: yes option. Hosts that are down are
probed more frequently.
With the option turned on, it probes about every 120 seconds,
eventually after exponential backoff, and that keeps that way. If
traffic keeps up for the domain. It probes with one at a time, eg.
one query is allowed to probe, other queries within that 120 second
interval are turned away.
19 October 2020: George
- Merge PR #324 from James Renken: Add modern X.509v3 extensions to
unbound-control TLS certificates.
- Fix for PR #324 to attach the x509v3 extensions to the client
certificate.
19 October 2020: Ralph
- local-zone regional allocations outside of chunk
19 October 2020: Wouter
- Fix that http settings have colon in set_option, for
http-endpoint, http-max-streams, http-query-buffer-size,
http-response-buffer-size, and http-nodelay.
- Fix memory leak of https port string when reading config.
- Fix #330: [Feature request] Add unencrypted DNS over HTTPS support.
This adds the option http-notls-downstream: yesno to change that,
and the dohclient test code has the -n option.
- Fix python documentation warning on functions.rst inplace_cb_reply.
- Fix dnstap test to wait for log timer to see if queries are logged.
- Log ip address when http session recv fails, eg. due to tls fail.
- Fix to set the tcp handler event toggle flag back to default when
the handler structure is reused.
- Clean the fix for out of order TCP processing limits on number
of queries. It was tested to work.
16 October 2020: Wouter
- Fix that the out of order TCP processing does not limit the
number of outstanding queries over a connection.
15 October 2020: George
- Fix that if there are reply callbacks for the given rcode, those
are called per reply and a new message created if that was modified
by the call.
- Pass the comm_reply information to the inplace_cb_reply* functions
during the mesh state and update the documentation on that.
15 October 2020: Wouter
- Merge PR #326 from netblue30: DoH: implement content-length
header field
- DoH content length, simplify code, remove declaration after
statement and fix cast warning.
14 October 2020: Wouter
- Fix for python reply callback to see mesh state reply_list member,
it only removes it briefly for the commpoint call so that it does
not drop it and attempt to modify the reply list during reply.
- Fix that if there are on reply callbacks, those are called per
reply and a new message created if that was modified by the call.
- Free up auth zone parse region after use for lookup of host
13 October 2020: Wouter
- Fix #323: unbound testsuite fails on mock build in systemd-nspawn
if systemd support is build.
9 October 2020: Wouter
- Fix dnstap socket and the chroot not applied properly to the dnstap
socket path.
- Fix warning in libnss compile, nss_buf2dsa is not used without DSA.
8 October 2020: Wouter
- Tag for 1.12.0 release.
- Current repo is version 1.12.1 in development.
- Fix #319: potential memory leak on config failure, in rpz config.
1 October 2020: Wouter
- Current repo is version 1.12.0 for release. Tag for 1.12.0rc1.
30 September 2020: Wouter
- Fix doh tests when not compiled in.
- Add dohclient test executable to gitignore.
- Fix stream_ssl, ssl_req_order and ssl_req_timeout tests for
alloc check debug output.
- Easier kill of unbound-dnstap-socket tool in test.
- Fix memory leak of edns tags at libunbound context delete.
- Fix double loopexit for unbound-dnstap-socket after sigterm.
29 September 2020: Ralph
- DNS Flag Day 2020: change edns-buffer-size default to 1232.
28 September 2020: Wouter
- Fix unit test for dnstap changes, so that it waits for the timer.
23 September 2020: Wouter
- Fix #305: dnstap logging significantly affects unbound performance
(regression in 1.11).
- Fix #305: only wake up thread when threshold reached.
- Fix to ifdef fptr wlist item for dnstap.
23 September 2020: Ralph
- Fix edns-client-tags get_option typo
- Add edns-client-tag-opcode option
- Use inclusive language in configuration
21 September 2020: Ralph
- Fix #304: dnstap logging not recovering after dnstap process restarts
21 September 2020: Wouter
- Merge PR #311 by luismerino: Dynlibmod leak.
- Error message is logged for dynlibmod malloc failures.
- iana portlist updated.
18 September 2020: Wouter
- Fix that prefer-ip4 and prefer-ip6 can be get and set with
unbound-control, with libunbound and the unbound-checkconf option
output function.
- iana portlist updated.
15 September 2020: George
- Introduce test for statistics.
15 September 2020: Wouter
- Spelling fix.
11 September 2020: Wouter
- Remove x file mode on ipset/ipset.c and h files.
9 September 2020: Wouter
- Fix num.expired statistics output.
31 August 2020: Wouter
- Merge PR #293: Add missing prototype. Also refactor to use the new
shorthand function to clean up the code.
- Refactor to use sock_strerr shorthand function.
- Fix #296: systemd nss-lookup.target is reached before unbound can
successfully answer queries. Changed contrib/unbound.service.in.
27 August 2020: Wouter
- Similar to NSD PR#113, implement that interface names can be used,
eg. something like interface: eth0 is resolved at server start and
uses the IP addresses for that named interface.
- Review fix, doxygen and assign null in case of error free.
26 August 2020: George
- Update documentation in python example code.
24 August 2020: Wouter
- Fix that dnstap reconnects do not spam the log with the repeated
attempts. Attempts on the timer are only logged on high verbosity,
if they produce a connection failure error.
- Fix to apply chroot to dnstap-socket-path, if chroot is enabled.
- Change configure to use EVP_sha256 instead of HMAC_Update for
openssl-3.0.0.
20 August 2020: Ralph
- Fix stats double count issue (#289).
13 August 2020: Ralph
- Create and init edns tags data for libunbound.
10 August 2020: Ralph
- Merge (modified) PR #277, use EVP_MAC_CTX_set_params if available,
by Vítězslav Čížek.
10 August 2020: Wouter
- Fix #287: doc typo: "Additionaly".
- Rerun autoconf
6 August 2020: Wouter
- Merge PR #284 and Fix #246: Remove DLV entirely from Unbound.
The DLV has been decommisioned and in unbound 1.5.4, in 2015, there
was advise to stop using it. The current code base does not contain
DLV code any more. The use of dlv options displays a warning.
5 August 2020: Wouter
- contrib/aaaa-filter-iterator.patch file renewed diff content to
apply cleanly to the current coderepo for the current code version.
5 August 2020: Ralph
- Merge PR #272: Add EDNS client tag functionality.
4 August 2020: George
- Improve error log message when inserting rpz RR.
- Merge PR #280, Make tvOS & watchOS checks verify truthiness as well as
definedness, by Felipe Gasper.
4 August 2020: Wouter
- Fix mini_event.h on OpenBSD cannot find fd_set.
31 July 2020: Wouter
- Fix doxygen comment for no ssl for tls session ticket key callback
routine.
27 July 2020: George
- Merge PR #268, draft-ietf-dnsop-serve-stale-10 has become RFC 8767 on
March 2020, by and0x000.
27 July 2020: Ralph
- Merge PR #269, Fix python module len() implementations, by Torbjörn
Lönnemark
27 July 2020: Wouter
- branch now named 1.11.1. 1.11.0rc1 became the 1.11.0 release.
- Merge PR #270 from cgzones: munin plugin: always exit 0 in autoconf
20 July 2020: Wouter
- Fix streamtcp to print packet data to stdout. This makes the
stdout and stderr not mix together lines, when parsing its output.
- Fix contrib/fastrpz.patch to apply cleanly. It fixes for changes
due to added libdynmod, but it does not compile, it conflicts with
new rpz code.
- branch now named 1.11.0 and 1.11.0rc1 tag.
17 July 2020: Wouter
- Fix libnettle compile for session ticket key callback function
changes.
- Fix lock dependency cycle in rpz zone config setup.
17 July 2020: Ralph
- Merge PR #234 - Ensure proper alignment of cmsg buffers by Jérémie
Courrèges-Anglas.
- Fix PR #234 log_assert sizeof to use union buffer.
16 July 2020: Wouter
- Fix check conf test for referencing installation paths.
- Fix unused variable warning for clang analyzer.
16 July 2020: George
- Introduce 'include-toplevel:' configuration option.
16 July 2020: Ralph
- Add bidirectional frame streams support.
8 July 2020: Wouter
- Fix add missing DSA header, for compilation without deprecated
OpenSSL APIs.
- Fix to use SSL_CTX_set_tlsext_ticket_key_evp_cb in OpenSSL
3.0.0-alpha4.
- Longer keys for the test set, this avoids weak crypto errors.
7 July 2020: Wouter
- Fix #259: Fix unbound-checkconf does not check view existence.
unbound-checkconf checks access-control-view, access-control-tags,
access-control-tag-actions and access-control-tag-datas.
- Fix offset of error printout for access-control-tag-datas.
- Review fixes for checkconf #259 change.
6 July 2020: Wouter
- run_vm cleanup better and removes trailing slash on single argument.
29 June 2020: Wouter
- Move reply list clean for serve expired mesh callback to after
the reply is sent, so that script callbacks have reply_info.
- Also move reply list clean for mesh callbacks to the scrip callback
can see the reply_info.
- Fix for mesh accounting if the reply list already empty to begin
with.
- Fix for mesh accounting when rpz decides to drop a reply with a
tcp stream waiting for it.
- Review fix for number of detached states due to use of variable
after end of loop.
- Fix tcp req info drop due to size call into mesh accounting
removal of mesh state during mesh send reply.
24 June 2020: Wouter
- iana portlist updated.
- doxygen file comments for dynlibmodule.
17 June 2020: Wouter
- Fix default explanation in man page for qname-minimisation-strict.
- Fix display of event loop method with libev.
8 June 2020: Wouter
- Mention tls name possible when tls is enabled for stub-addr in the
man page.
27 May 2020: George
- Merge PR #241 by Robert Edmonds: contrib/libunbound.pc.in: Do not use
"Requires:".
25 May 2020: George
- Update contrib/aaaa-filter-iterator.patch for the recent
generate_sub_request() change and to apply cleanly.
21 May 2020: George
- Fix for integer overflow when printing RDF_TYPE_TIME.
19 May 2020: Wouter
- CVE-2020-12662 Unbound can be tricked into amplifying an incoming
query into a large number of queries directed to a target.
- CVE-2020-12663 Malformed answers from upstream name servers can be
used to make Unbound unresponsive.
- Release 1.10.1 is 1.10.0 with fixes, code repository continues,
including those fixes, towards the next release. Configure has
version 1.10.2 version number in it.
- For PR #93: windows compile warnings removal
- windows compile warnings removal for ip dscp option code.
- For PR #93: unit test for dynlib module.
18 May 2020: Wouter
- For PR #93: dynlibmod can handle reloads and deinit and inits again,
with dlclose and dlopen of the library again. Also for multiple
modules. Fix memory leak by not closing dlopened content. Fix
to allow one dynlibmod instance by unbound-checkconf.
- For PR #93: checkconf allows multiple dynlib in module-config, for
a couple cases.
- For PR #93: checkconf allows python dynlib in module-config, for
a couple cases.
- For PR #93: man page spelling reference fix.
- For PR #93: fix link of other executables for dynlibmod dependency.
15 May 2020: Wouter
- Merge PR #93: Add dynamic library support.
- Fixed conflicts for PR #93 and make configure, yacc, lex.
- For PR #93: Fix warnings for dynlibmodule.
15 May 2020: Ralph
- Cache ECS answers with longest scope of CNAME chain.
22 April 2020: George 22 April 2020: George
- Explicitly use 'rrset-roundrobin: no' for test cases. - Explicitly use 'rrset-roundrobin: no' for test cases.

View file

@ -39,6 +39,7 @@ RFC 4343: case insensitive handling of domain names.
RFC 4509: SHA256 DS hash. RFC 4509: SHA256 DS hash.
RFC 4592: wildcards. RFC 4592: wildcards.
RFC 4697: No DNS Resolution Misbehavior. RFC 4697: No DNS Resolution Misbehavior.
RFC 5001: DNS Name Server Identifier (NSID) Option
RFC 5011: update of trust anchors with timers. RFC 5011: update of trust anchors with timers.
RFC 5155: NSEC3, NSEC3PARAM types RFC 5155: NSEC3, NSEC3PARAM types
RFC 5358: reflectors-are-evil: access control list for recursive RFC 5358: reflectors-are-evil: access control list for recursive

View file

@ -14,7 +14,6 @@ o (option) store primed key data in a overlaid keyhints file (sort of like draft
o windows version, auto update feature, a query to check for the version. o windows version, auto update feature, a query to check for the version.
o command the server with TSIG inband. get-config, clearcache, o command the server with TSIG inband. get-config, clearcache,
get stats, get memstats, get ..., reload, clear one zone from cache get stats, get memstats, get ..., reload, clear one zone from cache
o NSID rfc 5001 support.
o timers rfc 5011 support. o timers rfc 5011 support.
o Treat YXDOMAIN from a DNAME properly, in iterator (not throwaway), validator. o Treat YXDOMAIN from a DNAME properly, in iterator (not throwaway), validator.
o make timeout backoffs randomized (a couple percent random) to spread traffic. o make timeout backoffs randomized (a couple percent random) to spread traffic.

View file

@ -5,9 +5,13 @@
# #
# this is a comment. # this is a comment.
#Use this to include other text into the file. # Use this anywhere in the file to include other text into this file.
#include: "otherfile.conf" #include: "otherfile.conf"
# Use this anywhere in the file to include other text, that explicitly starts a
# clause, into this file. Text after this directive needs to start a clause.
#include-toplevel: "otherfile.conf"
# The server clause sets the main parameters. # The server clause sets the main parameters.
server: server:
# whitespace is not necessary, but looks cleaner. # whitespace is not necessary, but looks cleaner.
@ -125,8 +129,8 @@ server:
# ip-dscp: 0 # ip-dscp: 0
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer # EDNS reassembly buffer to advertise to UDP peers (the actual buffer
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts) # is set with msg-buffer-size).
# edns-buffer-size: 4096 # edns-buffer-size: 1232
# Maximum UDP response size (not applied to TCP response). # Maximum UDP response size (not applied to TCP response).
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it. # Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
@ -157,6 +161,9 @@ server:
# msec to wait before close of port on timeout UDP. 0 disables. # msec to wait before close of port on timeout UDP. 0 disables.
# delay-close: 0 # delay-close: 0
# perform connect for UDP sockets to mitigate ICMP side channel.
# udp-connect: yes
# msec for waiting for an unknown server to reply. Increase if you # msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128. # are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376 # unknown-server-time-limit: 376
@ -188,6 +195,9 @@ server:
# minimum wait time for responses, increase if uplink is long. In msec. # minimum wait time for responses, increase if uplink is long. In msec.
# infra-cache-min-rtt: 50 # infra-cache-min-rtt: 50
# enable to make server probe down hosts more frequently.
# infra-keep-probing: no
# the number of slabs to use for the Infrastructure cache. # the number of slabs to use for the Infrastructure cache.
# the number of slabs must be a power of 2. # the number of slabs must be a power of 2.
# more slabs reduce lock contention, but fragment memory usage. # more slabs reduce lock contention, but fragment memory usage.
@ -367,6 +377,9 @@ server:
# the version to report. Leave "" or default to return package version. # the version to report. Leave "" or default to return package version.
# version: "" # version: ""
# NSID identity (hex string, or "ascii_somestring"). default disabled.
# nsid: "aabbccdd"
# the target fetch policy. # the target fetch policy.
# series of integers describing the policy per dependency depth. # series of integers describing the policy per dependency depth.
# The number of values in the list determines the maximum dependency # The number of values in the list determines the maximum dependency
@ -378,7 +391,7 @@ server:
# target-fetch-policy: "3 2 1 0 0" # target-fetch-policy: "3 2 1 0 0"
# Harden against very small EDNS buffer sizes. # Harden against very small EDNS buffer sizes.
# harden-short-bufsize: no # harden-short-bufsize: yes
# Harden against unseemly large queries. # Harden against unseemly large queries.
# harden-large-queries: no # harden-large-queries: no
@ -427,8 +440,8 @@ server:
# Domains (and domains in them) without support for dns-0x20 and # Domains (and domains in them) without support for dns-0x20 and
# the fallback fails because they keep sending different answers. # the fallback fails because they keep sending different answers.
# caps-whitelist: "licdn.com" # caps-exempt: "licdn.com"
# caps-whitelist: "senderbase.org" # caps-exempt: "senderbase.org"
# Enforce privacy of these addresses. Strips them away from answers. # Enforce privacy of these addresses. Strips them away from answers.
# It may cause DNSSEC validation to additionally mark it as bogus. # It may cause DNSSEC validation to additionally mark it as bogus.
@ -505,11 +518,6 @@ server:
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel) # Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
# root-key-sentinel: yes # root-key-sentinel: yes
# File with DLV trusted keys. Same format as trust-anchor-file.
# There can be only one DLV configured, it is trusted from root down.
# DLV is going to be decommissioned. Please do not use it any more.
# dlv-anchor-file: "dlv.isc.org.key"
# File with trusted keys for validation. Specify more than one file # File with trusted keys for validation. Specify more than one file
# with several entries, one file per entry. # with several entries, one file per entry.
# Zone file format, with DS and DNSKEY entries. # Zone file format, with DS and DNSKEY entries.
@ -585,11 +593,18 @@ server:
# #
# Time in milliseconds before replying to the client with expired data. # Time in milliseconds before replying to the client with expired data.
# This essentially enables the serve-stale behavior as specified in # This essentially enables the serve-stale behavior as specified in
# draft-ietf-dnsop-serve-stale-10 that first tries to resolve before # RFC 8767 that first tries to resolve before
# immediately responding with expired data. 0 disables this behavior. # immediately responding with expired data. 0 disables this behavior.
# A recommended value is 1800. # A recommended value is 1800.
# serve-expired-client-timeout: 0 # serve-expired-client-timeout: 0
# Return the original TTL as received from the upstream name server rather
# than the decrementing TTL as stored in the cache. Enabling this feature
# does not impact cache expiry, it only changes the TTL unbound embeds in
# responses to queries. Note that enabling this feature implicitly disables
# enforcement of the configured minimum and maximum TTL.
# serve-original-ttl: no
# Have the validator log failed validations for your diagnosis. # Have the validator log failed validations for your diagnosis.
# 0: off. 1: A line per failed user query. 2: With reason and bad IP. # 0: off. 1: A line per failed user query. 2: With reason and bad IP.
# val-log-level: 0 # val-log-level: 0
@ -623,7 +638,7 @@ server:
# more slabs reduce lock contention, but fragment memory usage. # more slabs reduce lock contention, but fragment memory usage.
# key-cache-slabs: 4 # key-cache-slabs: 4
# the amount of memory to use for the negative cache (used for DLV). # the amount of memory to use for the negative cache.
# plain value in bytes or you can append k, m or G. default is "1Mb". # plain value in bytes or you can append k, m or G. default is "1Mb".
# neg-cache-size: 1m # neg-cache-size: 1m
@ -699,8 +714,10 @@ server:
# o inform acts like transparent, but logs client IP address # o inform acts like transparent, but logs client IP address
# o inform_deny drops queries and logs client IP address # o inform_deny drops queries and logs client IP address
# o inform_redirect redirects queries and logs client IP address # o inform_redirect redirects queries and logs client IP address
# o always_transparent, always_refuse, always_nxdomain, resolve in # o always_transparent, always_refuse, always_nxdomain, always_nodata,
# that way but ignore local data for that name # always_deny resolve in that way but ignore local data for
# that name
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
# o noview breaks out of that view towards global local-zones. # o noview breaks out of that view towards global local-zones.
# #
# defaults are localhost address, reverse for 127.0.0.1 and ::1 # defaults are localhost address, reverse for 127.0.0.1 and ::1
@ -734,18 +751,26 @@ server:
# add a netblock specific override to a localzone, with zone type # add a netblock specific override to a localzone, with zone type
# local-zone-override: "example.com" 192.0.2.0/24 refuse # local-zone-override: "example.com" 192.0.2.0/24 refuse
# service clients over TLS (on the TCP sockets), with plain DNS inside # service clients over TLS (on the TCP sockets) with plain DNS inside
# the TLS stream. Give the certificate to use and private key. # the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
# Give the certificate to use and private key.
# default is "" (disabled). requires restart to take effect. # default is "" (disabled). requires restart to take effect.
# tls-service-key: "path/to/privatekeyfile.key" # tls-service-key: "path/to/privatekeyfile.key"
# tls-service-pem: "path/to/publiccertfile.pem" # tls-service-pem: "path/to/publiccertfile.pem"
# tls-port: 853 # tls-port: 853
# https-port: 443
# cipher setting for TLSv1.2 # cipher setting for TLSv1.2
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256" # tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
# cipher setting for TLSv1.3 # cipher setting for TLSv1.3
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# Pad responses to padded queries received over TLS
# pad-responses: yes
# Padded responses will be padded to the closest multiple of this size.
# pad-responses-block-size: 468
# Use the SNI extension for TLS connections. Default is yes. # Use the SNI extension for TLS connections. Default is yes.
# Changing the value requires a reload. # Changing the value requires a reload.
# tls-use-sni: yes # tls-use-sni: yes
@ -768,9 +793,34 @@ server:
# Add system certs to the cert bundle, from the Windows Cert Store # Add system certs to the cert bundle, from the Windows Cert Store
# tls-win-cert: no # tls-win-cert: no
# Pad queries over TLS upstreams
# pad-queries: yes
# Padded queries will be padded to the closest multiple of this size.
# pad-queries-block-size: 128
# Also serve tls on these port numbers (eg. 443, ...), by listing # Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-port: portno for each of the port numbers. # tls-additional-port: portno for each of the port numbers.
# HTTP endpoint to provide DNS-over-HTTPS service on.
# http-endpoint: "/dns-query"
# HTTP/2 SETTINGS_MAX_CONCURRENT_STREAMS value to use.
# http-max-streams: 100
# Maximum number of bytes used for all HTTP/2 query buffers.
# http-query-buffer-size: 4m
# Maximum number of bytes used for all HTTP/2 response buffers.
# http-response-buffer-size: 4m
# Set TCP_NODELAY socket option on sockets used for DNS-over-HTTPS
# service.
# http-nodelay: yes
# Disable TLS for DNS-over-HTTP downstream service.
# http-notls-downstream: no
# DNS64 prefix. Must be specified when DNS64 is use. # DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4. # Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
# dns64-prefix: 64:ff9b::0/96 # dns64-prefix: 64:ff9b::0/96
@ -844,9 +894,9 @@ server:
# ipsecmod-ignore-bogus: no # ipsecmod-ignore-bogus: no
# #
# Domains for which ipsecmod will be triggered. If not defined (default) # Domains for which ipsecmod will be triggered. If not defined (default)
# all domains are treated as being whitelisted. # all domains are treated as being allowed.
# ipsecmod-whitelist: "example.com" # ipsecmod-allow: "example.com"
# ipsecmod-whitelist: "nlnetlabs.nl" # ipsecmod-allow: "nlnetlabs.nl"
# Python config section. To enable: # Python config section. To enable:
@ -859,6 +909,17 @@ python:
# Script file to load # Script file to load
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py" # python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
# Dynamic library config section. To enable:
# o use --with-dynlibmodule to configure before compiling.
# o list dynlib in the module-config string (above) to enable.
# It can be placed anywhere, the dynlib module is only a very thin wrapper
# to load modules dynamically.
# o and give a dynlib-file to run. If more than one dynlib entry is listed in
# the module-config then you need one dynlib-file per instance.
dynlib:
# Script file to load
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
# Remote control config section. # Remote control config section.
remote-control: remote-control:
# Enable remote control with unbound-control(8) here. # Enable remote control with unbound-control(8) here.
@ -933,27 +994,27 @@ remote-control:
# upstream (which saves a lookup to the upstream). The first example # upstream (which saves a lookup to the upstream). The first example
# has a copy of the root for local usage. The second serves example.org # has a copy of the root for local usage. The second serves example.org
# authoritatively. zonefile: reads from file (and writes to it if you also # authoritatively. zonefile: reads from file (and writes to it if you also
# download it), master: fetches with AXFR and IXFR, or url to zonefile. # download it), primary: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from masters) sources of # With allow-notify: you can give additional (apart from primaries) sources of
# notifies. # notifies.
# auth-zone: # auth-zone:
# name: "." # name: "."
# master: 199.9.14.201 # b.root-servers.net # primary: 199.9.14.201 # b.root-servers.net
# master: 192.33.4.12 # c.root-servers.net # primary: 192.33.4.12 # c.root-servers.net
# master: 199.7.91.13 # d.root-servers.net # primary: 199.7.91.13 # d.root-servers.net
# master: 192.5.5.241 # f.root-servers.net # primary: 192.5.5.241 # f.root-servers.net
# master: 192.112.36.4 # g.root-servers.net # primary: 192.112.36.4 # g.root-servers.net
# master: 193.0.14.129 # k.root-servers.net # primary: 193.0.14.129 # k.root-servers.net
# master: 192.0.47.132 # xfr.cjr.dns.icann.org # primary: 192.0.47.132 # xfr.cjr.dns.icann.org
# master: 192.0.32.132 # xfr.lax.dns.icann.org # primary: 192.0.32.132 # xfr.lax.dns.icann.org
# master: 2001:500:200::b # b.root-servers.net # primary: 2001:500:200::b # b.root-servers.net
# master: 2001:500:2::c # c.root-servers.net # primary: 2001:500:2::c # c.root-servers.net
# master: 2001:500:2d::d # d.root-servers.net # primary: 2001:500:2d::d # d.root-servers.net
# master: 2001:500:2f::f # f.root-servers.net # primary: 2001:500:2f::f # f.root-servers.net
# master: 2001:500:12::d0d # g.root-servers.net # primary: 2001:500:12::d0d # g.root-servers.net
# master: 2001:7fd::1 # k.root-servers.net # primary: 2001:7fd::1 # k.root-servers.net
# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org # primary: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
# master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org # primary: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org
# fallback-enabled: yes # fallback-enabled: yes
# for-downstream: no # for-downstream: no
# for-upstream: yes # for-upstream: yes
@ -1035,6 +1096,8 @@ remote-control:
# upstream log destination, by socket path, TCP or TLS destination. # upstream log destination, by socket path, TCP or TLS destination.
# dnstap: # dnstap:
# dnstap-enable: no # dnstap-enable: no
# # if set to yes frame streams will be used in bidirectional mode
# dnstap-bidirectional: yes
# dnstap-socket-path: "@DNSTAP_SOCKET_PATH@" # dnstap-socket-path: "@DNSTAP_SOCKET_PATH@"
# # if "" use the unix socket in dnstap-socket-path, otherwise, # # if "" use the unix socket in dnstap-socket-path, otherwise,
# # set it to "IPaddress[@port]" of the destination. # # set it to "IPaddress[@port]" of the destination.
@ -1071,7 +1134,7 @@ remote-control:
# rpz: # rpz:
# name: "rpz.example.com" # name: "rpz.example.com"
# zonefile: "rpz.example.com" # zonefile: "rpz.example.com"
# master: 192.0.2.0 # primary: 192.0.2.0
# allow-notify: 192.0.2.0/32 # allow-notify: 192.0.2.0/32
# url: http://www.example.com/rpz.example.org.zone # url: http://www.example.com/rpz.example.org.zone
# rpz-action-override: cname # rpz-action-override: cname

View file

@ -305,6 +305,12 @@ Transfer the auth zone from master. The auth zone probe sequence is started,
where the masters are probed to see if they have an updated zone (with the SOA where the masters are probed to see if they have an updated zone (with the SOA
serial check). And then the zone is transferred for a newer zone version. serial check). And then the zone is transferred for a newer zone version.
.TP .TP
.B rpz_enable \fIzone\fR
Enable the RPZ zone if it had previously been disabled.
.TP
.B rpz_enable \fIzone\fR
Disable the RPZ zone.
.TP
.B view_list_local_zones \fIview\fR .B view_list_local_zones \fIview\fR
\fIlist_local_zones\fR for given view. \fIlist_local_zones\fR for given view.
.TP .TP
@ -506,6 +512,14 @@ negative cache.
Memory in bytes in used by the TCP and TLS stream wait buffers. These are Memory in bytes in used by the TCP and TLS stream wait buffers. These are
answers waiting to be written back to the clients. answers waiting to be written back to the clients.
.TP .TP
.I mem.http.query_buffer
Memory in bytes used by the HTTP/2 query buffers. Containing (partial) DNS
queries waiting for request stream completion.
.TP
.I mem.http.response_buffer
Memory in bytes used by the HTTP/2 response buffers. Containing DNS responses
waiting to be written back to the clients.
.TP
.I histogram.<sec>.<usec>.to.<sec>.<usec> .I histogram.<sec>.<usec>.to.<sec>.<usec>
Shows a histogram, summed over all threads. Every element counts the Shows a histogram, summed over all threads. Every element counts the
recursive queries whose reply time fit between the lower and upper bound. recursive queries whose reply time fit between the lower and upper bound.
@ -545,6 +559,11 @@ These are also counted in num.query.tcp, because TLS uses TCP.
Number of TLS session resumptions, these are queries over TLS towards Number of TLS session resumptions, these are queries over TLS towards
the unbound server where the client negotiated a TLS session resumption key. the unbound server where the client negotiated a TLS session resumption key.
.TP .TP
.I num.query.https
Number of queries that were made using HTTPS towards the unbound server.
These are also counted in num.query.tcp and num.query.tls, because HTTPS
uses TLS and TCP.
.TP
.I num.query.ipv6 .I num.query.ipv6
Number of queries that were made using IPv6 towards the unbound server. Number of queries that were made using IPv6 towards the unbound server.
.TP .TP

View file

@ -77,6 +77,12 @@ for the included files works, relative pathnames for the included names work
if the directory where the daemon is started equals its chroot/working if the directory where the daemon is started equals its chroot/working
directory or is specified before the include statement with directory: dir. directory or is specified before the include statement with directory: dir.
Wildcards can be used to include multiple files, see \fIglob\fR(7). Wildcards can be used to include multiple files, see \fIglob\fR(7).
.P
For a more structural include option, the
.B include\-toplevel:
directive can be used. This closes whatever clause is currently active (if any)
and forces the use of clauses in the included files and right after this
directive.
.SS "Server Options" .SS "Server Options"
These options are part of the These options are part of the
.B server: .B server:
@ -116,7 +122,8 @@ The port number, default 53, on which the server responds to queries.
Interface to use to connect to the network. This interface is listened to 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. for queries from clients, and answers to clients are given from it.
Can be given multiple times to work on several interfaces. If none are Can be given multiple times to work on several interfaces. If none are
given the default is to listen to localhost. given the default is to listen to localhost. If an interface name is used
instead of an ip address, the list of ip addresses on that interface are used.
The interfaces are not changed on a reload (kill \-HUP) but only on restart. 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 A port number can be specified with @port (without spaces between
interface and port number), if not specified the default port (from interface and port number), if not specified the default port (from
@ -200,12 +207,11 @@ accepted. For larger installations increasing this value is a good idea.
Number of bytes size to advertise as the EDNS reassembly buffer size. 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 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 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. not set higher than that value. Default is 1232 which is the DNS Flag Day 2020
If you have fragmentation reassembly problems, usually seen as timeouts, recommendation. Setting to 512 bypasses even the most stringent path MTU
then a value of 1472 can fix it. Setting to 512 bypasses even the most problems, but is seen as extreme, since the amount of TCP fallback generated is
stringent path MTU problems, but is seen as extreme, since the amount excessive (probably also for this resolver, consider tuning the outgoing tcp
of TCP fallback generated is excessive (probably also for this resolver, number).
consider tuning the outgoing tcp number).
.TP .TP
.B max\-udp\-size: \fI<number> .B max\-udp\-size: \fI<number>
Maximum UDP response size (not applied to TCP response). 65536 disables the Maximum UDP response size (not applied to TCP response). 65536 disables the
@ -268,6 +274,10 @@ 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 the ID and remote IP of packets, and unwanted packets are added to the
unwanted packet counter. unwanted packet counter.
.TP .TP
.B udp\-connect: \fI<yes or no>
Perform connect for UDP sockets that mitigates ICMP side channel leakage.
Default is yes.
.TP
.B unknown\-server\-time\-limit: \fI<msec> .B unknown\-server\-time\-limit: \fI<msec>
The wait time in msec for waiting for an unknown server to reply. The wait time in msec for waiting for an unknown server to reply.
Increase this if you are behind a slow satellite link, to eg. 1128. Increase this if you are behind a slow satellite link, to eg. 1128.
@ -376,6 +386,12 @@ Lower limit for dynamic retransmit timeout calculation in infrastructure
cache. Default is 50 milliseconds. Increase this value if using forwarders cache. Default is 50 milliseconds. Increase this value if using forwarders
needing more time to do recursive name resolution. needing more time to do recursive name resolution.
.TP .TP
.B infra\-keep\-probing: \fI<yes or no>
If enabled the server keeps probing hosts that are down, in the one probe
at a time regime. Default is no. Hosts that are down, eg. they did
not respond during the one probe at a time period, are marked as down and
it may take \fBinfra\-host\-ttl\fR time to get probed again.
.TP
.B define\-tag: \fI<"list of tags"> .B define\-tag: \fI<"list of tags">
Define the tags that can be used with local\-zone and access\-control. Define the tags that can be used with local\-zone and access\-control.
Enclose the list between quotes ("") and put spaces between tags. Enclose the list between quotes ("") and put spaces between tags.
@ -478,15 +494,16 @@ Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
file the last is used. file the last is used.
.TP .TP
.B tls\-service\-key: \fI<file> .B tls\-service\-key: \fI<file>
If enabled, the server provides TLS service on the TCP ports marked If enabled, the server provides DNS-over-TLS or DNS-over-HTTPS service on the
implicitly or explicitly for TLS service with tls\-port. The file must TCP ports marked implicitly or explicitly for these services with tls\-port or
contain the private key for the TLS session, the public certificate is in https\-port. The file must contain the private key for the TLS session, the
the tls\-service\-pem file and it must also be specified if tls\-service\-key public certificate is in the tls\-service\-pem file and it must also be
is specified. The default is "", turned off. Enabling or disabling specified if tls\-service\-key is specified. The default is "", turned off.
this service requires a restart (a reload is not enough), because the Enabling or disabling this service requires a restart (a reload is not enough),
key is read while root permissions are held and before chroot (if any). because the key is read while root permissions are held and before chroot (if any).
The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide The ports enabled implicitly or explicitly via \fBtls\-port:\fR and
normal DNS TCP service. \fBhttps\-port:\fR do not provide normal DNS TCP service. Unbound needs to be
compiled with libnghttp2 in order to provide DNS-over-HTTPS.
.TP .TP
.B ssl\-service\-key: \fI<file> .B ssl\-service\-key: \fI<file>
Alternate syntax for \fBtls\-service\-key\fR. Alternate syntax for \fBtls\-service\-key\fR.
@ -509,7 +526,8 @@ Alternate syntax for \fBtls\-port\fR.
If null or "", no file is used. Set it to the certificate bundle file, If null or "", no file is used. Set it to the certificate bundle file,
for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used
for authenticating connections made to outside peers. For example auth\-zone for authenticating connections made to outside peers. For example auth\-zone
urls, and also DNS over TLS connections. urls, and also DNS over TLS connections. It is read at start up before
permission drop and chroot.
.TP .TP
.B ssl\-cert\-bundle: \fI<file> .B ssl\-cert\-bundle: \fI<file>
Alternate syntax for \fBtls\-cert\-bundle\fR. Alternate syntax for \fBtls\-cert\-bundle\fR.
@ -546,11 +564,63 @@ and that is the default.
Set the list of ciphersuites to allow when serving TLS. This is for newer Set the list of ciphersuites to allow when serving TLS. This is for newer
TLS 1.3 connections. Use "" for defaults, and that is the default. TLS 1.3 connections. Use "" for defaults, and that is the default.
.TP .TP
.B pad\-responses: \fI<yes or no>
If enabled, TLS serviced queries that contained an EDNS Padding option will
cause responses padded to the closest multiple of the size specified in
\fBpad\-responses\-block\-size\fR.
Default is yes.
.TP
.B pad\-responses\-block\-size: \fI<number>
The block size with which to pad responses serviced over TLS. Only responses
to padded queries will be padded.
Default is 468.
.TP
.B pad\-queries: \fI<yes or no>
If enabled, all queries sent over TLS upstreams will be padded to the closest
multiple of the size specified in \fBpad\-queries\-block\-size\fR.
Default is yes.
.TP
.B pad\-queries\-block\-size: \fI<number>
The block size with which to pad queries sent over TLS upstreams.
Default is 128.
.B tls\-use\-sni: \fI<yes or no> .B tls\-use\-sni: \fI<yes or no>
Enable or disable sending the SNI extension on TLS connections. Enable or disable sending the SNI extension on TLS connections.
Default is yes. Default is yes.
Changing the value requires a reload. Changing the value requires a reload.
.TP .TP
.B https\-port: \fI<number>
The port number on which to provide DNS-over-HTTPS service, default 443, only
interfaces configured with that port number as @number get the HTTPS service.
.TP
.B http\-endpoint: \fI<endpoint string>
The HTTP endpoint to provide DNS-over-HTTPS service on. Default "/dns-query".
.TP
.B http\-max\-streams: \fI<number of streams>
Number used in the SETTINGS_MAX_CONCURRENT_STREAMS parameter in the HTTP/2
SETTINGS frame for DNS-over-HTTPS connections. Default 100.
.TP
.B http\-query\-buffer\-size: \fI<size in bytes>
Maximum number of bytes used for all HTTP/2 query buffers combined. These
buffers contain (partial) DNS queries waiting for request stream completion.
An RST_STREAM frame will be send to streams exceeding this limit. 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 http\-response\-buffer\-size: \fI<size in bytes>
Maximum number of bytes used for all HTTP/2 response buffers combined. These
buffers contain DNS responses waiting to be written back to the clients.
An RST_STREAM frame will be send to streams exceeding this limit. 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 http\-nodelay: \fI<yes or no>
Set TCP_NODELAY socket option on sockets used to provide DNS-over-HTTPS service.
Ignored if the option is not available. Default is yes.
.TP
.B http\-notls\-downstream: \fI<yes or no>
Disable use of TLS for the downstream DNS-over-HTTP connections. Useful for
local back end servers. Default is no.
.TP
.B use\-systemd: \fI<yes or no> .B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation. Enable or disable systemd socket activation.
Default is no. Default is no.
@ -768,6 +838,11 @@ If enabled version.server and version.bind queries are refused.
Set the version to report. If set to "", the default, then the package Set the version to report. If set to "", the default, then the package
version is returned. version is returned.
.TP .TP
.B nsid:\fR <string>
Add the specified nsid to the EDNS section of the answer when queried
with an NSID EDNS enabled packet. As a sequence of hex characters or
with ascii_ prefix and then an ascii string.
.TP
.B hide\-trustanchor: \fI<yes or no> .B hide\-trustanchor: \fI<yes or no>
If enabled trustanchor.unbound queries are refused. If enabled trustanchor.unbound queries are refused.
.TP .TP
@ -788,9 +863,8 @@ closer to that of BIND 9, while setting "\-1 \-1 \-1 \-1 \-1" gives behaviour
rumoured to be closer to that of BIND 8. rumoured to be closer to that of BIND 8.
.TP .TP
.B harden\-short\-bufsize: \fI<yes or no> .B harden\-short\-bufsize: \fI<yes or no>
Very small EDNS buffer sizes from queries are ignored. Default is off, since Very small EDNS buffer sizes from queries are ignored. Default is on, as
it is legal protocol wise to send these, and unbound tries to give very described in the standard.
small answers to these queries, where possible.
.TP .TP
.B harden\-large\-queries: \fI<yes or no> .B harden\-large\-queries: \fI<yes or no>
Very large queries are ignored. Default is off, since it is legal protocol Very large queries are ignored. Default is off, since it is legal protocol
@ -847,12 +921,15 @@ authority servers and checks if the reply still has the correct casing.
Disabled by default. Disabled by default.
This feature is an experimental implementation of draft dns\-0x20. This feature is an experimental implementation of draft dns\-0x20.
.TP .TP
.B caps\-whitelist: \fI<domain> .B caps\-exempt: \fI<domain>
Whitelist the domain so that it does not receive caps\-for\-id perturbed Exempt 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 queries. For domains that do not support 0x20 and also fail with fallback
because they keep sending different answers, like some load balancers. because they keep sending different answers, like some load balancers.
Can be given multiple times, for different domains. Can be given multiple times, for different domains.
.TP .TP
.B caps\-whitelist: \fI<yes or no>
Alternate syntax for \fBcaps\-exempt\fR.
.TP
.B qname\-minimisation: \fI<yes or no> .B qname\-minimisation: \fI<yes or no>
Send minimum amount of information to upstream servers to enhance privacy. Send minimum amount of information to upstream servers to enhance privacy.
Only send minimum required labels of the QNAME and set QTYPE to A when Only send minimum required labels of the QNAME and set QTYPE to A when
@ -864,7 +941,7 @@ NXDOMAIN from a DNSSEC signed zone. Default is yes.
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
potentially broken nameservers. A lot of domains will not be resolvable when potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing. this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is off. This option only has effect when qname-minimisation is enabled. Default is no.
.TP .TP
.B aggressive\-nsec: \fI<yes or no> .B aggressive\-nsec: \fI<yes or no>
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
@ -963,7 +1040,9 @@ EDNS client subnet support the default is "subnetcache validator iterator".
Most modules that need to be listed here have to be listed at the beginning Most modules that need to be listed here have to be listed at the beginning
of the line. The cachedb module has to be listed just before the iterator. of the line. The cachedb module has to be listed just before the iterator.
The python module can be listed in different places, it then processes the The python module can be listed in different places, it then processes the
output of the module it is just before. output of the module it is just before. The dynlib module can be listed pretty
much anywhere, it is only a very thin wrapper that allows dynamic libraries to
run in its place.
.TP .TP
.B trust\-anchor\-file: \fI<filename> .B trust\-anchor\-file: \fI<filename>
File with trusted keys for validation. Both DS and DNSKEY entries can appear File with trusted keys for validation. Both DS and DNSKEY entries can appear
@ -1002,26 +1081,11 @@ Send RFC8145 key tag query after trust anchor priming. Default is yes.
.B root\-key\-sentinel: \fI<yes or no> .B root\-key\-sentinel: \fI<yes or no>
Root key trust anchor sentinel. Default is yes. Root key trust anchor sentinel. Default is yes.
.TP .TP
.B dlv\-anchor\-file: \fI<filename>
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<domain name> .B domain\-insecure: \fI<domain name>
Sets domain name to be insecure, DNSSEC chain of trust is ignored towards 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 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. 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 Can be given multiple times
to specify multiple domains that are treated as if unsigned. If you set to specify multiple domains that are treated as if unsigned. If you set
trust anchors for the domain they override this setting (and the domain trust anchors for the domain they override this setting (and the domain
is secured). is secured).
@ -1100,7 +1164,7 @@ later on. Default is "no".
.B serve\-expired\-ttl: \fI<seconds> .B serve\-expired\-ttl: \fI<seconds>
Limit serving of expired responses to configured seconds after expiration. 0 Limit serving of expired responses to configured seconds after expiration. 0
disables the limit. This option only applies when \fBserve\-expired\fR is disables the limit. This option only applies when \fBserve\-expired\fR is
enabled. A suggested value per draft-ietf-dnsop-serve-stale-10 is between enabled. A suggested value per RFC 8767 is between
86400 (1 day) and 259200 (3 days). The default is 0. 86400 (1 day) and 259200 (3 days). The default is 0.
.TP .TP
.B serve\-expired\-ttl\-reset: \fI<yes or no> .B serve\-expired\-ttl\-reset: \fI<yes or no>
@ -1112,16 +1176,29 @@ expired records will be served as long as there are queries for it. Default is
.B serve\-expired\-reply\-ttl: \fI<seconds> .B serve\-expired\-reply\-ttl: \fI<seconds>
TTL value to use when replying with expired data. If TTL value to use when replying with expired data. If
\fBserve\-expired\-client\-timeout\fR is also used then it is RECOMMENDED to \fBserve\-expired\-client\-timeout\fR is also used then it is RECOMMENDED to
use 30 as the value (draft-ietf-dnsop-serve-stale-10). The default is 30. use 30 as the value (RFC 8767). The default is 30.
.TP .TP
.B serve\-expired\-client\-timeout: \fI<msec> .B serve\-expired\-client\-timeout: \fI<msec>
Time in milliseconds before replying to the client with expired data. This Time in milliseconds before replying to the client with expired data. This
essentially enables the serve-stale behavior as specified in essentially enables the serve-stale behavior as specified in
draft-ietf-dnsop-serve-stale-10 that first tries to resolve before immediately RFC 8767 that first tries to resolve before immediately
responding with expired data. A recommended value per responding with expired data. A recommended value per
draft-ietf-dnsop-serve-stale-10 is 1800. Setting this to 0 will disable this RFC 8767 is 1800. Setting this to 0 will disable this
behavior. Default is 0. behavior. Default is 0.
.TP .TP
.B serve\-original\-ttl: \fI<yes or no>
If enabled, unbound will always return the original TTL as received from
the upstream name server rather than the decrementing TTL as
stored in the cache. This feature may be useful if unbound serves as a
front-end to a hidden authoritative name server. Enabling this feature does
not impact cache expiry, it only changes the TTL unbound embeds in responses to
queries. Note that enabling this feature implicitly disables enforcement of
the configured minimum and maximum TTL, as it is assumed users who enable this
feature do not want unbound to change the TTL obtained from an upstream server.
Thus, the values set using \fBcache\-min\-ttl\fR and \fBcache\-max\-ttl\fR are
ignored.
Default is "no".
.TP
.B val\-nsec3\-keysize\-iterations: \fI<"list of values"> .B val\-nsec3\-keysize\-iterations: \fI<"list of values">
List of keysize and iteration count values, separated by spaces, surrounded List of keysize and iteration count values, separated by spaces, surrounded
by quotes. Default is "1024 150 2048 500 4096 2500". This determines the by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
@ -1190,7 +1267,7 @@ address space are not validated. This is usually required whenever
Configure a local zone. The type determines the answer to give if 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, there is no match from local\-data. The types are deny, refuse, static,
transparent, redirect, nodefault, typetransparent, inform, inform_deny, transparent, redirect, nodefault, typetransparent, inform, inform_deny,
inform_redirect, always_transparent, always_refuse, always_nxdomain, noview, inform_redirect, always_transparent, always_refuse, always_nxdomain, always_null, noview,
and are explained below. After that the default settings are listed. Use 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 local\-data: to enter data into the local zone. Answers for local zones
are authoritative DNS answers. By default the zones are class IN. are authoritative DNS answers. By default the zones are class IN.
@ -1264,6 +1341,17 @@ Like refuse, but ignores local data and refuses the query.
\h'5'\fIalways_nxdomain\fR \h'5'\fIalways_nxdomain\fR
Like static, but ignores local data and returns nxdomain for the query. Like static, but ignores local data and returns nxdomain for the query.
.TP 10 .TP 10
\h'5'\fIalways_nodata\fR
Like static, but ignores local data and returns nodata for the query.
.TP 10
\h'5'\fIalways_deny\fR
Like deny, but ignores local data and drops the query.
.TP 10
\h'5'\fIalways_null\fR
Always returns 0.0.0.0 or ::0 for every name in the zone. Like redirect
with zero data for A and AAAA. Ignores local data in the zone. Used for
some block lists.
.TP 10
\h'5'\fInoview\fR \h'5'\fInoview\fR
Breaks out of that view and moves towards the global local zones for answer Breaks out of that view and moves towards the global local zones for answer
to the query. If the view first is no, it'll resolve normally. If view first to the query. If the view first is no, it'll resolve normally. If view first
@ -1508,6 +1596,16 @@ servers set. The default for fast\-server\-permil is 0.
Set the number of servers that should be used for fast server selection. Only Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 3 servers. option, that turns this on or off. The default is to use the fastest 3 servers.
.TP 5
.B edns\-client\-string: \fI<IP netblock> <string>
Include an EDNS0 option containing configured ascii string in queries with
destination address matching the configured IP netblock. This configuration
option can be used multiple times. The most specific match will be used.
.TP 5
.B edns\-client\-string\-opcode: \fI<opcode>
EDNS0 option code for the \fIedns\-client\-string\fR option, from 0 to 65535.
A value from the `Reserved for Local/Experimental` range (65001-65534) should
be used. Default is 65001.
.SS "Remote Control Options" .SS "Remote Control Options"
In the In the
.B remote\-control: .B remote\-control:
@ -1612,6 +1710,9 @@ Name of stub zone nameserver. Is itself resolved before it is used.
.B stub\-addr: \fI<IP address> .B stub\-addr: \fI<IP address>
IP address of stub zone nameserver. Can be IP 4 or IP 6. 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. To use a nondefault port for DNS communication append '@' with the port number.
If tls is enabled, then you can append a '#' and a name, then it'll check
the tls authentication certificates with that name. If you combine
the '@' and '#', the '@' comes first.
.TP .TP
.B stub\-prime: \fI<yes or no> .B stub\-prime: \fI<yes or no>
This option is by default no. If enabled it performs NS set priming, This option is by default no. If enabled it performs NS set priming,
@ -1707,16 +1808,16 @@ uses the SOA timer values and performs SOA UDP queries to detect zone changes.
If the update fetch fails, the timers in the SOA record are used to time If the update fetch fails, the timers in the SOA record are used to time
another fetch attempt. Until the SOA expiry timer is reached. Then the another fetch attempt. Until the SOA expiry timer is reached. Then the
zone is expired. When a zone is expired, queries are SERVFAIL, and zone is expired. When a zone is expired, queries are SERVFAIL, and
any new serial number is accepted from the master (even if older), and if any new serial number is accepted from the primary (even if older), and if
fallback is enabled, the fallback activates to fetch from the upstream instead fallback is enabled, the fallback activates to fetch from the upstream instead
of the SERVFAIL. of the SERVFAIL.
.TP .TP
.B name: \fI<zone name> .B name: \fI<zone name>
Name of the authority zone. Name of the authority zone.
.TP .TP
.B master: \fI<IP address or host name> .B primary: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails. primaries can be specified. They are all tried if one fails.
With the "ip#name" notation a AXFR over TLS can be used. With the "ip#name" notation a AXFR over TLS can be used.
If you point it at another Unbound instance, it would not work because If you point it at another Unbound instance, it would not work because
that does not support AXFR/IXFR for the zone, but if you used \fBurl:\fR to download that does not support AXFR/IXFR for the zone, but if you used \fBurl:\fR to download
@ -1725,27 +1826,31 @@ If you specify the hostname, you cannot use the domain from the zonefile,
because it may not have that when retrieving that data, instead use a plain because it may not have that when retrieving that data, instead use a plain
IP address to avoid a circular dependency on retrieving that IP address. IP address to avoid a circular dependency on retrieving that IP address.
.TP .TP
.B master: \fI<IP address or host name>
Alternate syntax for \fBprimary\fR.
.TP
.B url: \fI<url to zonefile> .B url: \fI<url to zonefile>
Where to download a zonefile for the zone. With http or https. An example Where to download a zonefile for the zone. With http or https. An example
for the url is "http://www.example.com/example.org.zone". Multiple url for the url is "http://www.example.com/example.org.zone". Multiple url
statements can be given, they are tried in turn. If only urls are given statements can be given, they are tried in turn. If only urls are given
the SOA refresh timer is used to wait for making new downloads. If also the SOA refresh timer is used to wait for making new downloads. If also
masters are listed, the masters are first probed with UDP SOA queries to primaries are listed, the primaries are first probed with UDP SOA queries to
see if the SOA serial number has changed, reducing the number of downloads. see if the SOA serial number has changed, reducing the number of downloads.
If none of the urls work, the masters are tried with IXFR and AXFR. If none of the urls work, the primaries are tried with IXFR and AXFR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection. to authenticate the connection.
If you specify a hostname in the URL, you cannot use the domain from the If you specify a hostname in the URL, you cannot use the domain from the
zonefile, because it may not have that when retrieving that data, instead zonefile, because it may not have that when retrieving that data, instead
use a plain IP address to avoid a circular dependency on retrieving that IP use a plain IP address to avoid a circular dependency on retrieving that IP
address. Avoid dependencies on name lookups by using a notation like "http://192.0.2.1/unbound-master/example.com.zone", with an explicit IP address. address. Avoid dependencies on name lookups by using a notation like
"http://192.0.2.1/unbound-primaries/example.com.zone", with an explicit IP address.
.TP .TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix> .B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies. With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer. When notified, the server attempts to first probe and then zone transfer.
If the notify is from a master, it first attempts that master. Otherwise If the notify is from a primary, it first attempts that primary. Otherwise
other masters are attempted. If there are no masters, but only urls, the other primaries are attempted. If there are no primaries, but only urls, the
file is downloaded when notified. The masters from master: statements are file is downloaded when notified. The primaries from primary: statements are
allowed notify by default. allowed notify by default.
.TP .TP
.B fallback\-enabled: \fI<yes or no> .B fallback\-enabled: \fI<yes or no>
@ -1773,7 +1878,7 @@ downstream clients, and use the zone data as a local copy to speed up lookups.
.B zonefile: \fI<filename> .B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used. The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone If the file does not exist or is empty, unbound will attempt to fetch zone
data (eg. from the master servers). data (eg. from the primary servers).
.SS "View Options" .SS "View Options"
.LP .LP
There may be multiple There may be multiple
@ -1830,6 +1935,24 @@ directory.
.B python\-script: \fI<python file>\fR .B python\-script: \fI<python file>\fR
The script file to load. Repeat this option for every python module instance The script file to load. Repeat this option for every python module instance
added to the \fBmodule\-config:\fR option. added to the \fBmodule\-config:\fR option.
.SS "Dynamic Library Module Options"
.LP
The
.B dynlib:
clause gives the settings for the \fIdynlib\fR module. This module is only
a very small wrapper that allows dynamic modules to be loaded on runtime
instead of being compiled into the application. To enable the dynlib module it
has to be compiled into the daemon, and the word "dynlib" has to be put in the
\fBmodule\-config:\fR option. Multiple instances of dynamic libraries are
supported by adding the word "dynlib" more than once.
.LP
The \fBdynlib\-file:\fR path should be specified as an absolute path relative
to the new path set by \fBchroot:\fR option, or as a relative path to the
working directory.
.TP
.B dynlib\-file: \fI<dynlib file>\fR
The dynamic library file to load. Repeat this option for every dynlib module
instance added to the \fBmodule\-config:\fR option.
.SS "DNS64 Module Options" .SS "DNS64 Module Options"
.LP .LP
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64 The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
@ -1922,14 +2045,16 @@ The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache
validator iterator" directive and be compiled into the daemon to be validator iterator" directive and be compiled into the daemon to be
enabled. These settings go in the \fBserver:\fR section. enabled. These settings go in the \fBserver:\fR section.
.LP .LP
If the destination address is whitelisted with Unbound will add the EDNS0 If the destination address is allowed in the configuration Unbound will add the
option to the query containing the relevant part of the client's address. When EDNS0 option to the query containing the relevant part of the client's address.
an answer contains the ECS option the response and the option are placed in a When an answer contains the ECS option the response and the option are placed in
specialized cache. If the authority indicated no support, the response is a specialized cache. If the authority indicated no support, the response is
stored in the regular cache. stored in the regular cache.
.LP .LP
Additionally, when a client includes the option in its queries, Unbound will Additionally, when a client includes the option in its queries, Unbound will
forward the option to the authority if present in the whitelist, or forward the option when sending the query to addresses that are explicitly
allowed in the configuration using \fBsend\-client\-subnet\fR. The option will
always be forwarded, regardless the allowed addresses, if
\fBclient\-subnet\-always\-forward\fR is set to yes. In this case the lookup in \fBclient\-subnet\-always\-forward\fR is set to yes. In this case the lookup in
the regular cache is skipped. the regular cache is skipped.
.LP .LP
@ -1950,12 +2075,13 @@ given multiple times. Zones not listed will not receive edns-subnet information,
unless hosted by authority specified in \fBsend\-client\-subnet\fR. unless hosted by authority specified in \fBsend\-client\-subnet\fR.
.TP .TP
.B client\-subnet\-always\-forward: \fI<yes or no>\fR .B client\-subnet\-always\-forward: \fI<yes or no>\fR
Specify whether the ECS whitelist check (configured using Specify whether the ECS address check (configured using
\fBsend\-client\-subnet\fR) is applied for all queries, even if the triggering \fBsend\-client\-subnet\fR) is applied for all queries, even if the triggering
query contains an ECS record, or only for queries for which the ECS record is query contains an ECS record, or only for queries for which the ECS record is
generated using the querier address (and therefore did not contain ECS data in generated using the querier address (and therefore did not contain ECS data in
the client query). If enabled, the whitelist check is skipped when the client the client query). If enabled, the address check is skipped when the client
query contains an ECS record. Default is no. query contains an ECS record. And the lookup in the regular cache is skipped.
Default is no.
.TP .TP
.B max\-client\-subnet\-ipv6: \fI<number>\fR .B max\-client\-subnet\-ipv6: \fI<number>\fR
Specifies the maximum prefix length of the client source address we are willing Specifies the maximum prefix length of the client source address we are willing
@ -2044,10 +2170,13 @@ to yes, the hook will be called and the A/AAAA answer will be returned to the
client. If set to no, the hook will not be called and the answer to the client. If set to no, the hook will not be called and the answer to the
A/AAAA query will be SERVFAIL. Mainly used for testing. Defaults to no. A/AAAA query will be SERVFAIL. Mainly used for testing. Defaults to no.
.TP .TP
.B ipsecmod\-whitelist: \fI<domain>\fR .B ipsecmod\-allow: \fI<domain>\fR
Whitelist the domain so that the module logic will be executed. Can Allow the ipsecmod functionality for the domain so that the module logic will be
be given multiple times, for different domains. If the option is not executed. Can be given multiple times, for different domains. If the option is
specified, all domains are treated as being whitelisted (default). not specified, all domains are treated as being allowed (default).
.TP
.B ipsecmod\-whitelist: \fI<yes or no>
Alternate syntax for \fBipsecmod\-allow\fR.
.SS "Cache DB Module Options" .SS "Cache DB Module Options"
.LP .LP
The Cache DB module must be configured in the \fBmodule\-config:\fR The Cache DB module must be configured in the \fBmodule\-config:\fR
@ -2081,7 +2210,7 @@ even if some data have expired in terms of DNS TTL or the Redis server has
cached too much data; cached too much data;
if necessary the Redis server must be configured to limit the cache size, if necessary the Redis server must be configured to limit the cache size,
preferably with some kind of least-recently-used eviction policy. preferably with some kind of least-recently-used eviction policy.
Additionaly, the \fBredis\-expire\-records\fR option can be used in order to Additionally, the \fBredis\-expire\-records\fR option can be used in order to
set the relative DNS TTL of the message as timeout to the Redis records; keep set the relative DNS TTL of the message as timeout to the Redis records; keep
in mind that some additional memory is used per key and that the expire in mind that some additional memory is used per key and that the expire
information is stored as absolute Unix timestamps in Redis (computer time must information is stored as absolute Unix timestamps in Redis (computer time must
@ -2160,6 +2289,10 @@ If dnstap is enabled. Default no. If yes, it connects to the dnstap server
and if any of the dnstap-log-..-messages options is enabled it sends logs and if any of the dnstap-log-..-messages options is enabled it sends logs
for those messages to the server. for those messages to the server.
.TP .TP
.B dnstap-bidirectional: \fI<yes or no>
Use frame streams in bidirectional mode to transfer DNSTAP messages. Default is
yes.
.TP
.B dnstap-socket-path: \fI<file name> .B dnstap-socket-path: \fI<file name>
Sets the unix socket file name for connecting to the server that is Sets the unix socket file name for connecting to the server that is
listening on that socket. Default is "@DNSTAP_SOCKET_PATH@". listening on that socket. Default is "@DNSTAP_SOCKET_PATH@".
@ -2240,33 +2373,36 @@ are applied after
.B name: \fI<zone name> .B name: \fI<zone name>
Name of the authority zone. Name of the authority zone.
.TP .TP
.B master: \fI<IP address or host name> .B primary: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails. primaries can be specified. They are all tried if one fails.
.TP
.B master: \fI<IP address or host name>
Alternate syntax for \fBprimary\fR.
.TP .TP
.B url: \fI<url to zonefile> .B url: \fI<url to zonefile>
Where to download a zonefile for the zone. With http or https. An example Where to download a zonefile for the zone. With http or https. An example
for the url is "http://www.example.com/example.org.zone". Multiple url for the url is "http://www.example.com/example.org.zone". Multiple url
statements can be given, they are tried in turn. If only urls are given statements can be given, they are tried in turn. If only urls are given
the SOA refresh timer is used to wait for making new downloads. If also the SOA refresh timer is used to wait for making new downloads. If also
masters are listed, the masters are first probed with UDP SOA queries to primaries are listed, the primaries are first probed with UDP SOA queries to
see if the SOA serial number has changed, reducing the number of downloads. see if the SOA serial number has changed, reducing the number of downloads.
If none of the urls work, the masters are tried with IXFR and AXFR. If none of the urls work, the primaries are tried with IXFR and AXFR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection. to authenticate the connection.
.TP .TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix> .B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies. With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer. When notified, the server attempts to first probe and then zone transfer.
If the notify is from a master, it first attempts that master. Otherwise If the notify is from a primary, it first attempts that primary. Otherwise
other masters are attempted. If there are no masters, but only urls, the other primaries are attempted. If there are no primaries, but only urls, the
file is downloaded when notified. The masters from master: statements are file is downloaded when notified. The primaries from primary: statements are
allowed notify by default. allowed notify by default.
.TP .TP
.B zonefile: \fI<filename> .B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used. The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone If the file does not exist or is empty, unbound will attempt to fetch zone
data (eg. from the master servers). data (eg. from the primary servers).
.TP .TP
.B rpz\-action\-override: \fI<action> .B rpz\-action\-override: \fI<action>
Always use this RPZ action for matching triggers from this zone. Possible action Always use this RPZ action for matching triggers from this zone. Possible action

View file

@ -1143,7 +1143,7 @@ COMPACT_LATEX = NO
# by the printer. Possible values are: a4, a4wide, letter, legal and # by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used. # executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide #PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output. # packages that should be included in the LaTeX output.
@ -1451,7 +1451,7 @@ EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script # The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl'). # interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl #PERL_PATH = /usr/bin/perl
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the dot tool # Configuration options related to the dot tool
@ -1473,7 +1473,7 @@ CLASS_DIAGRAMS = YES
# the mscgen tool resides. If left empty the tool is assumed to be found in the # the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path. # default search path.
MSCGEN_PATH = #MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide # If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented # inheritance and usage relations if the target is undocumented

306
dynlibmod/dynlibmod.c Normal file
View file

@ -0,0 +1,306 @@
/**
* \file
* This file contains the dynamic library module for Unbound.
* This loads a dynamic library (.dll, .so) and calls that for the
* module actions.
*/
#include "config.h"
#include "dynlibmod/dynlibmod.h"
#include "util/module.h"
#include "util/config_file.h"
#if HAVE_WINDOWS_H
#include <windows.h>
#define __DYNMOD HMODULE
#define __DYNSYM FARPROC
#define __LOADSYM GetProcAddress
static void log_dlerror() {
DWORD dwLastError = GetLastError();
LPSTR MessageBuffer;
DWORD dwBufferLength;
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM ;
if((dwBufferLength = FormatMessageA(
dwFormatFlags,
NULL, // module to get message from (NULL == system)
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPSTR) &MessageBuffer,
0,
NULL
)))
{
log_err("dynlibmod: %s (%ld)", MessageBuffer, dwLastError);
LocalFree(MessageBuffer);
}
}
static HMODULE open_library(const char* fname) {
return LoadLibrary(fname);
}
static void close_library(const char* fname, __DYNMOD handle) {
(void)fname;
(void)handle;
}
#else
#include <dlfcn.h>
#define __DYNMOD void*
#define __DYNSYM void*
#define __LOADSYM dlsym
static void log_dlerror() {
log_err("dynlibmod: %s", dlerror());
}
static void* open_library(const char* fname) {
return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
}
static void close_library(const char* fname, __DYNMOD handle) {
if(!handle) return;
if(dlclose(handle) != 0) {
log_err("dlclose %s: %s", fname, strerror(errno));
}
}
#endif
/** module counter for multiple dynlib modules */
static int dynlib_mod_count = 0;
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id) {
int dynlib_mod_idx = dynlib_mod_count++;
struct config_strlist* cfg_item = env->cfg->dynlib_file;
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
__DYNMOD dynamic_library;
if (!de)
{
log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
return 0;
}
env->modinfo[id] = (void*) de;
de->fname = NULL;
for(int i = dynlib_mod_idx;
i != 0 && cfg_item != NULL;
i--, cfg_item = cfg_item->next) {}
if (cfg_item == NULL || cfg_item->str == NULL || cfg_item->str[0] == 0) {
log_err("dynlibmod[%d]: no dynamic library given.", dynlib_mod_idx);
return 0;
} else {
de->fname = cfg_item->str;
}
verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
dynamic_library = open_library(de->fname);
de->dynamic_library = (void*)dynamic_library;
if (dynamic_library == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
__DYNSYM initializer;
__DYNSYM deinitializer;
__DYNSYM operate;
__DYNSYM inform;
__DYNSYM clear;
__DYNSYM get_mem;
initializer = __LOADSYM(dynamic_library,"init");
if (initializer == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load init procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_init = (func_init_t)(void*)initializer;
}
deinitializer = __LOADSYM(dynamic_library,"deinit");
if (deinitializer == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load deinit procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_deinit = (func_deinit_t)(void*)deinitializer;
}
operate = __LOADSYM(dynamic_library,"operate");
if (operate == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load operate procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_operate = (func_operate_t)(void*)operate;
}
inform = __LOADSYM(dynamic_library,"inform_super");
if (inform == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load inform_super procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_inform = (func_inform_t)(void*)inform;
}
clear = __LOADSYM(dynamic_library,"clear");
if (clear == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load clear procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_clear = (func_clear_t)(void*)clear;
}
get_mem = __LOADSYM(dynamic_library,"get_mem");
if (get_mem == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load get_mem procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_get_mem = (func_get_mem_t)(void*)get_mem;
}
}
de->inplace_cb_delete_wrapped = &inplace_cb_delete_wrapped;
de->inplace_cb_register_wrapped = &inplace_cb_register_wrapped;
return de->func_init(env, id);
}
/** dynlib module deinit */
void dynlibmod_deinit(struct module_env* env, int id) {
struct dynlibmod_env* de = env->modinfo[id];
if(de == NULL)
return;
de->func_deinit(env, id);
close_library(de->fname, (__DYNMOD)de->dynamic_library);
dynlib_mod_count--;
de->fname = NULL;
free(de);
}
/** dynlib module operate on a query */
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
de->func_operate(qstate, event, id, outbound);
}
/** dynlib module */
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
de->func_inform(qstate, id, super);
}
/** dynlib module cleanup query state */
void dynlibmod_clear(struct module_qstate* qstate, int id) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
de->func_clear(qstate, id);
}
/** dynlib module alloc size routine */
size_t dynlibmod_get_mem(struct module_env* env, int id) {
struct dynlibmod_env* de = (struct dynlibmod_env*)env->modinfo[id];
size_t size;
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
if(!de)
return 0;
size = de->func_get_mem(env, id);
return size + sizeof(*de);
}
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region,
struct timeval* start_time, int id, void* callback) {
struct cb_pair* cb_pair = (struct cb_pair*) callback;
return ((inplace_cb_reply_func_type*) cb_pair->cb)(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, region, start_time, id, cb_pair->cb_arg);
}
int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
struct module_qstate* qstate, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region,
int id, void* callback) {
struct cb_pair* cb_pair = (struct cb_pair*) callback;
return ((inplace_cb_query_func_type*) cb_pair->cb)(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, id, cb_pair->cb_arg);
}
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
int id, void* cb_args) {
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
return ((inplace_cb_edns_back_parsed_func_type*) cb_pair->cb)(qstate, id, cb_pair->cb_arg);
}
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
struct dns_msg* response, int id, void* cb_args) {
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
return ((inplace_cb_query_response_func_type*) cb_pair->cb)(qstate, response, id, cb_pair->cb_arg);
}
int
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
struct module_env* env, int id) {
struct cb_pair* cb_pair = malloc(sizeof(struct cb_pair));
if(cb_pair == NULL) {
log_err("dynlibmod[%d]: malloc failure", id);
return 0;
}
cb_pair->cb = cb;
cb_pair->cb_arg = cbarg;
if(type >= inplace_cb_reply && type <= inplace_cb_reply_servfail) {
return inplace_cb_register(&dynlib_inplace_cb_reply_generic, type, (void*) cb_pair, env, id);
} else if(type == inplace_cb_query) {
return inplace_cb_register(&dynlib_inplace_cb_query_generic, type, (void*) cb_pair, env, id);
} else if(type == inplace_cb_query_response) {
return inplace_cb_register(&dynlib_inplace_cb_query_response, type, (void*) cb_pair, env, id);
} else if(type == inplace_cb_edns_back_parsed) {
return inplace_cb_register(&dynlib_inplace_cb_edns_back_parsed, type, (void*) cb_pair, env, id);
} else {
free(cb_pair);
return 0;
}
}
void
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
int id) {
struct inplace_cb* temp = env->inplace_cb_lists[type];
struct inplace_cb* prev = NULL;
while(temp) {
if(temp->id == id) {
if(!prev) {
env->inplace_cb_lists[type] = temp->next;
free(temp->cb_arg);
free(temp);
temp = env->inplace_cb_lists[type];
}
else {
prev->next = temp->next;
free(temp->cb_arg);
free(temp);
temp = prev->next;
}
}
else {
prev = temp;
temp = temp->next;
}
}
}
/**
* The module function block
*/
static struct module_func_block dynlibmod_block = {
"dynlib",
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
&dynlibmod_clear, &dynlibmod_get_mem
};
struct module_func_block* dynlibmod_get_funcblock(void)
{
return &dynlibmod_block;
}

139
dynlibmod/dynlibmod.h Normal file
View file

@ -0,0 +1,139 @@
/*
* dynlibmod.h: module header file
*
* Copyright (c) 2019, Peter Munch-Ellingsen (peterme AT peterme.net)
*
* 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 organization 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 REGENTS 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
* Dynamic loading module for unbound. Loads dynamic library.
*/
#ifndef DYNLIBMOD_H
#define DYNLIBMOD_H
#include "util/module.h"
#include "services/outbound_list.h"
/**
* Get the module function block.
* @return: function block with function pointers to module methods.
*/
struct module_func_block* dynlibmod_get_funcblock(void);
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id);
/** dynlib module deinit */
void dynlibmod_deinit(struct module_env* env, int id);
/** dynlib module operate on a query */
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** dynlib module */
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** dynlib module cleanup query state */
void dynlibmod_clear(struct module_qstate* qstate, int id);
/** dynlib module alloc size routine */
size_t dynlibmod_get_mem(struct module_env* env, int id);
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region,
struct timeval* start_time, int id, void* callback);
int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
struct module_qstate* qstate, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region,
int id, void* callback);
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
int id, void* cb_args);
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
struct dns_msg* response, int id, void* cb_args);
int
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
struct module_env* env, int id);
void
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
int id);
struct cb_pair {
void *cb;
void *cb_arg;
};
/**
* Global state for the module.
*/
typedef int (*func_init_t)(struct module_env*, int);
typedef void (*func_deinit_t)(struct module_env*, int);
typedef void (*func_operate_t)(struct module_qstate*, enum module_ev, int, struct outbound_entry*);
typedef void (*func_inform_t)(struct module_qstate*, int, struct module_qstate*);
typedef void (*func_clear_t)(struct module_qstate*, int);
typedef size_t (*func_get_mem_t)(struct module_env*, int);
typedef void (*inplace_cb_delete_wrapped_t)(struct module_env*, enum inplace_cb_list_type, int);
typedef int (*inplace_cb_register_wrapped_t)(void*, enum inplace_cb_list_type, void*, struct module_env*, int);
struct dynlibmod_env {
/** Dynamic library filename. */
const char* fname;
/** dynamic library handle */
void* dynamic_library;
/** Module init function */
func_init_t func_init;
/** Module deinit function */
func_deinit_t func_deinit;
/** Module operate function */
func_operate_t func_operate;
/** Module super_inform function */
func_inform_t func_inform;
/** Module clear function */
func_clear_t func_clear;
/** Module get_mem function */
func_get_mem_t func_get_mem;
/** Wrapped inplace callback functions to circumvent callback whitelisting */
inplace_cb_delete_wrapped_t inplace_cb_delete_wrapped;
inplace_cb_register_wrapped_t inplace_cb_register_wrapped;
/** Pointer to any data the dynamic library might want to keep */
void *dyn_env;
};
#endif /* DYNLIBMOD_H */

View file

@ -0,0 +1,132 @@
/**
* \file
*
* This is an example to show how dynamic libraries can be made to work with
* unbound. To build a .so file simply run:
* gcc -I../.. -shared -Wall -Werror -fpic -o helloworld.so helloworld.c
* And to build for windows, first make unbound with the --with-dynlibmod
* switch, then use this command:
* x86_64-w64-mingw32-gcc -m64 -I../.. -shared -Wall -Werror -fpic
* -o helloworld.dll helloworld.c -L../.. -l:libunbound.dll.a
* to cross-compile a 64-bit Windows DLL. The libunbound.dll.a is produced
* by the compile step that makes unbound.exe and allows the dynlib dll to
* access definitions in unbound.exe.
*/
#include "../../config.h"
#include "../../util/module.h"
#include "../../sldns/parseutil.h"
#include "../dynlibmod.h"
/* Declare the EXPORT macro that expands to exporting the symbol for DLLs when
* compiling for Windows. All procedures marked with EXPORT in this example are
* called directly by the dynlib module and must be present for the module to
* load correctly. */
#ifdef HAVE_WINDOWS_H
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
/* Forward declare a callback, implemented at the bottom of this file */
int reply_callback(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region,
struct timeval* start_time, int id, void* callback);
/* Init is called when the module is first loaded. It should be used to set up
* the environment for this module and do any other initialisation required. */
EXPORT int init(struct module_env* env, int id) {
log_info("dynlib: hello world from init");
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
de->inplace_cb_register_wrapped(&reply_callback,
inplace_cb_reply,
NULL, env, id);
struct dynlibmod_env* local_env = env->modinfo[id];
local_env->dyn_env = NULL;
return 1;
}
/* Deinit is run as the program is shutting down. It should be used to clean up
* the environment and any left over data. */
EXPORT void deinit(struct module_env* env, int id) {
log_info("dynlib: hello world from deinit");
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
de->inplace_cb_delete_wrapped(env, inplace_cb_reply, id);
if (de->dyn_env != NULL) free(de->dyn_env);
}
/* Operate is called every time a query passes by this module. The event can be
* used to determine which direction in the module chain it came from. */
EXPORT void operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* entry) {
log_info("dynlib: hello world from operate");
log_info("dynlib: incoming query: %s %s(%d) %s(%d)",
qstate->qinfo.qname,
sldns_lookup_by_id(sldns_rr_classes, qstate->qinfo.qclass)->name,
qstate->qinfo.qclass,
sldns_rr_descript(qstate->qinfo.qtype)->_name,
qstate->qinfo.qtype);
if (event == module_event_new || event == module_event_pass) {
qstate->ext_state[id] = module_wait_module;
struct dynlibmod_env* env = qstate->env->modinfo[id];
if (env->dyn_env == NULL) {
env->dyn_env = calloc(3, sizeof(int));
((int *)env->dyn_env)[0] = 42;
((int *)env->dyn_env)[1] = 102;
((int *)env->dyn_env)[2] = 192;
} else {
log_err("dynlib: already has data!");
qstate->ext_state[id] = module_error;
}
} else if (event == module_event_moddone) {
qstate->ext_state[id] = module_finished;
} else {
qstate->ext_state[id] = module_error;
}
}
/* Inform super is called when a query is completed or errors out, but only if
* a sub-query has been registered to it by this module. Look at
* mesh_attach_sub in services/mesh.h to see how this is done. */
EXPORT void inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super) {
log_info("dynlib: hello world from inform_super");
}
/* Clear is called once a query is complete and the response has been sent
* back. It is used to clear up any per-query allocations. */
EXPORT void clear(struct module_qstate* qstate, int id) {
log_info("dynlib: hello world from clear");
struct dynlibmod_env* env = qstate->env->modinfo[id];
if (env->dyn_env != NULL) {
free(env->dyn_env);
env->dyn_env = NULL;
}
}
/* Get mem is called when Unbound is printing performance information. This
* only happens explicitly and is only used to show memory usage to the user. */
EXPORT size_t get_mem(struct module_env* env, int id) {
log_info("dynlib: hello world from get_mem");
return 0;
}
/* The callback that was forward declared earlier. It is registered in the init
* procedure to run when a query is being replied to. */
int reply_callback(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region,
struct timeval* start_time, int id, void* callback) {
log_info("dynlib: hello world from callback");
struct dynlibmod_env* env = qstate->env->modinfo[id];
if (env->dyn_env != NULL) {
log_info("dynlib: numbers gotten from query: %d, %d, and %d",
((int *)env->dyn_env)[0],
((int *)env->dyn_env)[1],
((int *)env->dyn_env)[2]);
}
return 0;
}

View file

@ -386,8 +386,7 @@ update_cache(struct module_qstate *qstate, int id)
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */ rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */ rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr, addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
edns->subnet_source_mask, edns->subnet_source_mask, sq->max_scope, rep,
sq->ecs_server_in.subnet_scope_mask, rep,
rep->ttl, *qstate->env->now); rep->ttl, *qstate->env->now);
lock_rw_unlock(&lru_entry->lock); lock_rw_unlock(&lru_entry->lock);
@ -543,7 +542,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
c_out->subnet_addr_fam = c_in->subnet_addr_fam; c_out->subnet_addr_fam = c_in->subnet_addr_fam;
c_out->subnet_source_mask = c_in->subnet_source_mask; c_out->subnet_source_mask = c_in->subnet_source_mask;
memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE); memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
c_out->subnet_scope_mask = s_in->subnet_scope_mask; c_out->subnet_scope_mask = sq->max_scope;
/* Limit scope returned to client to scope used for caching. */ /* Limit scope returned to client to scope used for caching. */
if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) { if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
if(c_out->subnet_scope_mask > if(c_out->subnet_scope_mask >
@ -648,6 +647,19 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
qstate->env->cfg->client_subnet_opcode); qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0; sq->subnet_sent = 0;
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out)); memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
} else if (!sq->track_max_scope &&
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_NOERROR &&
response->rep->an_numrrsets > 0
) {
struct ub_packed_rrset_key* s = response->rep->rrsets[0];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(qstate->qinfo.qname,
s->rk.dname) == 0) {
/* CNAME response for QNAME. From now on keep track of
* longest received ECS prefix for all queries on this
* qstate. */
sq->track_max_scope = 1;
}
} }
return 1; return 1;
} }
@ -663,16 +675,19 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
return 1; return 1;
if((ecs_opt = edns_opt_list_find( if((ecs_opt = edns_opt_list_find(
qstate->edns_opts_back_in, qstate->edns_opts_back_in,
qstate->env->cfg->client_subnet_opcode))) { qstate->env->cfg->client_subnet_opcode)) &&
if(parse_subnet_option(ecs_opt, &sq->ecs_server_in) && parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
sq->subnet_sent && sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
sq->ecs_server_in.subnet_validdata)
/* Only skip global cache store if we sent an ECS option /* Only skip global cache store if we sent an ECS option
* and received one back. Answers from non-whitelisted * and received one back. Answers from non-whitelisted
* servers will end up in global cache. Answers for * servers will end up in global cache. Answers for
* queries with 0 source will not (unless nameserver * queries with 0 source will not (unless nameserver
* does not support ECS). */ * does not support ECS). */
qstate->no_cache_store = 1; qstate->no_cache_store = 1;
if(!sq->track_max_scope || (sq->track_max_scope &&
sq->ecs_server_in.subnet_scope_mask >
sq->max_scope))
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
} }
return 1; return 1;

View file

@ -45,6 +45,7 @@
#include "util/alloc.h" #include "util/alloc.h"
#include "util/net_help.h" #include "util/net_help.h"
#include "util/storage/slabhash.h" #include "util/storage/slabhash.h"
#include "util/data/dname.h"
#include "edns-subnet/addrtree.h" #include "edns-subnet/addrtree.h"
#include "edns-subnet/edns-subnet.h" #include "edns-subnet/edns-subnet.h"
@ -83,6 +84,12 @@ struct subnet_qstate {
struct ecs_data ecs_server_out; struct ecs_data ecs_server_out;
int subnet_downstream; int subnet_downstream;
int subnet_sent; int subnet_sent;
/** keep track of longest received scope, set after receiving CNAME for
* incoming QNAME. */
int track_max_scope;
/** longest received scope mask since track_max_scope is set. This value
* is used for caching and answereing to client. */
uint8_t max_scope;
/** has the subnet module been started with no_cache_store? */ /** has the subnet module been started with no_cache_store? */
int started_no_cache_store; int started_no_cache_store;
}; };

0
ipset/ipset.c Executable file → Normal file
View file

0
ipset/ipset.h Executable file → Normal file
View file

View file

@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
} }
for(a = dp->target_list; a; a = a->next_target) { for(a = dp->target_list; a; a = a->next_target) {
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
a->bogus, a->lame, a->tls_auth_name)) a->bogus, a->lame, a->tls_auth_name, NULL))
return NULL; return NULL;
} }
return copy; return copy;
@ -161,7 +161,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
int int
delegpt_add_target(struct delegpt* dp, struct regional* region, delegpt_add_target(struct delegpt* dp, struct regional* region,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr, uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t bogus, uint8_t lame) socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions)
{ {
struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
log_assert(!dp->dp_type_mlc); log_assert(!dp->dp_type_mlc);
@ -176,13 +176,14 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
if(ns->got4 && ns->got6) if(ns->got4 && ns->got6)
ns->resolved = 1; ns->resolved = 1;
} }
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL); return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL,
additions);
} }
int int
delegpt_add_addr(struct delegpt* dp, struct regional* region, delegpt_add_addr(struct delegpt* dp, struct regional* region,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
uint8_t lame, char* tls_auth_name) uint8_t lame, char* tls_auth_name, int* additions)
{ {
struct delegpt_addr* a; struct delegpt_addr* a;
log_assert(!dp->dp_type_mlc); log_assert(!dp->dp_type_mlc);
@ -194,6 +195,8 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
a->lame = 0; a->lame = 0;
return 1; return 1;
} }
if(additions)
*additions = 1;
a = (struct delegpt_addr*)regional_alloc(region, a = (struct delegpt_addr*)regional_alloc(region,
sizeof(struct delegpt_addr)); sizeof(struct delegpt_addr));
@ -382,10 +385,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
continue; continue;
if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) { if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) {
if(!delegpt_add_rrset_A(dp, region, s, 0)) if(!delegpt_add_rrset_A(dp, region, s, 0, NULL))
return NULL; return NULL;
} else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) { } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) {
if(!delegpt_add_rrset_AAAA(dp, region, s, 0)) if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL))
return NULL; return NULL;
} }
} }
@ -416,7 +419,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
int int
delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* ak, uint8_t lame) struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
{ {
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
size_t i; size_t i;
@ -432,7 +435,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE); memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);
if(!delegpt_add_target(dp, region, ak->rk.dname, if(!delegpt_add_target(dp, region, ak->rk.dname,
ak->rk.dname_len, (struct sockaddr_storage*)&sa, ak->rk.dname_len, (struct sockaddr_storage*)&sa,
len, (d->security==sec_status_bogus), lame)) len, (d->security==sec_status_bogus), lame, additions))
return 0; return 0;
} }
return 1; return 1;
@ -440,7 +443,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
int int
delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* ak, uint8_t lame) struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
{ {
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
size_t i; size_t i;
@ -456,7 +459,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE); memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);
if(!delegpt_add_target(dp, region, ak->rk.dname, if(!delegpt_add_target(dp, region, ak->rk.dname,
ak->rk.dname_len, (struct sockaddr_storage*)&sa, ak->rk.dname_len, (struct sockaddr_storage*)&sa,
len, (d->security==sec_status_bogus), lame)) len, (d->security==sec_status_bogus), lame, additions))
return 0; return 0;
} }
return 1; return 1;
@ -464,20 +467,33 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
int int
delegpt_add_rrset(struct delegpt* dp, struct regional* region, delegpt_add_rrset(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* rrset, uint8_t lame) struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions)
{ {
if(!rrset) if(!rrset)
return 1; return 1;
if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS) if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
return delegpt_rrset_add_ns(dp, region, rrset, lame); return delegpt_rrset_add_ns(dp, region, rrset, lame);
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A) else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
return delegpt_add_rrset_A(dp, region, rrset, lame); return delegpt_add_rrset_A(dp, region, rrset, lame, additions);
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA) else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
return delegpt_add_rrset_AAAA(dp, region, rrset, lame); return delegpt_add_rrset_AAAA(dp, region, rrset, lame,
additions);
log_warn("Unknown rrset type added to delegpt"); log_warn("Unknown rrset type added to delegpt");
return 1; return 1;
} }
void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype)
{
if(ns) {
if(qtype == LDNS_RR_TYPE_A)
ns->got4 = 2;
else if(qtype == LDNS_RR_TYPE_AAAA)
ns->got6 = 2;
if(ns->got4 && ns->got6)
ns->resolved = 1;
}
}
void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
{ {
struct reply_info* rep = (struct reply_info*)msg->entry.data; struct reply_info* rep = (struct reply_info*)msg->entry.data;
@ -487,14 +503,7 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) { if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {
struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname,
msg->key.qname_len); msg->key.qname_len);
if(ns) { delegpt_mark_neg(ns, msg->key.qtype);
if(msg->key.qtype == LDNS_RR_TYPE_A)
ns->got4 = 1;
else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)
ns->got6 = 1;
if(ns->got4 && ns->got6)
ns->resolved = 1;
}
} }
} }

View file

@ -106,9 +106,10 @@ struct delegpt_ns {
* and marked true if got4 and got6 are both true. * and marked true if got4 and got6 are both true.
*/ */
int resolved; int resolved;
/** if the ipv4 address is in the delegpt */ /** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative,
* negative means it was done, but no content. */
uint8_t got4; uint8_t got4;
/** if the ipv6 address is in the delegpt */ /** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */
uint8_t got6; uint8_t got6;
/** /**
* If the name is parent-side only and thus dispreferred. * If the name is parent-side only and thus dispreferred.
@ -215,11 +216,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
* @param addrlen: the length of addr. * @param addrlen: the length of addr.
* @param bogus: security status for the address, pass true if bogus. * @param bogus: security status for the address, pass true if bogus.
* @param lame: address is lame. * @param lame: address is lame.
* @param additions: will be set to 1 if a new address is added
* @return false on error. * @return false on error.
*/ */
int delegpt_add_target(struct delegpt* dp, struct regional* regional, int delegpt_add_target(struct delegpt* dp, struct regional* regional,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr, uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t bogus, uint8_t lame); socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions);
/** /**
* Add A RRset to delegpt. * Add A RRset to delegpt.
@ -227,10 +229,11 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional,
* @param regional: where to allocate the info. * @param regional: where to allocate the info.
* @param rrset: RRset A to add. * @param rrset: RRset A to add.
* @param lame: rrset is lame, disprefer it. * @param lame: rrset is lame, disprefer it.
* @param additions: will be set to 1 if a new address is added
* @return 0 on alloc error. * @return 0 on alloc error.
*/ */
int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* rrset, uint8_t lame); struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
/** /**
* Add AAAA RRset to delegpt. * Add AAAA RRset to delegpt.
@ -238,10 +241,11 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
* @param regional: where to allocate the info. * @param regional: where to allocate the info.
* @param rrset: RRset AAAA to add. * @param rrset: RRset AAAA to add.
* @param lame: rrset is lame, disprefer it. * @param lame: rrset is lame, disprefer it.
* @param additions: will be set to 1 if a new address is added
* @return 0 on alloc error. * @return 0 on alloc error.
*/ */
int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* rrset, uint8_t lame); struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
/** /**
* Add any RRset to delegpt. * Add any RRset to delegpt.
@ -250,10 +254,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
* @param regional: where to allocate the info. * @param regional: where to allocate the info.
* @param rrset: RRset to add, NS, A, AAAA. * @param rrset: RRset to add, NS, A, AAAA.
* @param lame: rrset is lame, disprefer it. * @param lame: rrset is lame, disprefer it.
* @param additions: will be set to 1 if a new address is added
* @return 0 on alloc error. * @return 0 on alloc error.
*/ */
int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* rrset, uint8_t lame); struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
/** /**
* Add address to the delegation point. No servername is associated or checked. * Add address to the delegation point. No servername is associated or checked.
@ -264,11 +269,12 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
* @param bogus: if address is bogus. * @param bogus: if address is bogus.
* @param lame: if address is lame. * @param lame: if address is lame.
* @param tls_auth_name: TLS authentication name (or NULL). * @param tls_auth_name: TLS authentication name (or NULL).
* @param additions: will be set to 1 if a new address is added
* @return false on error. * @return false on error.
*/ */
int delegpt_add_addr(struct delegpt* dp, struct regional* regional, int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
struct sockaddr_storage* addr, socklen_t addrlen, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t bogus, uint8_t lame, char* tls_auth_name); uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions);
/** /**
* Find NS record in name list of delegation point. * Find NS record in name list of delegation point.
@ -341,6 +347,14 @@ size_t delegpt_count_targets(struct delegpt* dp);
struct delegpt* delegpt_from_message(struct dns_msg* msg, struct delegpt* delegpt_from_message(struct dns_msg* msg,
struct regional* regional); struct regional* regional);
/**
* Mark negative return in delegation point for specific nameserver.
* sets the got4 or got6 to negative, updates the ns->resolved.
* @param ns: the nameserver in the delegpt.
* @param qtype: A or AAAA (host order).
*/
void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype);
/** /**
* Add negative message to delegation point. * Add negative message to delegation point.
* @param dp: delegation point. * @param dp: delegation point.

View file

@ -185,8 +185,9 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,
/** Get target name of a CNAME */ /** Get target name of a CNAME */
static int static int
parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
size_t* snamelen) size_t* snamelen, sldns_buffer* pkt)
{ {
size_t oldpos, dlen;
if(rrset->rr_count != 1) { if(rrset->rr_count != 1) {
struct rr_parse* sig; struct rr_parse* sig;
verbose(VERB_ALGO, "Found CNAME rrset with " verbose(VERB_ALGO, "Found CNAME rrset with "
@ -204,6 +205,19 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
*sname = rrset->rr_first->ttl_data + sizeof(uint32_t) *sname = rrset->rr_first->ttl_data + sizeof(uint32_t)
+ sizeof(uint16_t); /* skip ttl, rdatalen */ + sizeof(uint16_t); /* skip ttl, rdatalen */
*snamelen = rrset->rr_first->size - sizeof(uint16_t); *snamelen = rrset->rr_first->size - sizeof(uint16_t);
if(rrset->rr_first->outside_packet) {
if(!dname_valid(*sname, *snamelen))
return 0;
return 1;
}
oldpos = sldns_buffer_position(pkt);
sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt)));
dlen = pkt_dname_len(pkt);
sldns_buffer_set_position(pkt, oldpos);
if(dlen == 0)
return 0; /* parse fail on the rdata name */
*snamelen = dlen;
return 1; return 1;
} }
@ -215,7 +229,7 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
/* we already know that sname is a strict subdomain of DNAME owner */ /* we already know that sname is a strict subdomain of DNAME owner */
uint8_t* dtarg = NULL; uint8_t* dtarg = NULL;
size_t dtarglen; size_t dtarglen;
if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen)) if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt))
return 0; return 0;
if(qnamelen <= dname_rrset->dname_len) if(qnamelen <= dname_rrset->dname_len)
return 0; return 0;
@ -388,7 +402,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
/* check next cname */ /* check next cname */
uint8_t* t = NULL; uint8_t* t = NULL;
size_t tlen = 0; size_t tlen = 0;
if(!parse_get_cname_target(nx, &t, &tlen)) if(!parse_get_cname_target(nx, &t, &tlen, pkt))
return 0; return 0;
if(dname_pkt_compare(pkt, alias, t) == 0) { if(dname_pkt_compare(pkt, alias, t) == 0) {
/* it's OK and better capitalized */ /* it's OK and better capitalized */
@ -439,7 +453,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
size_t tlen = 0; size_t tlen = 0;
if(synth_cname(sname, snamelen, nx, alias, if(synth_cname(sname, snamelen, nx, alias,
&aliaslen, pkt) && &aliaslen, pkt) &&
parse_get_cname_target(rrset, &t, &tlen) && parse_get_cname_target(rrset, &t, &tlen, pkt) &&
dname_pkt_compare(pkt, alias, t) == 0) { dname_pkt_compare(pkt, alias, t) == 0) {
/* the synthesized CNAME equals the /* the synthesized CNAME equals the
* current CNAME. This CNAME is the * current CNAME. This CNAME is the
@ -460,7 +474,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
} }
/* move to next name in CNAME chain */ /* move to next name in CNAME chain */
if(!parse_get_cname_target(rrset, &sname, &snamelen)) if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt))
return 0; return 0;
prev = rrset; prev = rrset;
rrset = rrset->rrset_all_next; rrset = rrset->rrset_all_next;

View file

@ -1199,7 +1199,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
log_rrset_key(VERB_ALGO, "found parent-side", akey); log_rrset_key(VERB_ALGO, "found parent-side", akey);
ns->done_pside4 = 1; ns->done_pside4 = 1;
/* a negative-cache-element has no addresses it adds */ /* a negative-cache-element has no addresses it adds */
if(!delegpt_add_rrset_A(dp, region, akey, 1)) if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL))
log_err("malloc failure in lookup_parent_glue"); log_err("malloc failure in lookup_parent_glue");
lock_rw_unlock(&akey->entry.lock); lock_rw_unlock(&akey->entry.lock);
} }
@ -1211,7 +1211,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
log_rrset_key(VERB_ALGO, "found parent-side", akey); log_rrset_key(VERB_ALGO, "found parent-side", akey);
ns->done_pside6 = 1; ns->done_pside6 = 1;
/* a negative-cache-element has no addresses it adds */ /* a negative-cache-element has no addresses it adds */
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1)) if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL))
log_err("malloc failure in lookup_parent_glue"); log_err("malloc failure in lookup_parent_glue");
lock_rw_unlock(&akey->entry.lock); lock_rw_unlock(&akey->entry.lock);
} }

View file

@ -72,6 +72,8 @@
/* in msec */ /* in msec */
int UNKNOWN_SERVER_NICENESS = 376; int UNKNOWN_SERVER_NICENESS = 376;
static void target_count_increase_nx(struct iter_qstate* iq, int num);
int int
iter_setup(struct module_env* env, int id) iter_setup(struct module_env* env, int id)
{ {
@ -150,6 +152,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->sent_count = 0; iq->sent_count = 0;
iq->ratelimit_ok = 0; iq->ratelimit_ok = 0;
iq->target_count = NULL; iq->target_count = NULL;
iq->dp_target_count = 0;
iq->wait_priming_stub = 0; iq->wait_priming_stub = 0;
iq->refetch_glue = 0; iq->refetch_glue = 0;
iq->dnssec_expected = 0; iq->dnssec_expected = 0;
@ -221,6 +224,7 @@ final_state(struct iter_qstate* iq)
static void static void
error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
{ {
struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id]; struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A || if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
@ -246,7 +250,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
super->region, super_iq->dp)) super->region, super_iq->dp))
log_err("out of memory adding missing"); log_err("out of memory adding missing");
} }
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
dpns->resolved = 1; /* mark as failed */ dpns->resolved = 1; /* mark as failed */
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
(dpns->got6 == 2 || !ie->supports_ipv6))
target_count_increase_nx(super_iq, 1);
} }
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) { if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
/* prime failed to get delegation */ /* prime failed to get delegation */
@ -621,7 +629,7 @@ static void
target_count_create(struct iter_qstate* iq) target_count_create(struct iter_qstate* iq)
{ {
if(!iq->target_count) { if(!iq->target_count) {
iq->target_count = (int*)calloc(2, sizeof(int)); iq->target_count = (int*)calloc(3, sizeof(int));
/* if calloc fails we simply do not track this number */ /* if calloc fails we simply do not track this number */
if(iq->target_count) if(iq->target_count)
iq->target_count[0] = 1; iq->target_count[0] = 1;
@ -634,6 +642,15 @@ target_count_increase(struct iter_qstate* iq, int num)
target_count_create(iq); target_count_create(iq);
if(iq->target_count) if(iq->target_count)
iq->target_count[1] += num; iq->target_count[1] += num;
iq->dp_target_count++;
}
static void
target_count_increase_nx(struct iter_qstate* iq, int num)
{
target_count_create(iq);
if(iq->target_count)
iq->target_count[2] += num;
} }
/** /**
@ -656,13 +673,15 @@ target_count_increase(struct iter_qstate* iq, int num)
* @param subq_ret: if newly allocated, the subquerystate, or NULL if it does * @param subq_ret: if newly allocated, the subquerystate, or NULL if it does
* not need initialisation. * not need initialisation.
* @param v: if true, validation is done on the subquery. * @param v: if true, validation is done on the subquery.
* @param detached: true if this qstate should not attach to the subquery
* @return false on error (malloc). * @return false on error (malloc).
*/ */
static int static int
generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
uint16_t qclass, struct module_qstate* qstate, int id, uint16_t qclass, struct module_qstate* qstate, int id,
struct iter_qstate* iq, enum iter_state initial_state, struct iter_qstate* iq, enum iter_state initial_state,
enum iter_state finalstate, struct module_qstate** subq_ret, int v) enum iter_state finalstate, struct module_qstate** subq_ret, int v,
int detached)
{ {
struct module_qstate* subq = NULL; struct module_qstate* subq = NULL;
struct iter_qstate* subiq = NULL; struct iter_qstate* subiq = NULL;
@ -689,11 +708,23 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
valrec = 1; valrec = 1;
} }
/* attach subquery, lookup existing or make a new one */ if(detached) {
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); struct mesh_state* sub = NULL;
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, fptr_ok(fptr_whitelist_modenv_add_sub(
&subq)) { qstate->env->add_sub));
return 0; if(!(*qstate->env->add_sub)(qstate, &qinf,
qflags, prime, valrec, &subq, &sub)){
return 0;
}
}
else {
/* attach subquery, lookup existing or make a new one */
fptr_ok(fptr_whitelist_modenv_attach_sub(
qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
valrec, &subq)) {
return 0;
}
} }
*subq_ret = subq; *subq_ret = subq;
if(subq) { if(subq) {
@ -716,6 +747,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
subiq->target_count = iq->target_count; subiq->target_count = iq->target_count;
if(iq->target_count) if(iq->target_count)
iq->target_count[0] ++; /* extra reference */ iq->target_count[0] ++; /* extra reference */
subiq->dp_target_count = 0;
subiq->num_current_queries = 0; subiq->num_current_queries = 0;
subiq->depth = iq->depth+1; subiq->depth = iq->depth+1;
outbound_list_init(&subiq->outlist); outbound_list_init(&subiq->outlist);
@ -759,7 +791,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id,
* the normal INIT state logic (which would cause an infloop). */ * the normal INIT state logic (which would cause an infloop). */
if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS, if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS,
qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE, qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE,
&subq, 0)) { &subq, 0, 0)) {
verbose(VERB_ALGO, "could not prime root"); verbose(VERB_ALGO, "could not prime root");
return 0; return 0;
} }
@ -850,7 +882,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
* redundant INIT state processing. */ * redundant INIT state processing. */
if(!generate_sub_request(stub_dp->name, stub_dp->namelen, if(!generate_sub_request(stub_dp->name, stub_dp->namelen,
LDNS_RR_TYPE_NS, qclass, qstate, id, iq, LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) { QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) {
verbose(VERB_ALGO, "could not prime stub"); verbose(VERB_ALGO, "could not prime stub");
errinf(qstate, "could not generate lookup for stub prime"); errinf(qstate, "could not generate lookup for stub prime");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
@ -1025,7 +1057,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq,
if(!generate_sub_request(s->rk.dname, s->rk.dname_len, if(!generate_sub_request(s->rk.dname, s->rk.dname_len,
ntohs(s->rk.type), ntohs(s->rk.rrset_class), ntohs(s->rk.type), ntohs(s->rk.rrset_class),
qstate, id, iq, qstate, id, iq,
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
verbose(VERB_ALGO, "could not generate addr check"); verbose(VERB_ALGO, "could not generate addr check");
return; return;
} }
@ -1069,7 +1101,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass); iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
if(!generate_sub_request(iq->dp->name, iq->dp->namelen, if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq, LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
verbose(VERB_ALGO, "could not generate ns check"); verbose(VERB_ALGO, "could not generate ns check");
return; return;
} }
@ -1126,7 +1158,7 @@ generate_dnskey_prefetch(struct module_qstate* qstate,
iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass); iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass);
if(!generate_sub_request(iq->dp->name, iq->dp->namelen, if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq,
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) { INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
/* we'll be slower, but it'll work */ /* we'll be slower, but it'll work */
verbose(VERB_ALGO, "could not generate dnskey prefetch"); verbose(VERB_ALGO, "could not generate dnskey prefetch");
return; return;
@ -1315,6 +1347,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->refetch_glue = 0; iq->refetch_glue = 0;
iq->query_restart_count++; iq->query_restart_count++;
iq->sent_count = 0; iq->sent_count = 0;
iq->dp_target_count = 0;
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region); sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
if(qstate->env->cfg->qname_minimisation) if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE; iq->minimisation_state = INIT_MINIMISE_STATE;
@ -1693,7 +1726,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
{ {
struct module_qstate* subq; struct module_qstate* subq;
if(!generate_sub_request(name, namelen, qtype, qclass, qstate, if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
return 0; return 0;
if(subq) { if(subq) {
struct iter_qstate* subiq = struct iter_qstate* subiq =
@ -1744,7 +1777,7 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,
{ {
struct module_qstate* subq; struct module_qstate* subq;
if(!generate_sub_request(name, namelen, qtype, qclass, qstate, if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
return 0; return 0;
log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass); log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);
return 1; return 1;
@ -1783,6 +1816,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
"number of glue fetches %d", s, iq->target_count[1]); "number of glue fetches %d", s, iq->target_count[1]);
return 0; return 0;
} }
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
char s[LDNS_MAX_DOMAINLEN+1];
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d to a single delegation point",
s, iq->dp_target_count);
return 0;
}
iter_mark_cycle_targets(qstate, iq->dp); iter_mark_cycle_targets(qstate, iq->dp);
missing = (int)delegpt_count_missing_targets(iq->dp); missing = (int)delegpt_count_missing_targets(iq->dp);
@ -1896,7 +1937,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
for(a = p->target_list; a; a=a->next_target) { for(a = p->target_list; a; a=a->next_target) {
(void)delegpt_add_addr(iq->dp, qstate->region, (void)delegpt_add_addr(iq->dp, qstate->region,
&a->addr, a->addrlen, a->bogus, &a->addr, a->addrlen, a->bogus,
a->lame, a->tls_auth_name); a->lame, a->tls_auth_name, NULL);
} }
} }
iq->dp->has_parent_side_NS = 1; iq->dp->has_parent_side_NS = 1;
@ -1913,6 +1954,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
iq->refetch_glue = 1; iq->refetch_glue = 1;
iq->query_restart_count++; iq->query_restart_count++;
iq->sent_count = 0; iq->sent_count = 0;
iq->dp_target_count = 0;
if(qstate->env->cfg->qname_minimisation) if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE; iq->minimisation_state = INIT_MINIMISE_STATE;
return next_state(iq, INIT_REQUEST_STATE); return next_state(iq, INIT_REQUEST_STATE);
@ -2078,7 +2120,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
iq->dsns_point, LDNS_RR_TYPE_NS, iq->qchase.qclass); iq->dsns_point, LDNS_RR_TYPE_NS, iq->qchase.qclass);
if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len, if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len,
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq, LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) { INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
errinf_dname(qstate, "for DS query parent-child nameserver search, could not generate NS lookup for", iq->dsns_point); errinf_dname(qstate, "for DS query parent-child nameserver search, could not generate NS lookup for", iq->dsns_point);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
} }
@ -2136,6 +2178,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
errinf(qstate, "exceeded the maximum number of sends"); errinf(qstate, "exceeded the maximum number of sends");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
} }
if(iq->target_count && iq->target_count[2] > MAX_TARGET_NX) {
verbose(VERB_QUERY, "request has exceeded the maximum "
" number of nxdomain nameserver lookups with %d",
iq->target_count[2]);
errinf(qstate, "exceeded the maximum nameserver nxdomains");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* Make sure we have a delegation point, otherwise priming failed /* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */ * or another failure occurred */
@ -2240,12 +2289,41 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qinfo_out.qtype, iq->qinfo_out.qclass, iq->qinfo_out.qtype, iq->qinfo_out.qclass,
qstate->query_flags, qstate->region, qstate->query_flags, qstate->region,
qstate->env->scratch, 0); qstate->env->scratch, 0);
if(msg && msg->rep->an_numrrsets == 0 if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
&& FLAGS_GET_RCODE(msg->rep->flags) ==
LDNS_RCODE_NOERROR) LDNS_RCODE_NOERROR)
/* no need to send query if it is already /* no need to send query if it is already
* cached as NOERROR/NODATA */ * cached as NOERROR */
return 1; return 1;
if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
LDNS_RCODE_NXDOMAIN &&
qstate->env->need_to_validate &&
qstate->env->cfg->harden_below_nxdomain) {
if(msg->rep->security == sec_status_secure) {
iq->response = msg;
return final_state(iq);
}
if(msg->rep->security == sec_status_unchecked) {
struct module_qstate* subq = NULL;
if(!generate_sub_request(
iq->qinfo_out.qname,
iq->qinfo_out.qname_len,
iq->qinfo_out.qtype,
iq->qinfo_out.qclass,
qstate, id, iq,
INIT_REQUEST_STATE,
FINISHED_STATE, &subq, 1, 1))
verbose(VERB_ALGO,
"could not validate NXDOMAIN "
"response");
}
}
if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
LDNS_RCODE_NXDOMAIN) {
/* return and add a label in the next
* minimisation iteration.
*/
return 1;
}
} }
} }
if(iq->minimisation_state == SKIP_MINIMISE_STATE) { if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
@ -2321,6 +2399,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* generated query will immediately be discarded due to depth and * generated query will immediately be discarded due to depth and
* that servfail is cached, which is not good as opportunism goes. */ * that servfail is cached, which is not good as opportunism goes. */
if(iq->depth < ie->max_dependency_depth if(iq->depth < ie->max_dependency_depth
&& iq->num_target_queries == 0
&& (!iq->target_count || iq->target_count[2]==0)
&& iq->sent_count < TARGET_FETCH_STOP) { && iq->sent_count < TARGET_FETCH_STOP) {
tf_policy = ie->target_fetch_policy[iq->depth]; tf_policy = ie->target_fetch_policy[iq->depth];
} }
@ -2366,6 +2446,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_current_queries++; /* RespState decrements it*/ iq->num_current_queries++; /* RespState decrements it*/
iq->referral_count++; /* make sure we don't loop */ iq->referral_count++; /* make sure we don't loop */
iq->sent_count = 0; iq->sent_count = 0;
iq->dp_target_count = 0;
iq->state = QUERY_RESP_STATE; iq->state = QUERY_RESP_STATE;
return 1; return 1;
} }
@ -2453,6 +2534,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_current_queries++; /* RespState decrements it*/ iq->num_current_queries++; /* RespState decrements it*/
iq->referral_count++; /* make sure we don't loop */ iq->referral_count++; /* make sure we don't loop */
iq->sent_count = 0; iq->sent_count = 0;
iq->dp_target_count = 0;
iq->state = QUERY_RESP_STATE; iq->state = QUERY_RESP_STATE;
return 1; return 1;
} }
@ -2748,7 +2830,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* Make subrequest to validate intermediate /* Make subrequest to validate intermediate
* NXDOMAIN if harden-below-nxdomain is * NXDOMAIN if harden-below-nxdomain is
* enabled. */ * enabled. */
if(qstate->env->cfg->harden_below_nxdomain) { if(qstate->env->cfg->harden_below_nxdomain &&
qstate->env->need_to_validate) {
struct module_qstate* subq = NULL; struct module_qstate* subq = NULL;
log_query_info(VERB_QUERY, log_query_info(VERB_QUERY,
"schedule NXDOMAIN validation:", "schedule NXDOMAIN validation:",
@ -2760,16 +2843,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response->qinfo.qclass, iq->response->qinfo.qclass,
qstate, id, iq, qstate, id, iq,
INIT_REQUEST_STATE, INIT_REQUEST_STATE,
FINISHED_STATE, &subq, 1)) FINISHED_STATE, &subq, 1, 1))
verbose(VERB_ALGO, verbose(VERB_ALGO,
"could not validate NXDOMAIN " "could not validate NXDOMAIN "
"response"); "response");
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
fptr_ok(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
} }
} }
return next_state(iq, QUERYTARGETS_STATE); return next_state(iq, QUERYTARGETS_STATE);
@ -2853,6 +2930,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* Count this as a referral. */ /* Count this as a referral. */
iq->referral_count++; iq->referral_count++;
iq->sent_count = 0; iq->sent_count = 0;
iq->dp_target_count = 0;
/* see if the next dp is a trust anchor, or a DS was sent /* see if the next dp is a trust anchor, or a DS was sent
* along, indicating dnssec is expected for next zone */ * along, indicating dnssec is expected for next zone */
iq->dnssec_expected = iter_indicates_dnssec(qstate->env, iq->dnssec_expected = iter_indicates_dnssec(qstate->env,
@ -2929,6 +3007,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dsns_point = NULL; iq->dsns_point = NULL;
iq->auth_zone_response = 0; iq->auth_zone_response = 0;
iq->sent_count = 0; iq->sent_count = 0;
iq->dp_target_count = 0;
if(iq->minimisation_state != MINIMISE_STATE) if(iq->minimisation_state != MINIMISE_STATE)
/* Only count as query restart when it is not an extra /* Only count as query restart when it is not an extra
* query as result of qname minimisation. */ * query as result of qname minimisation. */
@ -3112,7 +3191,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
/* validate the root or stub after priming (if enabled). /* validate the root or stub after priming (if enabled).
* This is the same query as the prime query, but with validation. * This is the same query as the prime query, but with validation.
* Now that we are primed, the additional queries that validation * Now that we are primed, the additional queries that validation
* may need can be resolved, such as DLV. */ * may need can be resolved. */
if(qstate->env->cfg->harden_referral_path) { if(qstate->env->cfg->harden_referral_path) {
struct module_qstate* subq = NULL; struct module_qstate* subq = NULL;
log_nametypeclass(VERB_ALGO, "schedule prime validation", log_nametypeclass(VERB_ALGO, "schedule prime validation",
@ -3121,7 +3200,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
if(!generate_sub_request(qstate->qinfo.qname, if(!generate_sub_request(qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype, qstate->qinfo.qname_len, qstate->qinfo.qtype,
qstate->qinfo.qclass, qstate, id, iq, qstate->qinfo.qclass, qstate, id, iq,
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
verbose(VERB_ALGO, "could not generate prime check"); verbose(VERB_ALGO, "could not generate prime check");
} }
generate_a_aaaa_check(qstate, iq, id); generate_a_aaaa_check(qstate, iq, id);
@ -3149,6 +3228,7 @@ static void
processTargetResponse(struct module_qstate* qstate, int id, processTargetResponse(struct module_qstate* qstate, int id,
struct module_qstate* forq) struct module_qstate* forq)
{ {
struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id]; struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
struct ub_packed_rrset_key* rrset; struct ub_packed_rrset_key* rrset;
@ -3186,7 +3266,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
log_rrset_key(VERB_ALGO, "add parentside glue to dp", log_rrset_key(VERB_ALGO, "add parentside glue to dp",
iq->pside_glue); iq->pside_glue);
if(!delegpt_add_rrset(foriq->dp, forq->region, if(!delegpt_add_rrset(foriq->dp, forq->region,
iq->pside_glue, 1)) iq->pside_glue, 1, NULL))
log_err("out of memory adding pside glue"); log_err("out of memory adding pside glue");
} }
@ -3197,6 +3277,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
* response type was ANSWER. */ * response type was ANSWER. */
rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep); rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep);
if(rrset) { if(rrset) {
int additions = 0;
/* if CNAMEs have been followed - add new NS to delegpt. */ /* if CNAMEs have been followed - add new NS to delegpt. */
/* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */ /* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
if(!delegpt_find_ns(foriq->dp, rrset->rk.dname, if(!delegpt_find_ns(foriq->dp, rrset->rk.dname,
@ -3208,13 +3289,23 @@ processTargetResponse(struct module_qstate* qstate, int id,
} }
/* if dpns->lame then set the address(es) lame too */ /* if dpns->lame then set the address(es) lame too */
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset, if(!delegpt_add_rrset(foriq->dp, forq->region, rrset,
dpns->lame)) dpns->lame, &additions))
log_err("out of memory adding targets"); log_err("out of memory adding targets");
if(!additions) {
/* no new addresses, increase the nxns counter, like
* this could be a list of wildcards with no new
* addresses */
target_count_increase_nx(foriq, 1);
}
verbose(VERB_ALGO, "added target response"); verbose(VERB_ALGO, "added target response");
delegpt_log(VERB_ALGO, foriq->dp); delegpt_log(VERB_ALGO, foriq->dp);
} else { } else {
verbose(VERB_ALGO, "iterator TargetResponse failed"); verbose(VERB_ALGO, "iterator TargetResponse failed");
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
dpns->resolved = 1; /* fail the target */ dpns->resolved = 1; /* fail the target */
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
(dpns->got6 == 2 || !ie->supports_ipv6))
target_count_increase_nx(foriq, 1);
} }
} }
@ -3388,7 +3479,7 @@ processCollectClass(struct module_qstate* qstate, int id)
qstate->qinfo.qname_len, qstate->qinfo.qtype, qstate->qinfo.qname_len, qstate->qinfo.qtype,
c, qstate, id, iq, INIT_REQUEST_STATE, c, qstate, id, iq, INIT_REQUEST_STATE,
FINISHED_STATE, &subq, FINISHED_STATE, &subq,
(int)!(qstate->query_flags&BIT_CD))) { (int)!(qstate->query_flags&BIT_CD), 0)) {
errinf(qstate, "could not generate class ANY" errinf(qstate, "could not generate class ANY"
" lookup query"); " lookup query");
return error_response(qstate, id, return error_response(qstate, id,

View file

@ -55,6 +55,11 @@ struct rbtree_type;
/** max number of targets spawned for a query and its subqueries */ /** max number of targets spawned for a query and its subqueries */
#define MAX_TARGET_COUNT 64 #define MAX_TARGET_COUNT 64
/** max number of target lookups per qstate, per delegation point */
#define MAX_DP_TARGET_COUNT 16
/** max number of nxdomains allowed for target lookups for a query and
* its subqueries */
#define MAX_TARGET_NX 5
/** max number of query restarts. Determines max number of CNAME chain. */ /** max number of query restarts. Determines max number of CNAME chain. */
#define MAX_RESTART_COUNT 8 #define MAX_RESTART_COUNT 8
/** max number of referrals. Makes sure resolver does not run away */ /** max number of referrals. Makes sure resolver does not run away */
@ -305,9 +310,14 @@ struct iter_qstate {
int sent_count; int sent_count;
/** number of target queries spawned in [1], for this query and its /** number of target queries spawned in [1], for this query and its
* subqueries, the malloced-array is shared, [0] refcount. */ * subqueries, the malloced-array is shared, [0] refcount.
* in [2] the number of nxdomains is counted. */
int* target_count; int* target_count;
/** number of target lookups per delegation point. Reset to 0 after
* receiving referral answer. Not shared with subqueries. */
int dp_target_count;
/** if true, already tested for ratelimiting and passed the test */ /** if true, already tested for ratelimiting and passed the test */
int ratelimit_ok; int ratelimit_ok;

View file

@ -50,6 +50,7 @@
#include "services/authzone.h" #include "services/authzone.h"
#include "util/data/msgreply.h" #include "util/data/msgreply.h"
#include "util/storage/slabhash.h" #include "util/storage/slabhash.h"
#include "util/edns.h"
#include "sldns/sbuffer.h" #include "sldns/sbuffer.h"
int int
@ -81,6 +82,8 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL; return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz)) if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz))
return UB_INITFAIL; return UB_INITFAIL;
if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg))
return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size, if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) { cfg->msg_cache_slabs)) {
slabhash_delete(ctx->env->msg_cache); slabhash_delete(ctx->env->msg_cache);

View file

@ -58,6 +58,7 @@
#include "util/net_help.h" #include "util/net_help.h"
#include "util/tube.h" #include "util/tube.h"
#include "util/ub_event.h" #include "util/ub_event.h"
#include "util/edns.h"
#include "services/modstack.h" #include "services/modstack.h"
#include "services/localzone.h" #include "services/localzone.h"
#include "services/cache/infra.h" #include "services/cache/infra.h"
@ -153,6 +154,18 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
ctx->env->edns_strings = edns_strings_create();
if(!ctx->env->edns_strings) {
auth_zones_delete(ctx->env->auth_zones);
edns_known_options_delete(ctx->env);
config_delete(ctx->env->cfg);
free(ctx->env);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
return NULL;
}
ctx->env->alloc = &ctx->superalloc; ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL; ctx->env->worker = NULL;
ctx->env->need_to_validate = 0; ctx->env->need_to_validate = 0;
@ -174,6 +187,7 @@ ub_ctx_create(void)
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
modstack_deinit(&ctx->mods, ctx->env); modstack_deinit(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
free(ctx->env); free(ctx->env);
free(ctx); free(ctx);
errno = e; errno = e;
@ -187,6 +201,7 @@ ub_ctx_create(void)
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
modstack_deinit(&ctx->mods, ctx->env); modstack_deinit(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
free(ctx->env); free(ctx->env);
free(ctx); free(ctx);
errno = e; errno = e;
@ -326,6 +341,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache); infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
auth_zones_delete(ctx->env->auth_zones); auth_zones_delete(ctx->env->auth_zones);
free(ctx->env); free(ctx->env);
} }

View file

@ -73,12 +73,15 @@
#include "iterator/iter_hints.h" #include "iterator/iter_hints.h"
#include "sldns/sbuffer.h" #include "sldns/sbuffer.h"
#include "sldns/str2wire.h" #include "sldns/str2wire.h"
#ifdef USE_DNSTAP
#include "dnstap/dtstream.h"
#endif
#ifdef HAVE_TARGETCONDITIONALS_H #ifdef HAVE_TARGETCONDITIONALS_H
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH) #if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
#undef HAVE_FORK #undef HAVE_FORK
#endif #endif
@ -238,7 +241,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
ports, numports, cfg->unwanted_threshold, ports, numports, cfg->unwanted_threshold,
cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w, cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx, cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
cfg->delay_close, cfg->tls_use_sni, NULL); cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect);
w->env->outnet = w->back; w->env->outnet = w->back;
if(!w->is_bg || w->is_bg_thread) { if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock); lock_basic_unlock(&ctx->cfglock);
@ -574,6 +577,7 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
edns->edns_version = 0; edns->edns_version = 0;
edns->bits = EDNS_DO; edns->bits = EDNS_DO;
edns->opt_list = NULL; edns->opt_list = NULL;
edns->padding_block_size = 0;
if(sldns_buffer_capacity(w->back->udp_buff) < 65535) if(sldns_buffer_capacity(w->back->udp_buff) < 65535)
edns->udp_size = (uint16_t)sldns_buffer_capacity( edns->udp_size = (uint16_t)sldns_buffer_capacity(
w->back->udp_buff); w->back->udp_buff);

View file

@ -642,6 +642,7 @@ struct ub_shm_stat_info {
long long respip; long long respip;
long long dnscrypt_shared_secret; long long dnscrypt_shared_secret;
long long dnscrypt_nonce; long long dnscrypt_nonce;
long long dynlib;
} mem; } mem;
}; };
@ -696,6 +697,8 @@ struct ub_server_stats {
long long qtcp_outgoing; long long qtcp_outgoing;
/** number of queries over (DNS over) TLS */ /** number of queries over (DNS over) TLS */
long long qtls; long long qtls;
/** number of queries over (DNS over) HTTPS */
long long qhttps;
/** number of queries over IPv6 */ /** number of queries over IPv6 */
long long qipv6; long long qipv6;
/** number of queries with QR bit */ /** number of queries with QR bit */
@ -786,6 +789,10 @@ struct ub_server_stats {
long long num_query_subnet_cache; long long num_query_subnet_cache;
/** number of bytes in the stream wait buffers */ /** number of bytes in the stream wait buffers */
long long mem_stream_wait; long long mem_stream_wait;
/** number of bytes in the HTTP2 query buffers */
long long mem_http2_query_buffer;
/** number of bytes in the HTTP2 response buffers */
long long mem_http2_response_buffer;
/** number of TLS connection resume */ /** number of TLS connection resume */
long long qtls_resume; long long qtls_resume;
/** RPZ action stats */ /** RPZ action stats */

View file

@ -412,6 +412,11 @@ if [ "$DOWIN" = "yes" ]; then
cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-control-setup.cmd ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt ../contrib/create_unbound_ad_servers.cmd ../contrib/warmup.cmd ../contrib/unbound_cache.cmd . cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-control-setup.cmd ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt ../contrib/create_unbound_ad_servers.cmd ../contrib/warmup.cmd ../contrib/unbound_cache.cmd .
mkdir libunbound mkdir libunbound
cp ../../unbound_shared/unbound.h ../../unbound_shared/.libs/libunbound*.dll ../../unbound_shared/.libs/libunbound.dll.a ../../unbound_shared/.libs/libunbound.a ../../unbound_shared/.libs/libunbound*.def ../../sslsharedinstall/lib/libcrypto.dll.a ../../sslsharedinstall/lib/libssl.dll.a ../../sslsharedinstall/bin/libcrypto*.dll ../../sslsharedinstall/bin/libssl*.dll ../../wxpinstall/bin/libexpat*.dll ../../wxpinstall/lib/libexpat.dll.a libunbound/. cp ../../unbound_shared/unbound.h ../../unbound_shared/.libs/libunbound*.dll ../../unbound_shared/.libs/libunbound.dll.a ../../unbound_shared/.libs/libunbound.a ../../unbound_shared/.libs/libunbound*.def ../../sslsharedinstall/lib/libcrypto.dll.a ../../sslsharedinstall/lib/libssl.dll.a ../../sslsharedinstall/bin/libcrypto*.dll ../../sslsharedinstall/bin/libssl*.dll ../../wxpinstall/bin/libexpat*.dll ../../wxpinstall/lib/libexpat.dll.a libunbound/.
if test "$W64" = "no"; then
cp /usr/i686-w64-mingw32/sys-root/mingw/bin/libssp-0.dll libunbound/.
else
cp /usr/x86_64-w64-mingw32/sys-root/mingw/bin/libssp-0.dll libunbound/.
fi
# zipfile # zipfile
zip -r ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog libunbound zip -r ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog libunbound
info "Testing $file" info "Testing $file"

View file

@ -60,7 +60,6 @@ The callback function's prototype is the following:
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh states.
:return: True on success, False on failure. :return: True on success, False on failure.
@ -105,8 +104,6 @@ The callback function's prototype is the following:
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.
@ -154,8 +151,6 @@ The callback function's prototype is the following:
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.
@ -201,8 +196,6 @@ The callback function's prototype is the following:
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.

View file

@ -256,14 +256,6 @@ config_file
Files with trusted DNSKEYs in named.conf format, list. Files with trusted DNSKEYs in named.conf format, list.
.. attribute:: dlv_anchor_file
DLV anchor file.
.. attribute:: dlv_anchor_list
DLV anchor inline.
.. attribute:: max_ttl .. attribute:: max_ttl
The number of seconds maximal TTL used for RRsets and messages. The number of seconds maximal TTL used for RRsets and messages.

View file

@ -89,7 +89,7 @@ EDNS options
Inplace callbacks Inplace callbacks
----------------- -----------------
.. function:: inplace_cb_reply(qinfo, qstate, rep, rcode, edns, opt_list_out, region) .. function:: inplace_cb_reply(qinfo, qstate, rep, rcode, edns, opt_list_out, region, \*\*kwargs)
Function prototype for callback functions used in Function prototype for callback functions used in
`register_inplace_cb_reply`_, `register_inplace_cb_reply_cache`_, `register_inplace_cb_reply`_, `register_inplace_cb_reply_cache`_,
@ -102,6 +102,9 @@ Inplace callbacks
:param edns: :class:`edns_data` :param edns: :class:`edns_data`
:param opt_list_out: :class:`edns_option`. EDNS option list to append options to. :param opt_list_out: :class:`edns_option`. EDNS option list to append options to.
:param region: :class:`regional` :param region: :class:`regional`
:param \*\*kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: :class:`comm_reply`. Reply information for a communication point.
.. function:: inplace_cb_query(qinfo, flags, qstate, addr, zone, region) .. function:: inplace_cb_query(qinfo, flags, qstate, addr, zone, region)

View file

@ -59,6 +59,8 @@
# | num-threads: 32 # | num-threads: 32
# | cache-max-negative-ttl: 60 # | cache-max-negative-ttl: 60
# | cache-max-ttl: 60 # | cache-max-ttl: 60
# | python:
# | python-script: path/to/this/file
# #
# #
# The plugin can also be run interactively. Provide the name and # The plugin can also be run interactively. Provide the name and

View file

@ -43,7 +43,7 @@
# This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is # This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is
# intentionally bogus. The reply will contain an empty EDNS option # intentionally bogus. The reply will contain an empty EDNS option
# with option code 65003. # with option code 65003.
# Unbound will also log the source address(es) of the client(s) that made # Unbound will also log the source address of the client that made
# the request. # the request.
# (unbound needs to be validating for this example to work) # (unbound needs to be validating for this example to work)
@ -91,8 +91,6 @@ def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.
@ -121,8 +119,6 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.
@ -173,8 +169,6 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.
@ -205,13 +199,11 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
:param **kwargs: Dictionary that may contain parameters added in a future :param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters: release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply). ``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure. :return: True on success, False on failure.
For demonstration purposes we want to reply with an empty EDNS code '65003' For demonstration purposes we want to reply with an empty EDNS code '65003'
and log the IP address(es) of the client(s). and log the IP address of the client.
""" """
log_info("python: called back while servfail.") log_info("python: called back while servfail.")
@ -219,30 +211,14 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
b = bytearray.fromhex("") b = bytearray.fromhex("")
edns_opt_list_append(opt_list_out, 65003, b, region) edns_opt_list_append(opt_list_out, 65003, b, region)
# Log the client(s) IP address(es) # Log the client's IP address
comm_reply = kwargs['repinfo'] comm_reply = kwargs['repinfo']
if comm_reply: if comm_reply:
# If it is not None this callback was called before the query reached
# the mesh states(modules). There is only one client associated with
# this query.
addr = comm_reply.addr addr = comm_reply.addr
port = comm_reply.port port = comm_reply.port
addr_family = comm_reply.family addr_family = comm_reply.family
log_info("python: Client IP: {}({}), port: {}" log_info("python: Client IP: {}({}), port: {}"
"".format(addr, addr_family, port)) "".format(addr, addr_family, port))
else:
# If it is not None this callback was called while the query is in the
# mesh states(modules). In this case they may be multiple clients
# waiting for this query.
# The following code is the same as with the resip.py example.
rl = qstate.mesh_info.reply_list
while (rl):
if rl.query_reply:
q = rl.query_reply
log_info("python: Client IP: {}({}), port: {}"
"".format(q.addr, q.family, q.port))
rl = rl.next
return True return True

View file

@ -20,6 +20,7 @@
* called to perform operations on queries. * called to perform operations on queries.
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <time.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
@ -314,16 +315,16 @@ struct packed_rrset_data {
class RRSetData_RRLen: class RRSetData_RRLen:
def __init__(self, obj): self.obj = obj def __init__(self, obj): self.obj = obj
def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index) def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index)
def __len__(self): return obj.count + obj.rrsig_count def __len__(self): return self.obj.count + self.obj.rrsig_count
class RRSetData_RRTTL: class RRSetData_RRTTL:
def __init__(self, obj): self.obj = obj def __init__(self, obj): self.obj = obj
def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index) def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index)
def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value) def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value)
def __len__(self): return obj.count + obj.rrsig_count def __len__(self): return self.obj.count + self.obj.rrsig_count
class RRSetData_RRData: class RRSetData_RRData:
def __init__(self, obj): self.obj = obj def __init__(self, obj): self.obj = obj
def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index) def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index)
def __len__(self): return obj.count + obj.rrsig_count def __len__(self): return self.obj.count + self.obj.rrsig_count
%} %}
%inline %{ %inline %{
@ -404,12 +405,12 @@ struct dns_msg {
class ReplyInfo_RRSet: class ReplyInfo_RRSet:
def __init__(self, obj): self.obj = obj def __init__(self, obj): self.obj = obj
def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index) def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index)
def __len__(self): return obj.rrset_count def __len__(self): return self.obj.rrset_count
class ReplyInfo_Ref: class ReplyInfo_Ref:
def __init__(self, obj): self.obj = obj def __init__(self, obj): self.obj = obj
def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index) def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index)
def __len__(self): return obj.rrset_count def __len__(self): return self.obj.rrset_count
%} %}
%inline %{ %inline %{
@ -696,6 +697,8 @@ struct edns_data {
/* ************************************************************************************ * /* ************************************************************************************ *
Structure module_env Structure module_env
* ************************************************************************************ */ * ************************************************************************************ */
%rename(_now) module_env::now;
%rename(_now_tv) module_env::now_tv;
struct module_env { struct module_env {
struct config_file* cfg; struct config_file* cfg;
struct slabhash* msg_cache; struct slabhash* msg_cache;
@ -739,6 +742,19 @@ struct module_env {
size_t edns_known_options_num; size_t edns_known_options_num;
}; };
%inline %{
PyObject* _module_env_now_get(struct module_env* env) {
double ts = env->now_tv->tv_sec + env->now_tv->tv_usec / 1e6;
return PyFloat_FromDouble(ts);
}
%}
%extend module_env {
%pythoncode %{
def _now_get(self): return _module_env_now_get(self)
now = property(_now_get)
%}
}
/* ************************************************************************************ * /* ************************************************************************************ *
Structure module_qstate Structure module_qstate
* ************************************************************************************ */ * ************************************************************************************ */
@ -992,8 +1008,6 @@ struct config_file {
struct config_strlist* trust_anchor_file_list; struct config_strlist* trust_anchor_file_list;
struct config_strlist* trust_anchor_list; struct config_strlist* trust_anchor_list;
struct config_strlist* trusted_keys_file_list; struct config_strlist* trusted_keys_file_list;
char* dlv_anchor_file;
struct config_strlist* dlv_anchor_list;
int max_ttl; int max_ttl;
int32_t val_date_override; int32_t val_date_override;
int bogus_ttl; int bogus_ttl;
@ -1415,6 +1429,19 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
/****************************** /******************************
* Various debugging functions * * Various debugging functions *
******************************/ ******************************/
/* rename the variadic functions because python does the formatting already*/
%rename (unbound_log_info) log_info;
%rename (unbound_log_err) log_err;
%rename (unbound_log_warn) log_warn;
%rename (unbound_verbose) verbose;
/* provide functions that take one string as argument, so python can cook
the string */
%rename (log_info) pymod_log_info;
%rename (log_warn) pymod_log_warn;
%rename (log_err) pymod_log_err;
%rename (verbose) pymod_verbose;
void verbose(enum verbosity_value level, const char* format, ...); void verbose(enum verbosity_value level, const char* format, ...);
void log_info(const char* format, ...); void log_info(const char* format, ...);
void log_err(const char* format, ...); void log_err(const char* format, ...);
@ -1424,6 +1451,19 @@ void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* r
void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf); void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
void regional_log_stats(struct regional *r); void regional_log_stats(struct regional *r);
/* the one argument string log functions */
void pymod_log_info(const char* str);
void pymod_log_err(const char* str);
void pymod_log_warn(const char* str);
void pymod_verbose(enum verbosity_value level, const char* str);
%{
void pymod_log_info(const char* str) { log_info("%s", str); }
void pymod_log_err(const char* str) { log_err("%s", str); }
void pymod_log_warn(const char* str) { log_warn("%s", str); }
void pymod_verbose(enum verbosity_value level, const char* str) {
verbose(level, "%s", str); }
%}
/*************************************************************************** /***************************************************************************
* Free allocated memory from marked sources returning corresponding types * * Free allocated memory from marked sources returning corresponding types *
***************************************************************************/ ***************************************************************************/
@ -1501,13 +1541,14 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
int python_inplace_cb_reply_generic(struct query_info* qinfo, int python_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode, struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out, struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region, int id, struct comm_reply* repinfo, struct regional* region,
void* python_callback) struct timeval* start_time, int id, void* python_callback)
{ {
PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo; PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
PyObject *py_rep, *py_repinfo, *py_region; PyObject *py_rep, *py_repinfo, *py_region;
PyObject *py_args, *py_kwargs, *result; PyObject *py_args, *py_kwargs, *result;
int res = 0; int res = 0;
double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6;
PyGILState_STATE gstate = PyGILState_Ensure(); PyGILState_STATE gstate = PyGILState_Ensure();
func = (PyObject *) python_callback; func = (PyObject *) python_callback;
@ -1522,7 +1563,8 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep, py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
rcode, py_edns, py_opt_list_out, py_region); rcode, py_edns, py_opt_list_out, py_region);
py_kwargs = Py_BuildValue("{s:O}", "repinfo", py_repinfo); py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time",
py_start_time);
result = PyObject_Call(func, py_args, py_kwargs); result = PyObject_Call(func, py_args, py_kwargs);
Py_XDECREF(py_edns); Py_XDECREF(py_edns);
Py_XDECREF(py_qstate); Py_XDECREF(py_qstate);

View file

@ -72,8 +72,8 @@ size_t pythonmod_get_mem(struct module_env* env, int id);
int python_inplace_cb_reply_generic(struct query_info* qinfo, int python_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode, struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out, struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region, int id, struct comm_reply* repinfo, struct regional* region,
void* python_callback); struct timeval* start_time, int id, void* python_callback);
/** Declared here for fptr_wlist access. The definition is in interface.i. */ /** Declared here for fptr_wlist access. The definition is in interface.i. */
int python_inplace_cb_query_generic( int python_inplace_cb_query_generic(

View file

@ -39,6 +39,7 @@
* conversions. * conversions.
*/ */
#include "config.h" #include "config.h"
#include "pythonmod/pythonmod_utils.h"
#include "util/module.h" #include "util/module.h"
#include "util/netevent.h" #include "util/netevent.h"
#include "util/net_help.h" #include "util/net_help.h"

View file

@ -43,6 +43,7 @@
#include "util/module.h" #include "util/module.h"
struct delegpt_addr; struct delegpt_addr;
struct sldns_buffer;
/** /**
* Store the reply_info and query_info pair in message cache (qstate->msg_cache) * Store the reply_info and query_info pair in message cache (qstate->msg_cache)
@ -77,7 +78,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin
* @param pkt: a sldns_buffer which contains sldns_packet data * @param pkt: a sldns_buffer which contains sldns_packet data
* @return 0 on failure, out of memory or parse error. * @return 0 on failure, out of memory or parse error.
*/ */
int createResponse(struct module_qstate* qstate, sldns_buffer* pkt); int createResponse(struct module_qstate* qstate, struct sldns_buffer* pkt);
/** /**
* Convert reply->addr to string * Convert reply->addr to string

View file

@ -523,7 +523,7 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
return NULL; /* guard against integer overflow */ return NULL; /* guard against integer overflow */
dsize += data->rr_len[i]; dsize += data->rr_len[i];
} }
d = regional_alloc(region, dsize); d = regional_alloc_zero(region, dsize);
if(!d) if(!d)
return NULL; return NULL;
*d = *data; *d = *data;
@ -914,7 +914,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
int ret = 1; int ret = 1;
struct ub_packed_rrset_key* redirect_rrset = NULL; struct ub_packed_rrset_key* redirect_rrset = NULL;
struct rpz* r; struct rpz* r;
struct auth_zone* a; struct auth_zone* a = NULL;
struct ub_packed_rrset_key* data = NULL; struct ub_packed_rrset_key* data = NULL;
int rpz_used = 0; int rpz_used = 0;
int rpz_log = 0; int rpz_log = 0;
@ -1109,7 +1109,7 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
qstate->return_msg && qstate->return_msg->rep) { qstate->return_msg && qstate->return_msg->rep) {
struct reply_info* new_rep = qstate->return_msg->rep; struct reply_info* new_rep = qstate->return_msg->rep;
struct ub_packed_rrset_key* alias_rrset = NULL; struct ub_packed_rrset_key* alias_rrset = NULL;
struct respip_action_info actinfo = {0}; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
actinfo.action = respip_none; actinfo.action = respip_none;
if(!respip_rewrite_reply(&qstate->qinfo, if(!respip_rewrite_reply(&qstate->qinfo,
@ -1170,7 +1170,7 @@ respip_merge_cname(struct reply_info* base_rep,
struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */ struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */
uint16_t tgt_rcode; uint16_t tgt_rcode;
size_t i, j; size_t i, j;
struct respip_action_info actinfo = {0}; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
actinfo.action = respip_none; actinfo.action = respip_none;
/* If the query for the CNAME target would result in an unusual rcode, /* If the query for the CNAME target would result in an unusual rcode,

View file

@ -1866,15 +1866,26 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
struct auth_xfer* x = NULL; struct auth_xfer* x = NULL;
/* create zone */ /* create zone */
if(c->isrpz) {
/* if the rpz lock is needed, grab it before the other
* locks to avoid a lock dependency cycle */
lock_rw_wrlock(&az->rpz_lock);
}
lock_rw_wrlock(&az->lock); lock_rw_wrlock(&az->lock);
if(!(z=auth_zones_find_or_add_zone(az, c->name))) { if(!(z=auth_zones_find_or_add_zone(az, c->name))) {
lock_rw_unlock(&az->lock); lock_rw_unlock(&az->lock);
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
return 0; return 0;
} }
if(c->masters || c->urls) { if(c->masters || c->urls) {
if(!(x=auth_zones_find_or_add_xfer(az, z))) { if(!(x=auth_zones_find_or_add_xfer(az, z))) {
lock_rw_unlock(&az->lock); lock_rw_unlock(&az->lock);
lock_rw_unlock(&z->lock); lock_rw_unlock(&z->lock);
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
return 0; return 0;
} }
} }
@ -1889,6 +1900,9 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
lock_basic_unlock(&x->lock); lock_basic_unlock(&x->lock);
} }
lock_rw_unlock(&z->lock); lock_rw_unlock(&z->lock);
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
return 0; return 0;
} }
z->for_downstream = c->for_downstream; z->for_downstream = c->for_downstream;
@ -1900,11 +1914,13 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
return 0; return 0;
} }
lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz)); lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz));
lock_rw_wrlock(&az->rpz_lock); /* the az->rpz_lock is locked above */
z->rpz_az_next = az->rpz_first; z->rpz_az_next = az->rpz_first;
if(az->rpz_first) if(az->rpz_first)
az->rpz_first->rpz_az_prev = z; az->rpz_first->rpz_az_prev = z;
az->rpz_first = z; az->rpz_first = z;
}
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock); lock_rw_unlock(&az->rpz_lock);
} }
@ -2315,7 +2331,8 @@ static int
az_add_negative_soa(struct auth_zone* z, struct regional* region, az_add_negative_soa(struct auth_zone* z, struct regional* region,
struct dns_msg* msg) struct dns_msg* msg)
{ {
uint32_t minimum; time_t minimum;
size_t i;
struct packed_rrset_data* d; struct packed_rrset_data* d;
struct auth_rrset* soa; struct auth_rrset* soa;
struct auth_data* apex = az_find_name(z, z->name, z->namelen); struct auth_data* apex = az_find_name(z, z->name, z->namelen);
@ -2332,9 +2349,11 @@ az_add_negative_soa(struct auth_zone* z, struct regional* region,
/* last 4 bytes are minimum ttl in network format */ /* last 4 bytes are minimum ttl in network format */
if(d->count == 0) return 0; if(d->count == 0) return 0;
if(d->rr_len[0] < 2+4) return 0; if(d->rr_len[0] < 2+4) return 0;
minimum = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-4)); minimum = (time_t)sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-4));
d->ttl = (time_t)minimum; minimum = d->ttl<minimum?d->ttl:minimum;
d->rr_ttl[0] = (time_t)minimum; d->ttl = minimum;
for(i=0; i < d->count + d->rrsig_count; i++)
d->rr_ttl[i] = minimum;
msg->rep->ttl = get_rrset_ttl(msg->rep->rrsets[0]); msg->rep->ttl = get_rrset_ttl(msg->rep->rrsets[0]);
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
@ -3270,7 +3289,7 @@ auth_answer_encode(struct query_info* qinfo, struct module_env* env,
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, msg->rep, if(!inplace_cb_reply_local_call(env, qinfo, NULL, msg->rep,
(int)FLAGS_GET_RCODE(msg->rep->flags), edns, repinfo, temp) (int)FLAGS_GET_RCODE(msg->rep->flags), edns, repinfo, temp, env->now_tv)
|| !reply_info_answer_encode(qinfo, msg->rep, || !reply_info_answer_encode(qinfo, msg->rep,
*(uint16_t*)sldns_buffer_begin(buf), *(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), sldns_buffer_read_u16_at(buf, 2),
@ -3294,7 +3313,7 @@ auth_error_encode(struct query_info* qinfo, struct module_env* env,
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL, if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
rcode, edns, repinfo, temp)) rcode, edns, repinfo, temp, env->now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(buf, rcode|BIT_AA, qinfo, error_encode(buf, rcode|BIT_AA, qinfo,
*(uint16_t*)sldns_buffer_begin(buf), *(uint16_t*)sldns_buffer_begin(buf),
@ -5091,6 +5110,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
edns.edns_version = 0; edns.edns_version = 0;
edns.bits = EDNS_DO; edns.bits = EDNS_DO;
edns.opt_list = NULL; edns.opt_list = NULL;
edns.padding_block_size = 0;
if(sldns_buffer_capacity(buf) < 65535) if(sldns_buffer_capacity(buf) < 65535)
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf); edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
else edns.udp_size = 65535; else edns.udp_size = 65535;
@ -5371,6 +5391,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
} }
} }
regional_free_all(temp);
} else { } else {
if(verbosity >= VERB_ALGO) { if(verbosity >= VERB_ALGO) {
char zname[255+1]; char zname[255+1];
@ -6076,7 +6097,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
/* send udp packet */ /* send udp packet */
if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer, if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
(struct sockaddr*)&addr, addrlen)) { (struct sockaddr*)&addr, addrlen, 0)) {
char zname[255+1], as[256]; char zname[255+1], as[256];
dname_str(xfr->name, zname); dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as)); addr_to_str(&addr, addrlen, as, sizeof(as));
@ -6278,6 +6299,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
edns.edns_version = 0; edns.edns_version = 0;
edns.bits = EDNS_DO; edns.bits = EDNS_DO;
edns.opt_list = NULL; edns.opt_list = NULL;
edns.padding_block_size = 0;
if(sldns_buffer_capacity(buf) < 65535) if(sldns_buffer_capacity(buf) < 65535)
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf); edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
else edns.udp_size = 65535; else edns.udp_size = 65535;
@ -6428,6 +6450,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
} }
} }
regional_free_all(temp);
} else { } else {
if(verbosity >= VERB_ALGO) { if(verbosity >= VERB_ALGO) {
char zname[255+1]; char zname[255+1];

15
services/cache/dns.c vendored
View file

@ -273,7 +273,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
akey = rrset_cache_lookup(env->rrset_cache, ns->name, akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(akey) { if(akey) {
if(!delegpt_add_rrset_A(dp, region, akey, 0)) { if(!delegpt_add_rrset_A(dp, region, akey, 0, NULL)) {
lock_rw_unlock(&akey->entry.lock); lock_rw_unlock(&akey->entry.lock);
return 0; return 0;
} }
@ -293,7 +293,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
akey = rrset_cache_lookup(env->rrset_cache, ns->name, akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
if(akey) { if(akey) {
if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) { if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, NULL)) {
lock_rw_unlock(&akey->entry.lock); lock_rw_unlock(&akey->entry.lock);
return 0; return 0;
} }
@ -327,7 +327,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
akey = rrset_cache_lookup(env->rrset_cache, ns->name, akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(akey) { if(akey) {
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) { if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
NULL)) {
lock_rw_unlock(&akey->entry.lock); lock_rw_unlock(&akey->entry.lock);
return 0; return 0;
} }
@ -347,7 +348,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
akey = rrset_cache_lookup(env->rrset_cache, ns->name, akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
if(akey) { if(akey) {
if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) { if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame,
NULL)) {
lock_rw_unlock(&akey->entry.lock); lock_rw_unlock(&akey->entry.lock);
return 0; return 0;
} }
@ -888,9 +890,8 @@ dns_cache_lookup(struct module_env* env,
lock_rw_unlock(&rrset->entry.lock); lock_rw_unlock(&rrset->entry.lock);
} }
/* construct DS, DNSKEY, DLV messages from rrset cache. */ /* construct DS, DNSKEY messages from rrset cache. */
if((qtype == LDNS_RR_TYPE_DS || qtype == LDNS_RR_TYPE_DNSKEY || if((qtype == LDNS_RR_TYPE_DS || qtype == LDNS_RR_TYPE_DNSKEY) &&
qtype == LDNS_RR_TYPE_DLV) &&
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen, (rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
qtype, qclass, 0, now, 0))) { qtype, qclass, 0, now, 0))) {
/* if the rrset is from the additional section, and the /* if the rrset is from the additional section, and the

View file

@ -244,6 +244,7 @@ infra_create(struct config_file* cfg)
return NULL; return NULL;
} }
infra->host_ttl = cfg->host_ttl; infra->host_ttl = cfg->host_ttl;
infra->infra_keep_probing = cfg->infra_keep_probing;
infra_dp_ratelimit = cfg->ratelimit; infra_dp_ratelimit = cfg->ratelimit;
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs, infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ratelimit_size, INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
@ -297,6 +298,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
if(!infra) if(!infra)
return infra_create(cfg); return infra_create(cfg);
infra->host_ttl = cfg->host_ttl; infra->host_ttl = cfg->host_ttl;
infra->infra_keep_probing = cfg->infra_keep_probing;
infra_dp_ratelimit = cfg->ratelimit; infra_dp_ratelimit = cfg->ratelimit;
infra_ip_ratelimit = cfg->ip_ratelimit; infra_ip_ratelimit = cfg->ip_ratelimit;
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+ maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
@ -445,6 +447,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
if(e && ((struct infra_data*)e->data)->ttl < timenow) { if(e && ((struct infra_data*)e->data)->ttl < timenow) {
/* it expired, try to reuse existing entry */ /* it expired, try to reuse existing entry */
int old = ((struct infra_data*)e->data)->rtt.rto; int old = ((struct infra_data*)e->data)->rtt.rto;
time_t tprobe = ((struct infra_data*)e->data)->probedelay;
uint8_t tA = ((struct infra_data*)e->data)->timeout_A; uint8_t tA = ((struct infra_data*)e->data)->timeout_A;
uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA; uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA;
uint8_t tother = ((struct infra_data*)e->data)->timeout_other; uint8_t tother = ((struct infra_data*)e->data)->timeout_other;
@ -460,6 +463,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
if(old >= USEFUL_SERVER_TOP_TIMEOUT) { if(old >= USEFUL_SERVER_TOP_TIMEOUT) {
((struct infra_data*)e->data)->rtt.rto ((struct infra_data*)e->data)->rtt.rto
= USEFUL_SERVER_TOP_TIMEOUT; = USEFUL_SERVER_TOP_TIMEOUT;
((struct infra_data*)e->data)->probedelay = tprobe;
((struct infra_data*)e->data)->timeout_A = tA; ((struct infra_data*)e->data)->timeout_A = tA;
((struct infra_data*)e->data)->timeout_AAAA = tAAAA; ((struct infra_data*)e->data)->timeout_AAAA = tAAAA;
((struct infra_data*)e->data)->timeout_other = tother; ((struct infra_data*)e->data)->timeout_other = tother;
@ -482,7 +486,8 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
*edns_vs = data->edns_version; *edns_vs = data->edns_version;
*edns_lame_known = data->edns_lame_known; *edns_lame_known = data->edns_lame_known;
*to = rtt_timeout(&data->rtt); *to = rtt_timeout(&data->rtt);
if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) { if(*to >= PROBE_MAXRTO && (infra->infra_keep_probing ||
rtt_notimeout(&data->rtt)*4 <= *to)) {
/* delay other queries, this is the probe query */ /* delay other queries, this is the probe query */
if(!wr) { if(!wr) {
lock_rw_unlock(&e->lock); lock_rw_unlock(&e->lock);
@ -566,18 +571,27 @@ infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
nm, nmlen, 1); nm, nmlen, 1);
struct infra_data* data; struct infra_data* data;
int needtoinsert = 0; int needtoinsert = 0, expired = 0;
int rto = 1; int rto = 1;
time_t oldprobedelay = 0;
if(!e) { if(!e) {
if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
return 0; return 0;
needtoinsert = 1; needtoinsert = 1;
} else if(((struct infra_data*)e->data)->ttl < timenow) { } else if(((struct infra_data*)e->data)->ttl < timenow) {
oldprobedelay = ((struct infra_data*)e->data)->probedelay;
data_entry_init(infra, e, timenow); data_entry_init(infra, e, timenow);
expired = 1;
} }
/* have an entry, update the rtt */ /* have an entry, update the rtt */
data = (struct infra_data*)e->data; data = (struct infra_data*)e->data;
if(roundtrip == -1) { if(roundtrip == -1) {
if(needtoinsert || expired) {
/* timeout on entry that has expired before the timer
* keep old timeout from the function caller */
data->rtt.rto = orig_rtt;
data->probedelay = oldprobedelay;
}
rtt_lost(&data->rtt, orig_rtt); rtt_lost(&data->rtt, orig_rtt);
if(qtype == LDNS_RR_TYPE_A) { if(qtype == LDNS_RR_TYPE_A) {
if(data->timeout_A < TIMEOUT_COUNT_MAX) if(data->timeout_A < TIMEOUT_COUNT_MAX)
@ -681,7 +695,12 @@ infra_get_lame_rtt(struct infra_cache* infra,
return 0; return 0;
host = (struct infra_data*)e->data; host = (struct infra_data*)e->data;
*rtt = rtt_unclamped(&host->rtt); *rtt = rtt_unclamped(&host->rtt);
if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay if(host->rtt.rto >= PROBE_MAXRTO && timenow >= host->probedelay
&& infra->infra_keep_probing) {
/* single probe, keep probing */
if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) { && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
/* single probe for this domain, and we are not probing */ /* single probe for this domain, and we are not probing */
/* unless the query type allows a probe to happen */ /* unless the query type allows a probe to happen */
@ -704,7 +723,8 @@ infra_get_lame_rtt(struct infra_cache* infra,
/* see if this can be a re-probe of an unresponsive server */ /* see if this can be a re-probe of an unresponsive server */
/* minus 1000 because that is outside of the RTTBAND, so /* minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen */ * blacklisted servers stay blacklisted if this is chosen */
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT ||
infra->infra_keep_probing) {
lock_rw_unlock(&e->lock); lock_rw_unlock(&e->lock);
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
*lame = 0; *lame = 0;

View file

@ -114,6 +114,8 @@ struct infra_cache {
struct slabhash* hosts; struct slabhash* hosts;
/** TTL value for host information, in seconds */ /** TTL value for host information, in seconds */
int host_ttl; int host_ttl;
/** the hosts that are down are kept probed for recovery */
int infra_keep_probing;
/** hash table with query rates per name: rate_key, rate_data */ /** hash table with query rates per name: rate_key, rate_data */
struct slabhash* domain_rates; struct slabhash* domain_rates;
/** ratelimit settings for domains, struct domain_limit_data */ /** ratelimit settings for domains, struct domain_limit_data */

View file

@ -45,6 +45,7 @@
#include "util/config_file.h" #include "util/config_file.h"
#include "util/data/packed_rrset.h" #include "util/data/packed_rrset.h"
#include "util/data/msgreply.h" #include "util/data/msgreply.h"
#include "util/data/msgparse.h"
#include "util/regional.h" #include "util/regional.h"
#include "util/alloc.h" #include "util/alloc.h"
#include "util/net_help.h" #include "util/net_help.h"
@ -396,6 +397,7 @@ rrset_update_sec_status(struct rrset_cache* r,
cachedata->ttl = updata->ttl + now; cachedata->ttl = updata->ttl + now;
for(i=0; i<cachedata->count+cachedata->rrsig_count; i++) for(i=0; i<cachedata->count+cachedata->rrsig_count; i++)
cachedata->rr_ttl[i] = updata->rr_ttl[i]+now; cachedata->rr_ttl[i] = updata->rr_ttl[i]+now;
cachedata->ttl_add = now;
} }
} }
lock_rw_unlock(&e->lock); lock_rw_unlock(&e->lock);

File diff suppressed because it is too large Load diff

View file

@ -43,6 +43,9 @@
#define LISTEN_DNSPORT_H #define LISTEN_DNSPORT_H
#include "util/netevent.h" #include "util/netevent.h"
#ifdef HAVE_NGHTTP2_NGHTTP2_H
#include <nghttp2/nghttp2.h>
#endif
struct listen_list; struct listen_list;
struct config_file; struct config_file;
struct addrinfo; struct addrinfo;
@ -94,8 +97,9 @@ enum listen_type {
/** tcp type + dnscrypt */ /** tcp type + dnscrypt */
listen_type_tcp_dnscrypt, listen_type_tcp_dnscrypt,
/** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/ /** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/
listen_type_udpancil_dnscrypt listen_type_udpancil_dnscrypt,
/** HTTP(2) over TLS over TCP */
listen_type_http
}; };
/** /**
@ -117,19 +121,32 @@ struct listen_port {
* interfaces for IP4 and/or IP6, for UDP and/or TCP. * interfaces for IP4 and/or IP6, for UDP and/or TCP.
* On the given port number. It creates the sockets. * On the given port number. It creates the sockets.
* @param cfg: settings on what ports to open. * @param cfg: settings on what ports to open.
* @param ifs: interfaces to open, array of IP addresses, "ip[@port]".
* @param num_ifs: length of ifs.
* @param reuseport: set to true if you want reuseport, or NULL to not have it, * @param reuseport: set to true if you want reuseport, or NULL to not have it,
* set to false on exit if reuseport failed to apply (because of no * set to false on exit if reuseport failed to apply (because of no
* kernel support). * kernel support).
* @return: linked list of ports or NULL on error. * @return: linked list of ports or NULL on error.
*/ */
struct listen_port* listening_ports_open(struct config_file* cfg, struct listen_port* listening_ports_open(struct config_file* cfg,
int* reuseport); char** ifs, int num_ifs, int* reuseport);
/** /**
* Close and delete the (list of) listening ports. * Close and delete the (list of) listening ports.
*/ */
void listening_ports_free(struct listen_port* list); void listening_ports_free(struct listen_port* list);
/**
* Resolve interface names in config and store result IP addresses
* @param cfg: config
* @param resif: string array (malloced array of malloced strings) with
* result. NULL if cfg has none.
* @param num_resif: length of resif. Zero if cfg has zero num_ifs.
* @return 0 on failure.
*/
int resolve_interface_names(struct config_file* cfg, char*** resif,
int* num_resif);
/** /**
* Create commpoints with for this thread for the shared ports. * Create commpoints with for this thread for the shared ports.
* @param base: the comm_base that provides event functionality. * @param base: the comm_base that provides event functionality.
@ -139,6 +156,10 @@ void listening_ports_free(struct listen_port* list);
* @param tcp_accept_count: max number of simultaneous TCP connections * @param tcp_accept_count: max number of simultaneous TCP connections
* from clients. * from clients.
* @param tcp_idle_timeout: idle timeout for TCP connections in msec. * @param tcp_idle_timeout: idle timeout for TCP connections in msec.
* @param harden_large_queries: whether query size should be limited.
* @param http_max_streams: maximum number of HTTP/2 streams per connection.
* @param http_endpoint: HTTP endpoint to service queries on
* @param http_notls: no TLS for http downstream
* @param tcp_conn_limit: TCP connection limit info. * @param tcp_conn_limit: TCP connection limit info.
* @param sslctx: nonNULL if ssl context. * @param sslctx: nonNULL if ssl context.
* @param dtenv: nonNULL if dnstap enabled. * @param dtenv: nonNULL if dnstap enabled.
@ -147,11 +168,13 @@ void listening_ports_free(struct listen_port* list);
* @param cb_arg: user data argument for callback function. * @param cb_arg: user data argument for callback function.
* @return: the malloced listening structure, ready for use. NULL on error. * @return: the malloced listening structure, ready for use. NULL on error.
*/ */
struct listen_dnsport* listen_create(struct comm_base* base, struct listen_dnsport*
struct listen_port* ports, size_t bufsize, listen_create(struct comm_base* base, struct listen_port* ports,
int tcp_accept_count, int tcp_idle_timeout, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
struct tcl_list* tcp_conn_limit, void* sslctx, int harden_large_queries, uint32_t http_max_streams,
struct dt_env *dtenv, comm_point_callback_type* cb, void* cb_arg); char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit,
void* sslctx, struct dt_env* dtenv, comm_point_callback_type* cb,
void *cb_arg);
/** /**
* delete the listening structure * delete the listening structure
@ -221,13 +244,15 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
* listening UDP port. Set to false on return if it failed to do so. * listening UDP port. Set to false on return if it failed to do so.
* @param transparent: set IP_TRANSPARENT socket option. * @param transparent: set IP_TRANSPARENT socket option.
* @param mss: maximum segment size of the socket. if zero, leaves the default. * @param mss: maximum segment size of the socket. if zero, leaves the default.
* @param nodelay: if true set TCP_NODELAY and TCP_QUICKACK socket options.
* @param freebind: set IP_FREEBIND socket option. * @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd. * @param use_systemd: if true, fetch sockets from systemd.
* @param dscp: DSCP to use. * @param dscp: DSCP to use.
* @return: the socket. -1 on error. * @return: the socket. -1 on error.
*/ */
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto, int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int freebind, int use_systemd, int dscp); int* reuseport, int transparent, int mss, int nodelay, int freebind,
int use_systemd, int dscp);
/** /**
* Create and bind local listening socket * Create and bind local listening socket
@ -369,7 +394,34 @@ int tcp_req_info_handle_read_close(struct tcp_req_info* req);
/** get the size of currently used tcp stream wait buffers (in bytes) */ /** get the size of currently used tcp stream wait buffers (in bytes) */
size_t tcp_req_info_get_stream_buffer_size(void); size_t tcp_req_info_get_stream_buffer_size(void);
/** get the size of currently used HTTP2 query buffers (in bytes) */
size_t http2_get_query_buffer_size(void);
/** get the size of currently used HTTP2 response buffers (in bytes) */
size_t http2_get_response_buffer_size(void);
#ifdef HAVE_NGHTTP2
/**
* Create nghttp2 callbacks to handle HTTP2 requests.
* @return malloc'ed struct, NULL on failure
*/
nghttp2_session_callbacks* http2_req_callbacks_create(void);
/** Free http2 stream buffers and decrease buffer counters */
void http2_req_stream_clear(struct http2_stream* h2_stream);
/**
* DNS response ready to be submitted to nghttp2, to be prepared for sending
* out. Response is stored in c->buffer. Copy to rbuffer because the c->buffer
* might be used before this will be send out.
* @param h2_session: http2 session, containing c->buffer which contains answer
* @param h2_stream: http2 stream, containing buffer to store answer in
* @return 0 on error, 1 otherwise
*/
int http2_submit_dns_response(struct http2_session* h2_session);
#else
int http2_submit_dns_response(void* v);
#endif /* HAVE_NGHTTP2 */
char* set_ip_dscp(int socket, int addrfamily, int ds); char* set_ip_dscp(int socket, int addrfamily, int ds);
char* sock_strerror(int errn);
#endif /* LISTEN_DNSPORT_H */ #endif /* LISTEN_DNSPORT_H */

View file

@ -157,7 +157,7 @@ local_zone_create(uint8_t* nm, size_t len, int labs,
z->namelen = len; z->namelen = len;
z->namelabs = labs; z->namelabs = labs;
lock_rw_init(&z->lock); lock_rw_init(&z->lock);
z->region = regional_create_custom(sizeof(struct regional)); z->region = regional_create_nochunk(sizeof(struct regional));
if(!z->region) { if(!z->region) {
free(z); free(z);
return NULL; return NULL;
@ -463,6 +463,48 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
return 1; return 1;
} }
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
* for the RR is entered later on local_zone_enter_rr() as with the other
* records. An artifical soa_negative record with a modified TTL (minimum of
* the TTL and the SOA.MINIMUM) is also created and marked for usage with
* negative answers and to avoid allocations during those answers. */
static int
lz_mark_soa_for_zone(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset,
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr)
{
struct packed_rrset_data* pd = (struct packed_rrset_data*)
regional_alloc_zero(z->region, sizeof(*pd));
struct ub_packed_rrset_key* rrset_negative = (struct ub_packed_rrset_key*)
regional_alloc_zero(z->region, sizeof(*rrset_negative));
time_t minimum;
if(!rrset_negative||!pd) {
log_err("out of memory");
return 0;
}
/* Mark the original SOA record and then continue with the negative one. */
z->soa = soa_rrset;
rrset_negative->entry.key = rrset_negative;
pd->trust = rrset_trust_prim_noglue;
pd->security = sec_status_insecure;
rrset_negative->entry.data = pd;
rrset_negative->rk.dname = soa_rrset->rk.dname;
rrset_negative->rk.dname_len = soa_rrset->rk.dname_len;
rrset_negative->rk.type = soa_rrset->rk.type;
rrset_negative->rk.rrset_class = soa_rrset->rk.rrset_class;
if(!rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr))
return 0;
/* last 4 bytes are minimum ttl in network format */
if(pd->count == 0 || pd->rr_len[0] < 2+4)
return 0;
minimum = (time_t)sldns_read_uint32(pd->rr_data[0]+(pd->rr_len[0]-4));
minimum = ttl<minimum?ttl:minimum;
pd->ttl = minimum;
pd->rr_ttl[0] = minimum;
z->soa_negative = rrset_negative;
return 1;
}
int int
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen, local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl, int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
@ -502,8 +544,10 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
if(query_dname_compare(node->name, z->name) == 0) { if(query_dname_compare(node->name, z->name) == 0) {
if(rrtype == LDNS_RR_TYPE_NSEC) if(rrtype == LDNS_RR_TYPE_NSEC)
rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX; rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX;
if(rrtype == LDNS_RR_TYPE_SOA) if(rrtype == LDNS_RR_TYPE_SOA &&
z->soa = rrset->rrset; !lz_mark_soa_for_zone(z, rrset->rrset, rdata, rdata_len, ttl,
rrstr))
return 0;
} }
} }
pd = (struct packed_rrset_data*)rrset->rrset->entry.data; pd = (struct packed_rrset_data*)rrset->rrset->entry.data;
@ -1215,7 +1259,7 @@ local_encode(struct query_info* qinfo, struct module_env* env,
edns->ext_rcode = 0; edns->ext_rcode = 0;
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
repinfo, temp) || !reply_info_answer_encode(qinfo, &rep, repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep,
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), *(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)) { buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
@ -1237,7 +1281,7 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
edns->bits &= EDNS_DO; edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL, if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
rcode, edns, repinfo, temp)) rcode, edns, repinfo, temp, env->now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf), error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns); sldns_buffer_read_u16_at(buf, 2), edns);
@ -1548,9 +1592,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
lz_type == local_zone_inform_redirect || lz_type == local_zone_inform_redirect ||
lz_type == local_zone_always_nodata)? lz_type == local_zone_always_nodata)?
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
if(z->soa) if(z->soa && z->soa_negative)
return local_encode(qinfo, env, edns, repinfo, buf, temp, return local_encode(qinfo, env, edns, repinfo, buf, temp,
z->soa, 0, rcode); z->soa_negative, 0, rcode);
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
(rcode|BIT_AA)); (rcode|BIT_AA));
return 1; return 1;
@ -1558,6 +1602,46 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|| lz_type == local_zone_always_transparent) { || lz_type == local_zone_always_transparent) {
/* no NODATA or NXDOMAINS for this zone type */ /* no NODATA or NXDOMAINS for this zone type */
return 0; return 0;
} else if(lz_type == local_zone_always_null) {
/* 0.0.0.0 or ::0 or noerror/nodata for this zone type,
* used for blocklists. */
if(qinfo->qtype == LDNS_RR_TYPE_A ||
qinfo->qtype == LDNS_RR_TYPE_AAAA) {
struct ub_packed_rrset_key lrr;
struct packed_rrset_data d;
time_t rr_ttl = 3600;
size_t rr_len = 0;
uint8_t rr_data[2+16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t* rr_datas = rr_data;
memset(&lrr, 0, sizeof(lrr));
memset(&d, 0, sizeof(d));
lrr.entry.data = &d;
lrr.rk.dname = qinfo->qname;
lrr.rk.dname_len = qinfo->qname_len;
lrr.rk.type = htons(qinfo->qtype);
lrr.rk.rrset_class = htons(qinfo->qclass);
if(qinfo->qtype == LDNS_RR_TYPE_A) {
rr_len = 4;
sldns_write_uint16(rr_data, rr_len);
rr_len += 2;
} else {
rr_len = 16;
sldns_write_uint16(rr_data, rr_len);
rr_len += 2;
}
d.ttl = rr_ttl;
d.count = 1;
d.rr_len = &rr_len;
d.rr_data = &rr_datas;
d.rr_ttl = &rr_ttl;
return local_encode(qinfo, env, edns, repinfo, buf, temp,
&lrr, 1, LDNS_RCODE_NOERROR);
} else {
local_error_encode(qinfo, env, edns, repinfo, buf,
temp, LDNS_RCODE_NOERROR,
(LDNS_RCODE_NOERROR|BIT_AA));
}
return 1;
} }
/* else lz_type == local_zone_transparent */ /* else lz_type == local_zone_transparent */
@ -1565,9 +1649,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
* does not, then we should make this noerror/nodata */ * does not, then we should make this noerror/nodata */
if(ld && ld->rrsets) { if(ld && ld->rrsets) {
int rcode = LDNS_RCODE_NOERROR; int rcode = LDNS_RCODE_NOERROR;
if(z->soa) if(z->soa && z->soa_negative)
return local_encode(qinfo, env, edns, repinfo, buf, temp, return local_encode(qinfo, env, edns, repinfo, buf, temp,
z->soa, 0, rcode); z->soa_negative, 0, rcode);
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
(rcode|BIT_AA)); (rcode|BIT_AA));
return 1; return 1;
@ -1762,6 +1846,7 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_always_nxdomain: return "always_nxdomain"; case local_zone_always_nxdomain: return "always_nxdomain";
case local_zone_always_nodata: return "always_nodata"; case local_zone_always_nodata: return "always_nodata";
case local_zone_always_deny: return "always_deny"; case local_zone_always_deny: return "always_deny";
case local_zone_always_null: return "always_null";
case local_zone_noview: return "noview"; case local_zone_noview: return "noview";
case local_zone_invalid: return "invalid"; case local_zone_invalid: return "invalid";
} }
@ -1798,6 +1883,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_always_nodata; *t = local_zone_always_nodata;
else if(strcmp(type, "always_deny") == 0) else if(strcmp(type, "always_deny") == 0)
*t = local_zone_always_deny; *t = local_zone_always_deny;
else if(strcmp(type, "always_null") == 0)
*t = local_zone_always_null;
else if(strcmp(type, "noview") == 0) else if(strcmp(type, "noview") == 0)
*t = local_zone_noview; *t = local_zone_noview;
else if(strcmp(type, "nodefault") == 0) else if(strcmp(type, "nodefault") == 0)
@ -2000,8 +2087,10 @@ void local_zones_del_data(struct local_zones* zones,
/* no memory recycling for zone deletions ... */ /* no memory recycling for zone deletions ... */
d->rrsets = NULL; d->rrsets = NULL;
/* did we delete the soa record ? */ /* did we delete the soa record ? */
if(query_dname_compare(d->name, z->name) == 0) if(query_dname_compare(d->name, z->name) == 0) {
z->soa = NULL; z->soa = NULL;
z->soa_negative = NULL;
}
/* cleanup the empty nonterminals for this name */ /* cleanup the empty nonterminals for this name */
del_empty_term(z, d, name, len, labs); del_empty_term(z, d, name, len, labs);

View file

@ -96,6 +96,9 @@ enum localzone_type {
local_zone_always_nodata, local_zone_always_nodata,
/** drop query, even when there is local data */ /** drop query, even when there is local data */
local_zone_always_deny, local_zone_always_deny,
/** answer with 0.0.0.0 or ::0 or noerror/nodata, even when there is
* local data */
local_zone_always_null,
/** answer not from the view, but global or no-answer */ /** answer not from the view, but global or no-answer */
local_zone_noview, local_zone_noview,
/** Invalid type, cannot be used to generate answer */ /** Invalid type, cannot be used to generate answer */
@ -155,6 +158,10 @@ struct local_zone {
rbtree_type data; rbtree_type data;
/** if data contains zone apex SOA data, this is a ptr to it. */ /** if data contains zone apex SOA data, this is a ptr to it. */
struct ub_packed_rrset_key* soa; struct ub_packed_rrset_key* soa;
/** if data contains zone apex SOA data, this is a prt to an
* artificial negative SOA rrset (TTL is the minimum of the TTL and the
* SOA.MINIMUM). */
struct ub_packed_rrset_key* soa_negative;
}; };
/** /**

View file

@ -498,7 +498,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!s) { if(!s) {
log_err("mesh_state_create: out of memory; SERVFAIL"); log_err("mesh_state_create: out of memory; SERVFAIL");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL, if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch)) LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL, error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns); qinfo, qid, qflags, edns);
@ -514,7 +514,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!s->s.edns_opts_front_in) { if(!s->s.edns_opts_front_in) {
log_err("mesh_state_create: out of memory; SERVFAIL"); log_err("mesh_state_create: out of memory; SERVFAIL");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch)) NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL, error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns); qinfo, qid, qflags, edns);
@ -551,6 +551,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
goto servfail_mem; goto servfail_mem;
} }
} }
if(rep->c->use_h2) {
http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
}
/* add serve expired timer if required and not already there */ /* add serve expired timer if required and not already there */
if(timeout && !mesh_serve_expired_init(s, timeout)) { if(timeout && !mesh_serve_expired_init(s, timeout)) {
log_err("mesh_new_client: out of memory initializing serve expired"); log_err("mesh_new_client: out of memory initializing serve expired");
@ -584,7 +587,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
servfail_mem: servfail_mem:
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s, if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch)) NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
edns->opt_list = NULL; edns->opt_list = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL, error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns); qinfo, qid, qflags, edns);
@ -1109,10 +1112,12 @@ int mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub)
* @param rcode: if not 0, error code. * @param rcode: if not 0, error code.
* @param rep: reply to send (or NULL if rcode is set). * @param rep: reply to send (or NULL if rcode is set).
* @param r: callback entry * @param r: callback entry
* @param start_time: the time to pass to callback functions, it is 0 or
* a value from one of the packets if the mesh state had packets.
*/ */
static void static void
mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
struct mesh_cb* r) struct mesh_cb* r, struct timeval* start_time)
{ {
int secure; int secure;
char* reason = NULL; char* reason = NULL;
@ -1133,11 +1138,11 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
if(rcode) { if(rcode) {
if(rcode == LDNS_RCODE_SERVFAIL) { if(rcode == LDNS_RCODE_SERVFAIL) {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, rcode, &r->edns, NULL, m->s.region)) rep, rcode, &r->edns, NULL, m->s.region, start_time))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
} else { } else {
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode, if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
&r->edns, NULL, m->s.region)) &r->edns, NULL, m->s.region, start_time))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
} }
fptr_ok(fptr_whitelist_mesh_cb(r->cb)); fptr_ok(fptr_whitelist_mesh_cb(r->cb));
@ -1152,7 +1157,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
r->edns.bits &= EDNS_DO; r->edns.bits &= EDNS_DO;
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) || LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region, start_time) ||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid, !reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->buf, 0, 1, r->qflags, r->buf, 0, 1,
m->s.env->scratch, udp_size, &r->edns, m->s.env->scratch, udp_size, &r->edns,
@ -1193,6 +1198,12 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
/* Copy the client's EDNS for later restore, to make sure the edns /* Copy the client's EDNS for later restore, to make sure the edns
* compare is with the correct edns options. */ * compare is with the correct edns options. */
struct edns_data edns_bak = r->edns; struct edns_data edns_bak = r->edns;
/* briefly set the replylist to null in case the
* meshsendreply calls tcpreqinfo sendreply that
* comm_point_drops because of size, and then the
* null stops the mesh state remove and thus
* reply_list modification and accounting */
struct mesh_reply* rlist = m->reply_list;
/* examine security status */ /* examine security status */
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) || if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
m->s.env->cfg->ignore_cd) && rep && m->s.env->cfg->ignore_cd) && rep &&
@ -1207,13 +1218,26 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
else secure = 0; else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR) if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL; rcode = LDNS_RCODE_SERVFAIL;
if(r->query_reply.c->use_h2) {
r->query_reply.c->h2_stream = r->h2_stream;
/* Mesh reply won't exist for long anymore. Make it impossible
* for HTTP/2 stream to refer to mesh state, in case
* connection gets cleanup before HTTP/2 stream close. */
r->h2_stream->mesh_state = NULL;
}
/* send the reply */ /* send the reply */
/* We don't reuse the encoded answer if either the previous or current /* We don't reuse the encoded answer if:
* response has a local alias. We could compare the alias records * - either the previous or current response has a local alias. We could
* and still reuse the previous answer if they are the same, but that * compare the alias records and still reuse the previous answer if they
* would be complicated and error prone for the relatively minor case. * are the same, but that would be complicated and error prone for the
* So we err on the side of safety. */ * relatively minor case. So we err on the side of safety.
if(prev && prev_buffer && prev->qflags == r->qflags && * - there are registered callback functions for the given rcode, as these
* need to be called for each reply. */
if(((rcode != LDNS_RCODE_SERVFAIL &&
!m->s.env->inplace_cb_lists[inplace_cb_reply]) ||
(rcode == LDNS_RCODE_SERVFAIL &&
!m->s.env->inplace_cb_lists[inplace_cb_reply_servfail])) &&
prev && prev_buffer && prev->qflags == r->qflags &&
!prev->local_alias && !r->local_alias && !prev->local_alias && !r->local_alias &&
prev->edns.edns_present == r->edns.edns_present && prev->edns.edns_present == r->edns.edns_present &&
prev->edns.bits == r->edns.bits && prev->edns.bits == r->edns.bits &&
@ -1226,22 +1250,26 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t)); sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t));
sldns_buffer_write_at(r_buffer, 12, r->qname, sldns_buffer_write_at(r_buffer, 12, r->qname,
m->s.qinfo.qname_len); m->s.qinfo.qname_len);
m->reply_list = NULL;
comm_point_send_reply(&r->query_reply); comm_point_send_reply(&r->query_reply);
m->reply_list = rlist;
} else if(rcode) { } else if(rcode) {
m->s.qinfo.qname = r->qname; m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias; m->s.qinfo.local_alias = r->local_alias;
if(rcode == LDNS_RCODE_SERVFAIL) { if(rcode == LDNS_RCODE_SERVFAIL) {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, rcode, &r->edns, NULL, m->s.region)) rep, rcode, &r->edns, &r->query_reply, m->s.region, &r->start_time))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
} else { } else {
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode, if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
&r->edns, NULL, m->s.region)) &r->edns, &r->query_reply, m->s.region, &r->start_time))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
} }
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid, error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
r->qflags, &r->edns); r->qflags, &r->edns);
m->reply_list = NULL;
comm_point_send_reply(&r->query_reply); comm_point_send_reply(&r->query_reply);
m->reply_list = rlist;
} else { } else {
size_t udp_size = r->edns.udp_size; size_t udp_size = r->edns.udp_size;
r->edns.edns_version = EDNS_ADVERTISED_VERSION; r->edns.edns_version = EDNS_ADVERTISED_VERSION;
@ -1251,7 +1279,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
m->s.qinfo.qname = r->qname; m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias; m->s.qinfo.local_alias = r->local_alias;
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) || LDNS_RCODE_NOERROR, &r->edns, &r->query_reply, m->s.region, &r->start_time) ||
!apply_edns_options(&r->edns, &edns_bak, !apply_edns_options(&r->edns, &edns_bak,
m->s.env->cfg, r->query_reply.c, m->s.env->cfg, r->query_reply.c,
m->s.region) || m->s.region) ||
@ -1261,13 +1289,15 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
secure)) secure))
{ {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region)) rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL, error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
&m->s.qinfo, r->qid, r->qflags, &r->edns); &m->s.qinfo, r->qid, r->qflags, &r->edns);
} }
r->edns = edns_bak; r->edns = edns_bak;
m->reply_list = NULL;
comm_point_send_reply(&r->query_reply); comm_point_send_reply(&r->query_reply);
m->reply_list = rlist;
} }
/* account */ /* account */
log_assert(m->s.env->mesh->num_reply_addrs > 0); log_assert(m->s.env->mesh->num_reply_addrs > 0);
@ -1296,12 +1326,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
void mesh_query_done(struct mesh_state* mstate) void mesh_query_done(struct mesh_state* mstate)
{ {
struct mesh_reply* r, *reply_list = NULL; struct mesh_reply* r;
struct mesh_reply* prev = NULL; struct mesh_reply* prev = NULL;
struct sldns_buffer* prev_buffer = NULL; struct sldns_buffer* prev_buffer = NULL;
struct mesh_cb* c; struct mesh_cb* c;
struct reply_info* rep = (mstate->s.return_msg? struct reply_info* rep = (mstate->s.return_msg?
mstate->s.return_msg->rep:NULL); mstate->s.return_msg->rep:NULL);
struct timeval tv = {0, 0};
/* No need for the serve expired timer anymore; we are going to reply. */ /* No need for the serve expired timer anymore; we are going to reply. */
if(mstate->s.serve_expired_data) { if(mstate->s.serve_expired_data) {
comm_timer_delete(mstate->s.serve_expired_data->timer); comm_timer_delete(mstate->s.serve_expired_data->timer);
@ -1320,27 +1351,9 @@ void mesh_query_done(struct mesh_state* mstate)
free(err); free(err);
} }
} }
if(mstate->reply_list) { for(r = mstate->reply_list; r; r = r->next) {
/* set the reply_list to NULL during the mesh_query_done tv = r->start_time;
* processing, so that calls back into the mesh from
* tcp_req_info (deciding to drop the reply and thus
* unregister the mesh_reply from the mstate) are stopped
* because the list is empty.
* The mstate is then likely not a reply_state, and maybe
* also a detached_state.
*/
reply_list = mstate->reply_list;
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
/* was a reply state, not anymore */
log_assert(mstate->s.env->mesh->num_reply_states > 0);
mstate->s.env->mesh->num_reply_states--;
}
if(!mstate->reply_list && !mstate->cb_list &&
mstate->super_set.count == 0)
mstate->s.env->mesh->num_detached_states++;
}
for(r = reply_list; r; r = r->next) {
/* if a response-ip address block has been stored the /* if a response-ip address block has been stored the
* information should be logged for each client. */ * information should be logged for each client. */
if(mstate->s.respip_action_info && if(mstate->s.respip_action_info &&
@ -1364,7 +1377,15 @@ void mesh_query_done(struct mesh_state* mstate)
/* if this query is determined to be dropped during the /* if this query is determined to be dropped during the
* mesh processing, this is the point to take that action. */ * mesh processing, this is the point to take that action. */
if(mstate->s.is_drop) { if(mstate->s.is_drop) {
/* briefly set the reply_list to NULL, so that the
* tcp req info cleanup routine that calls the mesh
* to deregister the meshstate for it is not done
* because the list is NULL and also accounting is not
* done there, but instead we do that here. */
struct mesh_reply* reply_list = mstate->reply_list;
mstate->reply_list = NULL;
comm_point_drop_reply(&r->query_reply); comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
} else { } else {
struct sldns_buffer* r_buffer = r->query_reply.c->buffer; struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info) { if(r->query_reply.c->tcp_req_info) {
@ -1381,6 +1402,17 @@ void mesh_query_done(struct mesh_state* mstate)
prev_buffer = r_buffer; prev_buffer = r_buffer;
} }
} }
if(mstate->reply_list) {
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
/* was a reply state, not anymore */
log_assert(mstate->s.env->mesh->num_reply_states > 0);
mstate->s.env->mesh->num_reply_states--;
}
if(!mstate->reply_list && !mstate->cb_list &&
mstate->super_set.count == 0)
mstate->s.env->mesh->num_detached_states++;
}
mstate->replies_sent = 1; mstate->replies_sent = 1;
while((c = mstate->cb_list) != NULL) { while((c = mstate->cb_list) != NULL) {
/* take this cb off the list; so that the list can be /* take this cb off the list; so that the list can be
@ -1394,7 +1426,7 @@ void mesh_query_done(struct mesh_state* mstate)
if(!mstate->reply_list && !mstate->cb_list && if(!mstate->reply_list && !mstate->cb_list &&
mstate->super_set.count == 0) mstate->super_set.count == 0)
mstate->s.env->mesh->num_detached_states++; mstate->s.env->mesh->num_detached_states++;
mesh_do_callback(mstate, mstate->s.return_rcode, rep, c); mesh_do_callback(mstate, mstate->s.return_rcode, rep, c, &tv);
} }
} }
@ -1488,6 +1520,8 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
s->s.qinfo.qname_len); s->s.qinfo.qname_len);
if(!r->qname) if(!r->qname)
return 0; return 0;
if(rep->c->use_h2)
r->h2_stream = rep->c->h2_stream;
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral /* Data related to local alias stored in 'qinfo' (if any) is ephemeral
* and can be different for different original queries (even if the * and can be different for different original queries (even if the
@ -1888,13 +1922,16 @@ mesh_serve_expired_callback(void* arg)
struct respip_action_info actinfo; struct respip_action_info actinfo;
struct query_info* lookup_qinfo = &qstate->qinfo; struct query_info* lookup_qinfo = &qstate->qinfo;
struct query_info qinfo_tmp; struct query_info qinfo_tmp;
struct timeval tv = {0, 0};
int must_validate = (!(qstate->query_flags&BIT_CD) int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate; || qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
if(!qstate->serve_expired_data) return; if(!qstate->serve_expired_data) return;
verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data"); verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data");
comm_timer_delete(qstate->serve_expired_data->timer); comm_timer_delete(qstate->serve_expired_data->timer);
qstate->serve_expired_data->timer = NULL; qstate->serve_expired_data->timer = NULL;
if(qstate->blacklist || qstate->no_cache_lookup || qstate->is_drop) { /* If is_drop or no_cache_lookup (modules that handle their own cache e.g.,
* subnetmod) ignore stale data from the main cache. */
if(qstate->no_cache_lookup || qstate->is_drop) {
verbose(VERB_ALGO, verbose(VERB_ALGO,
"Serve expired: Not allowed to look into cache for stale"); "Serve expired: Not allowed to look into cache for stale");
return; return;
@ -1958,16 +1995,9 @@ mesh_serve_expired_callback(void* arg)
if(verbosity >= VERB_ALGO) if(verbosity >= VERB_ALGO)
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep); log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
r = mstate->reply_list; for(r = mstate->reply_list; r; r = r->next) {
mstate->reply_list = NULL; tv = r->start_time;
if(!mstate->reply_list && !mstate->cb_list && r) {
log_assert(mesh->num_reply_states > 0);
mesh->num_reply_states--;
if(mstate->super_set.count == 0) {
mesh->num_detached_states++;
}
}
for(; r; r = r->next) {
/* If address info is returned, it means the action should be an /* If address info is returned, it means the action should be an
* 'inform' variant and the information should be logged. */ * 'inform' variant and the information should be logged. */
if(actinfo.addrinfo) { if(actinfo.addrinfo) {
@ -2000,6 +2030,16 @@ mesh_serve_expired_callback(void* arg)
mesh->ans_expired++; mesh->ans_expired++;
} }
if(mstate->reply_list) {
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
log_assert(mesh->num_reply_states > 0);
mesh->num_reply_states--;
if(mstate->super_set.count == 0) {
mesh->num_detached_states++;
}
}
}
while((c = mstate->cb_list) != NULL) { while((c = mstate->cb_list) != NULL) {
/* take this cb off the list; so that the list can be /* take this cb off the list; so that the list can be
* changed, eg. by adds from the callback routine */ * changed, eg. by adds from the callback routine */
@ -2012,6 +2052,6 @@ mesh_serve_expired_callback(void* arg)
if(!mstate->reply_list && !mstate->cb_list && if(!mstate->reply_list && !mstate->cb_list &&
mstate->super_set.count == 0) mstate->super_set.count == 0)
qstate->env->mesh->num_detached_states++; qstate->env->mesh->num_detached_states++;
mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c); mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c, &tv);
} }
} }

View file

@ -230,6 +230,8 @@ struct mesh_reply {
uint8_t* qname; uint8_t* qname;
/** same as that in query_info. */ /** same as that in query_info. */
struct local_rrset* local_alias; struct local_rrset* local_alias;
/** send query to this http2 stream, if set */
struct http2_stream* h2_stream;
}; };
/** /**

View file

@ -51,6 +51,9 @@
#ifdef WITH_PYTHONMODULE #ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h" #include "pythonmod/pythonmod.h"
#endif #endif
#ifdef WITH_DYNLIBMODULE
#include "dynlibmod/dynlibmod.h"
#endif
#ifdef USE_CACHEDB #ifdef USE_CACHEDB
#include "cachedb/cachedb.h" #include "cachedb/cachedb.h"
#endif #endif
@ -133,6 +136,9 @@ module_list_avail(void)
#ifdef WITH_PYTHONMODULE #ifdef WITH_PYTHONMODULE
"python", "python",
#endif #endif
#ifdef WITH_DYNLIBMODULE
"dynlib",
#endif
#ifdef USE_CACHEDB #ifdef USE_CACHEDB
"cachedb", "cachedb",
#endif #endif
@ -164,6 +170,9 @@ module_funcs_avail(void)
#ifdef WITH_PYTHONMODULE #ifdef WITH_PYTHONMODULE
&pythonmod_get_funcblock, &pythonmod_get_funcblock,
#endif #endif
#ifdef WITH_DYNLIBMODULE
&dynlibmod_get_funcblock,
#endif
#ifdef USE_CACHEDB #ifdef USE_CACHEDB
&cachedb_get_funcblock, &cachedb_get_funcblock,
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -52,6 +52,7 @@ struct ub_randstate;
struct pending_tcp; struct pending_tcp;
struct waiting_tcp; struct waiting_tcp;
struct waiting_udp; struct waiting_udp;
struct reuse_tcp;
struct infra_cache; struct infra_cache;
struct port_comm; struct port_comm;
struct port_if; struct port_if;
@ -106,6 +107,9 @@ struct outside_network {
int delayclose; int delayclose;
/** timeout for delayclose */ /** timeout for delayclose */
struct timeval delay_tv; struct timeval delay_tv;
/** if we perform udp-connect, connect() for UDP socket to mitigate
* ICMP side channel leakage */
int udp_connect;
/** array of outgoing IP4 interfaces */ /** array of outgoing IP4 interfaces */
struct port_if* ip4_ifs; struct port_if* ip4_ifs;
@ -154,6 +158,21 @@ struct outside_network {
size_t num_tcp; size_t num_tcp;
/** number of tcp communication points in use. */ /** number of tcp communication points in use. */
size_t num_tcp_outgoing; size_t num_tcp_outgoing;
/**
* tree of still-open and waiting tcp connections for reuse.
* can be closed and reopened to get a new tcp connection.
* or reused to the same destination again. with timeout to close.
* Entries are of type struct reuse_tcp.
* The entries are both active and empty connections.
*/
rbtree_type tcp_reuse;
/** max number of tcp_reuse entries we want to keep open */
size_t tcp_reuse_max;
/** first and last(oldest) in lru list of reuse connections.
* the oldest can be closed to get a new free pending_tcp if needed
* The list contains empty connections, that wait for timeout or
* a new query that can use the existing connection. */
struct reuse_tcp* tcp_reuse_first, *tcp_reuse_last;
/** list of tcp comm points that are free for use */ /** list of tcp comm points that are free for use */
struct pending_tcp* tcp_free; struct pending_tcp* tcp_free;
/** list of tcp queries waiting for a buffer */ /** list of tcp queries waiting for a buffer */
@ -211,6 +230,76 @@ struct port_comm {
struct comm_point* cp; struct comm_point* cp;
}; };
/**
* Reuse TCP connection, still open can be used again.
*/
struct reuse_tcp {
/** rbtree node with links in tcp_reuse tree. key is NULL when not
* in tree. Both active and empty connections are in the tree.
* key is a pointer to this structure, the members used to compare
* are the sockaddr and and then is-ssl bool, and then ptr value is
* used in case the same address exists several times in the tree
* when there are multiple connections to the same destination to
* make the rbtree items unique. */
rbnode_type node;
/** the key for the tcp_reuse tree. address of peer, ip4 or ip6,
* and port number of peer */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** also key for tcp_reuse tree, if ssl is used */
int is_ssl;
/** lru chain, so that the oldest can be removed to get a new
* connection when all are in (re)use. oldest is last in list.
* The lru only contains empty connections waiting for reuse,
* the ones with active queries are not on the list because they
* do not need to be closed to make space for others. They already
* service a query so the close for another query does not help
* service a larger number of queries. */
struct reuse_tcp* lru_next, *lru_prev;
/** true if the reuse_tcp item is on the lru list with empty items */
int item_on_lru_list;
/** the connection to reuse, the fd is non-1 and is open.
* the addr and port determine where the connection is going,
* and is key to the rbtree. The SSL ptr determines if it is
* a TLS connection or a plain TCP connection there. And TLS
* or not is also part of the key to the rbtree.
* There is a timeout and read event on the fd, to close it. */
struct pending_tcp* pending;
/**
* The more read again value pointed to by the commpoint
* tcp_more_read_again pointer, so that it exists after commpoint
* delete
*/
int cp_more_read_again;
/**
* The more write again value pointed to by the commpoint
* tcp_more_write_again pointer, so that it exists after commpoint
* delete
*/
int cp_more_write_again;
/** rbtree with other queries waiting on the connection, by ID number,
* of type struct waiting_tcp. It is for looking up received
* answers to the structure for callback. And also to see if ID
* numbers are unused and can be used for a new query.
* The write_wait elements are also in the tree, so that ID numbers
* can be looked up also for them. They are bool write_wait_queued. */
rbtree_type tree_by_id;
/** list of queries waiting to be written on the channel,
* if NULL no queries are waiting to be written and the pending->query
* is the query currently serviced. The first is the next in line.
* They are also in the tree_by_id. Once written, the are removed
* from this list, but stay in the tree. */
struct waiting_tcp* write_wait_first, *write_wait_last;
/** the outside network it is part of */
struct outside_network* outnet;
};
/** max number of queries on a reuse connection */
#define MAX_REUSE_TCP_QUERIES 200
/** timeout for REUSE entries in milliseconds. */
#define REUSE_TIMEOUT 60000
/** /**
* A query that has an answer pending for it. * A query that has an answer pending for it.
*/ */
@ -255,12 +344,15 @@ struct pending {
struct pending_tcp { struct pending_tcp {
/** next in list of free tcp comm points, or NULL. */ /** next in list of free tcp comm points, or NULL. */
struct pending_tcp* next_free; struct pending_tcp* next_free;
/** the ID for the query; checked in reply */
uint16_t id;
/** tcp comm point it was sent on (and reply must come back on). */ /** tcp comm point it was sent on (and reply must come back on). */
struct comm_point* c; struct comm_point* c;
/** the query being serviced, NULL if the pending_tcp is unused. */ /** the query being serviced, NULL if the pending_tcp is unused. */
struct waiting_tcp* query; struct waiting_tcp* query;
/** the pre-allocated reuse tcp structure. if ->pending is nonNULL
* it is in use and the connection is waiting for reuse.
* It is here for memory pre-allocation, and used to make this
* pending_tcp wait for reuse. */
struct reuse_tcp reuse;
}; };
/** /**
@ -269,12 +361,27 @@ struct pending_tcp {
struct waiting_tcp { struct waiting_tcp {
/** /**
* next in waiting list. * next in waiting list.
* if pkt==0, this points to the pending_tcp structure. * if on_tcp_waiting_list==0, this points to the pending_tcp structure.
*/ */
struct waiting_tcp* next_waiting; struct waiting_tcp* next_waiting;
/** if true the item is on the tcp waiting list and next_waiting
* is used for that. If false, the next_waiting points to the
* pending_tcp */
int on_tcp_waiting_list;
/** next and prev in query waiting list for stream connection */
struct waiting_tcp* write_wait_prev, *write_wait_next;
/** true if the waiting_tcp structure is on the write_wait queue */
int write_wait_queued;
/** entry in reuse.tree_by_id, if key is NULL, not in tree, otherwise,
* this struct is key and sorted by ID (from waiting_tcp.id). */
rbnode_type id_node;
/** the ID for the query; checked in reply */
uint16_t id;
/** timeout event; timer keeps running whether the query is /** timeout event; timer keeps running whether the query is
* waiting for a buffer or the tcp reply is pending */ * waiting for a buffer or the tcp reply is pending */
struct comm_timer* timer; struct comm_timer* timer;
/** timeout in msec */
int timeout;
/** the outside network it is part of */ /** the outside network it is part of */
struct outside_network* outnet; struct outside_network* outnet;
/** remote address. */ /** remote address. */
@ -284,13 +391,14 @@ struct waiting_tcp {
/** /**
* The query itself, the query packet to send. * The query itself, the query packet to send.
* allocated after the waiting_tcp structure. * allocated after the waiting_tcp structure.
* set to NULL when the query is serviced and it part of pending_tcp.
* if this is NULL, the next_waiting points to the pending_tcp.
*/ */
uint8_t* pkt; uint8_t* pkt;
/** length of query packet. */ /** length of query packet. */
size_t pkt_len; size_t pkt_len;
/** callback for the timeout, error or reply to the message */ /** callback for the timeout, error or reply to the message,
* or NULL if no user is waiting. the entry uses an ID number.
* a query that was written is no longer needed, but the ID number
* and a reply will come back and can be ignored if NULL */
comm_point_callback_type* cb; comm_point_callback_type* cb;
/** callback user argument */ /** callback user argument */
void* cb_arg; void* cb_arg;
@ -298,6 +406,8 @@ struct waiting_tcp {
int ssl_upstream; int ssl_upstream;
/** ref to the tls_auth_name from the serviced_query */ /** ref to the tls_auth_name from the serviced_query */
char* tls_auth_name; char* tls_auth_name;
/** the packet was involved in an error, to stop looping errors */
int error_count;
}; };
/** /**
@ -392,6 +502,8 @@ struct serviced_query {
struct service_callback* cblist; struct service_callback* cblist;
/** the UDP or TCP query that is pending, see status which */ /** the UDP or TCP query that is pending, see status which */
void* pending; void* pending;
/** block size with which to pad encrypted queries (default: 128) */
size_t padding_block_size;
}; };
/** /**
@ -421,6 +533,7 @@ struct serviced_query {
* msec to wait on timeouted udp sockets. * msec to wait on timeouted udp sockets.
* @param tls_use_sni: if SNI is used for TLS connections. * @param tls_use_sni: if SNI is used for TLS connections.
* @param dtenv: environment to send dnstap events with (if enabled). * @param dtenv: environment to send dnstap events with (if enabled).
* @param udp_connect: if the udp_connect option is enabled.
* @return: the new structure (with no pending answers) or NULL on error. * @return: the new structure (with no pending answers) or NULL on error.
*/ */
struct outside_network* outside_network_create(struct comm_base* base, struct outside_network* outside_network_create(struct comm_base* base,
@ -429,7 +542,8 @@ struct outside_network* outside_network_create(struct comm_base* base,
struct ub_randstate* rnd, int use_caps_for_id, int* availports, struct ub_randstate* rnd, int use_caps_for_id, int* availports,
int numavailports, size_t unwanted_threshold, int tcp_mss, int numavailports, size_t unwanted_threshold, int tcp_mss,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp, void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv); void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
int udp_connect);
/** /**
* Delete outside_network structure. * Delete outside_network structure.
@ -546,6 +660,19 @@ size_t outnet_get_mem(struct outside_network* outnet);
*/ */
size_t serviced_get_mem(struct serviced_query* sq); size_t serviced_get_mem(struct serviced_query* sq);
/** Pick random ID value for a tcp stream, avoids existing IDs. */
uint16_t reuse_tcp_select_id(struct reuse_tcp* reuse,
struct outside_network* outnet);
/** find element in tree by id */
struct waiting_tcp* reuse_tcp_by_id_find(struct reuse_tcp* reuse, uint16_t id);
/** insert element in tree by id */
void reuse_tree_by_id_insert(struct reuse_tcp* reuse, struct waiting_tcp* w);
/** delete readwait waiting_tcp elements, deletes the elements in the list */
void reuse_del_readwait(rbtree_type* tree_by_id);
/** get TCP file descriptor for address, returns -1 on failure, /** get TCP file descriptor for address, returns -1 on failure,
* tcp_mss is 0 or maxseg size to set for TCP packets. */ * tcp_mss is 0 or maxseg size to set for TCP packets. */
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp); int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp);
@ -643,4 +770,10 @@ int pending_cmp(const void* key1, const void* key2);
/** compare function of serviced query rbtree */ /** compare function of serviced query rbtree */
int serviced_cmp(const void* key1, const void* key2); int serviced_cmp(const void* key1, const void* key2);
/** compare function of reuse_tcp rbtree in outside_network struct */
int reuse_cmp(const void* key1, const void* key2);
/** compare function of reuse_tcp tree_by_id rbtree */
int reuse_id_cmp(const void* key1, const void* key2);
#endif /* OUTSIDE_NETWORK_H */ #endif /* OUTSIDE_NETWORK_H */

View file

@ -440,6 +440,8 @@ err:
respip_set_delete(r->respip_set); respip_set_delete(r->respip_set);
if(r->taglist) if(r->taglist)
free(r->taglist); free(r->taglist);
if(r->region)
regional_destroy(r->region);
free(r); free(r);
} }
return NULL; return NULL;
@ -597,8 +599,18 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
uint8_t* policydname; uint8_t* policydname;
if(!dname_subdomain_c(dname, azname)) { if(!dname_subdomain_c(dname, azname)) {
log_err("RPZ: name of record to insert into RPZ is not a " char* dname_str = sldns_wire2str_dname(dname, dnamelen);
"subdomain of the configured name of the RPZ zone"); char* azname_str = sldns_wire2str_dname(azname, aznamelen);
if(dname_str && azname_str) {
log_err("RPZ: name of record (%s) to insert into RPZ is not a "
"subdomain of the configured name of the RPZ zone (%s)",
dname_str, azname_str);
} else {
log_err("RPZ: name of record to insert into RPZ is not a "
"subdomain of the configured name of the RPZ zone");
}
free(dname_str);
free(azname_str);
return 0; return 0;
} }
@ -656,7 +668,8 @@ rpz_find_zone(struct rpz* r, uint8_t* qname, size_t qname_len, uint16_t qclass,
int only_exact, int wr, int zones_keep_lock) int only_exact, int wr, int zones_keep_lock)
{ {
uint8_t* ce; uint8_t* ce;
size_t ce_len, ce_labs; size_t ce_len;
int ce_labs;
uint8_t wc[LDNS_MAX_DOMAINLEN+1]; uint8_t wc[LDNS_MAX_DOMAINLEN+1];
int exact; int exact;
struct local_zone* z = NULL; struct local_zone* z = NULL;
@ -951,8 +964,8 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
for(a = az->rpz_first; a; a = a->rpz_az_next) { for(a = az->rpz_first; a; a = a->rpz_az_next) {
lock_rw_rdlock(&a->lock); lock_rw_rdlock(&a->lock);
r = a->rpz; r = a->rpz;
if(!r->taglist || taglist_intersect(r->taglist, if(!r->disabled && (!r->taglist || taglist_intersect(r->taglist,
r->taglistlen, taglist, taglen)) { r->taglistlen, taglist, taglen))) {
z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len, z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len,
qinfo->qclass, 0, 0, 0); qinfo->qclass, 0, 0, 0);
if(z && r->action_override == RPZ_DISABLED_ACTION) { if(z && r->action_override == RPZ_DISABLED_ACTION) {
@ -1032,3 +1045,17 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
return ret; return ret;
} }
void rpz_enable(struct rpz* r)
{
if(!r)
return;
r->disabled = 0;
}
void rpz_disable(struct rpz* r)
{
if(!r)
return;
r->disabled = 1;
}

View file

@ -99,6 +99,7 @@ struct rpz {
int log; int log;
char* log_name; char* log_name;
struct regional* region; struct regional* region;
int disabled;
}; };
/** /**
@ -198,4 +199,16 @@ void rpz_finish_config(struct rpz* r);
enum respip_action enum respip_action
rpz_action_to_respip_action(enum rpz_action a); rpz_action_to_respip_action(enum rpz_action a);
/**
* Enable RPZ
* @param r: RPZ struct to enable
*/
void rpz_enable(struct rpz* r);
/**
* Disable RPZ
* @param r: RPZ struct to disable
*/
void rpz_disable(struct rpz* r);
#endif /* SERVICES_RPZ_H */ #endif /* SERVICES_RPZ_H */

View file

@ -167,7 +167,7 @@ sldns_gmtime64_r(int64_t clock, struct tm *result)
static int64_t static int64_t
sldns_serial_arithmetics_time(int32_t time, time_t now) sldns_serial_arithmetics_time(int32_t time, time_t now)
{ {
int32_t offset = time - (int32_t) now; int32_t offset = (int32_t)((uint32_t) time - (uint32_t) now);
return (int64_t) now + offset; return (int64_t) now + offset;
} }
@ -619,13 +619,18 @@ size_t sldns_b64_ntop_calculate_size(size_t srcsize)
* *
* This routine does not insert spaces or linebreaks after 76 characters. * This routine does not insert spaces or linebreaks after 76 characters.
*/ */
int sldns_b64_ntop(uint8_t const *src, size_t srclength, static int sldns_b64_ntop_base(uint8_t const *src, size_t srclength,
char *target, size_t targsize) char *target, size_t targsize, int base64url, int padding)
{ {
const char* b64 = char* b64;
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const char pad64 = '='; const char pad64 = '=';
size_t i = 0, o = 0; size_t i = 0, o = 0;
if(base64url)
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789-_";
else
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789+/";
if(targsize < sldns_b64_ntop_calculate_size(srclength)) if(targsize < sldns_b64_ntop_calculate_size(srclength))
return -1; return -1;
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */ /* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
@ -645,18 +650,26 @@ int sldns_b64_ntop(uint8_t const *src, size_t srclength,
target[o] = b64[src[i] >> 2]; target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ]; target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ]; target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
target[o+3] = pad64; if(padding) {
/* i += 2; */ target[o+3] = pad64;
o += 4; /* i += 2; */
o += 4;
} else {
o += 3;
}
break; break;
case 1: case 1:
/* one at end, converted into A B = = */ /* one at end, converted into A B = = */
target[o] = b64[src[i] >> 2]; target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) ]; target[o+1] = b64[ ((src[i]&0x03)<<4) ];
target[o+2] = pad64; if(padding) {
target[o+3] = pad64; target[o+2] = pad64;
/* i += 1; */ target[o+3] = pad64;
o += 4; /* i += 1; */
o += 4;
} else {
o += 2;
}
break; break;
case 0: case 0:
default: default:
@ -669,19 +682,36 @@ int sldns_b64_ntop(uint8_t const *src, size_t srclength,
return (int)o; return (int)o;
} }
int sldns_b64_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return sldns_b64_ntop_base(src, srclength, target, targsize,
0 /* no base64url */, 1 /* padding */);
}
int sldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return sldns_b64_ntop_base(src, srclength, target, targsize,
1 /* base64url */, 0 /* no padding */);
}
size_t sldns_b64_pton_calculate_size(size_t srcsize) size_t sldns_b64_pton_calculate_size(size_t srcsize)
{ {
return (((((srcsize + 3) / 4) * 3)) + 1); return (((((srcsize + 3) / 4) * 3)) + 1);
} }
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize) /* padding not required if srcsize is set */
static int sldns_b64_pton_base(char const *src, size_t srcsize, uint8_t *target,
size_t targsize, int base64url)
{ {
const uint8_t pad64 = 64; /* is 64th in the b64 array */ const uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src; const char* s = src;
uint8_t in[4]; uint8_t in[4];
size_t o = 0, incount = 0; size_t o = 0, incount = 0;
int check_padding = (srcsize) ? 0 : 1;
while(*s) { while(*s && (check_padding || srcsize)) {
/* skip any character that is not base64 */ /* skip any character that is not base64 */
/* conceptually we do: /* conceptually we do:
const char* b64 = pad'=' is appended to array const char* b64 = pad'=' is appended to array
@ -690,30 +720,43 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
and use d-b64; and use d-b64;
*/ */
char d = *s++; char d = *s++;
srcsize--;
if(d <= 'Z' && d >= 'A') if(d <= 'Z' && d >= 'A')
d -= 'A'; d -= 'A';
else if(d <= 'z' && d >= 'a') else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26; d = d - 'a' + 26;
else if(d <= '9' && d >= '0') else if(d <= '9' && d >= '0')
d = d - '0' + 52; d = d - '0' + 52;
else if(d == '+') else if(!base64url && d == '+')
d = 62; d = 62;
else if(d == '/') else if(base64url && d == '-')
d = 62;
else if(!base64url && d == '/')
d = 63; d = 63;
else if(d == '=') else if(base64url && d == '_')
d = 63;
else if(d == '=') {
if(!check_padding)
continue;
d = 64; d = 64;
else continue; } else continue;
in[incount++] = (uint8_t)d; in[incount++] = (uint8_t)d;
if(incount != 4) /* work on block of 4, unless padding is not used and there are
* less than 4 chars left */
if(incount != 4 && (check_padding || srcsize))
continue; continue;
assert(!check_padding || incount==4);
/* process whole block of 4 characters into 3 output bytes */ /* process whole block of 4 characters into 3 output bytes */
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */ if((incount == 2 ||
(incount == 4 && in[3] == pad64 && in[2] == pad64))) { /* A B = = */
if(o+1 > targsize) if(o+1 > targsize)
return -1; return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1; o += 1;
break; /* we are done */ break; /* we are done */
} else if(in[3] == pad64) { /* A B C = */ } else if(incount == 3 ||
(incount == 4 && in[3] == pad64)) { /* A B C = */
if(o+2 > targsize) if(o+2 > targsize)
return -1; return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -721,7 +764,7 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
o += 2; o += 2;
break; /* we are done */ break; /* we are done */
} else { } else {
if(o+3 > targsize) if(incount != 4 || o+3 > targsize)
return -1; return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */ /* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -733,3 +776,17 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
} }
return (int)o; return (int)o;
} }
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
{
return sldns_b64_pton_base(src, 0, target, targsize, 0);
}
int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize)
{
if(!srcsize) {
return 0;
}
return sldns_b64_pton_base(src, srcsize, target, targsize, 1);
}

View file

@ -92,13 +92,16 @@ size_t sldns_b64_ntop_calculate_size(size_t srcsize);
int sldns_b64_ntop(uint8_t const *src, size_t srclength, int sldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize); char *target, size_t targsize);
int sldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize);
/** /**
* calculates the size needed to store the result of sldns_b64_pton * calculates the size needed to store the result of sldns_b64_pton
*/ */
size_t sldns_b64_pton_calculate_size(size_t srcsize); size_t sldns_b64_pton_calculate_size(size_t srcsize);
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize); int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize);
/** /**
* calculates the size needed to store the result of b32_ntop * calculates the size needed to store the result of b32_ntop

View file

@ -426,7 +426,8 @@ enum sldns_enum_edns_option
LDNS_EDNS_N3U = 7, /* RFC6975 */ LDNS_EDNS_N3U = 7, /* RFC6975 */
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */ LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/ LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
LDNS_EDNS_PADDING = 12 /* RFC7830 */ LDNS_EDNS_PADDING = 12, /* RFC7830 */
LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
}; };
typedef enum sldns_enum_edns_option sldns_edns_option; typedef enum sldns_enum_edns_option sldns_edns_option;

View file

@ -155,6 +155,36 @@
char* wsa_strerror(int err); char* wsa_strerror(int err);
#endif #endif
static const char ICANN_UPDATE_CA[] =
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
"-----BEGIN CERTIFICATE-----\n"
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
"-----END CERTIFICATE-----\n";
static const char DS_TRUST_ANCHOR[] =
/* The anchors must start on a new line with ". IN DS and end with \n"[;]
* because the makedist script greps on the source here */
/* anchor 20326 is from 2017 */
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n";
/** verbosity for this application */ /** verbosity for this application */
static int verb = 0; static int verb = 0;
@ -213,48 +243,21 @@ usage(void)
static const char* static const char*
get_builtin_cert(void) get_builtin_cert(void)
{ {
return return ICANN_UPDATE_CA;
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
"-----BEGIN CERTIFICATE-----\n"
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
"-----END CERTIFICATE-----\n"
;
} }
/** return the built in root DS trust anchor */ /** return the built in root DS trust anchor */
static const char* static const char*
get_builtin_ds(void) get_builtin_ds(void)
{ {
return return DS_TRUST_ANCHOR;
/* The anchors must start on a new line with ". IN DS and end with \n"[;]
* because the makedist script greps on the source here */
/* anchor 20326 is from 2017 */
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n";
} }
/** print hex data */ /** print hex data */
static void static void
print_data(const char* msg, const char* data, int len) print_data(const char* msg, const char* data, size_t len)
{ {
int i; size_t i;
printf("%s: ", msg); printf("%s: ", msg);
for(i=0; i<len; i++) { for(i=0; i<len; i++) {
printf(" %2.2x", (unsigned char)data[i]); printf(" %2.2x", (unsigned char)data[i]);
@ -1110,7 +1113,7 @@ read_http_result(SSL* ssl)
data = read_data_chunk(ssl, len); data = read_data_chunk(ssl, len);
} }
if(!data) return NULL; if(!data) return NULL;
if(verb >= 4) print_data("read data", data, (int)len); if(verb >= 4) print_data("read data", data, len);
m = BIO_new(BIO_s_mem()); m = BIO_new(BIO_s_mem());
if(!m) { if(!m) {
if(verb) printf("out of memory\n"); if(verb) printf("out of memory\n");

View file

@ -58,6 +58,7 @@
#include "services/authzone.h" #include "services/authzone.h"
#include "respip/respip.h" #include "respip/respip.h"
#include "sldns/sbuffer.h" #include "sldns/sbuffer.h"
#include "sldns/str2wire.h"
#ifdef HAVE_GETOPT_H #ifdef HAVE_GETOPT_H
#include <getopt.h> #include <getopt.h>
#endif #endif
@ -196,6 +197,94 @@ localzonechecks(struct config_file* cfg)
local_zones_delete(zs); local_zones_delete(zs);
} }
/** checks for acl and views */
static void
acl_view_tag_checks(struct config_file* cfg, struct views* views)
{
int d;
struct sockaddr_storage a;
socklen_t alen;
struct config_str2list* acl;
struct config_str3list* s3;
struct config_strbytelist* sb;
/* acl_view */
for(acl=cfg->acl_view; acl; acl = acl->next) {
struct view* v;
if(!netblockstrtoaddr(acl->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-view "
"address %s %s", acl->str, acl->str2);
}
v = views_find_view(views, acl->str2, 0);
if(!v) {
fatal_exit("cannot find view for "
"access-control-view: %s %s",
acl->str, acl->str2);
}
lock_rw_unlock(&v->lock);
}
/* acl_tags */
for(sb=cfg->acl_tags; sb; sb = sb->next) {
if(!netblockstrtoaddr(sb->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-tags "
"address %s", sb->str);
}
}
/* acl_tag_actions */
for(s3=cfg->acl_tag_actions; s3; s3 = s3->next) {
enum localzone_type t;
if(!netblockstrtoaddr(s3->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-tag-actions "
"address %s %s %s",
s3->str, s3->str2, s3->str3);
}
if(find_tag_id(cfg, s3->str2) == -1) {
fatal_exit("cannot parse tag %s (define-tag it), "
"for access-control-tag-actions: %s %s %s",
s3->str2, s3->str, s3->str2, s3->str3);
}
if(!local_zone_str2type(s3->str3, &t)) {
fatal_exit("cannot parse access control action type %s"
" for access-control-tag-actions: %s %s %s",
s3->str3, s3->str, s3->str2, s3->str3);
}
}
/* acl_tag_datas */
for(s3=cfg->acl_tag_datas; s3; s3 = s3->next) {
char buf[65536];
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t len = sizeof(rr);
int res;
if(!netblockstrtoaddr(s3->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-tag-datas address %s %s '%s'",
s3->str, s3->str2, s3->str3);
}
if(find_tag_id(cfg, s3->str2) == -1) {
fatal_exit("cannot parse tag %s (define-tag it), "
"for access-control-tag-datas: %s %s '%s'",
s3->str2, s3->str, s3->str2, s3->str3);
}
/* '.' is sufficient for validation, and it makes the call to
* sldns_wirerr_get_type() simpler below. */
snprintf(buf, sizeof(buf), "%s %s", ".", s3->str3);
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL,
0, NULL, 0);
if(res != 0) {
fatal_exit("cannot parse rr data [char %d] parse error %s, for access-control-tag-datas: %s %s '%s'",
(int)LDNS_WIREPARSE_OFFSET(res)-2,
sldns_get_errorstr_parse(res),
s3->str, s3->str2, s3->str3);
}
}
}
/** check view and response-ip configuration */ /** check view and response-ip configuration */
static void static void
view_and_respipchecks(struct config_file* cfg) view_and_respipchecks(struct config_file* cfg)
@ -213,6 +302,7 @@ view_and_respipchecks(struct config_file* cfg)
fatal_exit("Could not setup respip set"); fatal_exit("Could not setup respip set");
if(!respip_views_apply_cfg(views, cfg, &ignored)) if(!respip_views_apply_cfg(views, cfg, &ignored))
fatal_exit("Could not setup per-view respip sets"); fatal_exit("Could not setup per-view respip sets");
acl_view_tag_checks(cfg, views);
views_delete(views); views_delete(views);
respip_set_delete(respip); respip_set_delete(respip);
} }
@ -536,8 +626,6 @@ morechecks(struct config_file* cfg)
cfg->auto_trust_anchor_file_list, cfg->chrootdir, cfg); cfg->auto_trust_anchor_file_list, cfg->chrootdir, cfg);
check_chroot_filelist_wild("trusted-keys-file", check_chroot_filelist_wild("trusted-keys-file",
cfg->trusted_keys_file_list, cfg->chrootdir, cfg); cfg->trusted_keys_file_list, cfg->chrootdir, cfg);
check_chroot_string("dlv-anchor-file", &cfg->dlv_anchor_file,
cfg->chrootdir, cfg);
#ifdef USE_IPSECMOD #ifdef USE_IPSECMOD
if(cfg->ipsecmod_enabled && strstr(cfg->module_conf, "ipsecmod")) { if(cfg->ipsecmod_enabled && strstr(cfg->module_conf, "ipsecmod")) {
/* only check hook if enabled */ /* only check hook if enabled */
@ -571,6 +659,64 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "python dns64 iterator") != 0 && strcmp(cfg->module_conf, "python dns64 iterator") != 0
&& strcmp(cfg->module_conf, "python dns64 validator iterator") != 0 && strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
#endif #endif
#ifdef WITH_DYNLIBMODULE
&& strcmp(cfg->module_conf, "dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip iterator") != 0
&& strcmp(cfg->module_conf, "dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip validator iterator") != 0
&& strcmp(cfg->module_conf, "validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "validator cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip validator cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "validator dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod respip validator dynlib iterator") != 0
#endif
#ifdef USE_CACHEDB #ifdef USE_CACHEDB
&& strcmp(cfg->module_conf, "validator cachedb iterator") != 0 && strcmp(cfg->module_conf, "validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0 && strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0

View file

@ -120,12 +120,19 @@ if [ ! -f "$SVR_BASE.key" ]; then
fi fi
cat >server.cnf <<EOF cat >server.cnf <<EOF
[req]
default_bits=$BITS default_bits=$BITS
default_md=$HASH default_md=$HASH
prompt=no prompt=no
distinguished_name=req_distinguished_name distinguished_name=req_distinguished_name
x509_extensions=v3_ca
[req_distinguished_name] [req_distinguished_name]
commonName=$SERVERNAME commonName=$SERVERNAME
[v3_ca]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints=critical,CA:TRUE,pathlen:0
subjectAltName=DNS:$SERVERNAME
EOF EOF
[ -f server.cnf ] || fatal "cannot create openssl configuration" [ -f server.cnf ] || fatal "cannot create openssl configuration"
@ -156,8 +163,12 @@ default_bits=$BITS
default_md=$HASH default_md=$HASH
prompt=no prompt=no
distinguished_name=req_distinguished_name distinguished_name=req_distinguished_name
req_extensions=v3_req
[req_distinguished_name] [req_distinguished_name]
commonName=$CLIENTNAME commonName=$CLIENTNAME
[v3_req]
basicConstraints=critical,CA:FALSE
subjectAltName=DNS:$CLIENTNAME
EOF EOF
[ -f client.cnf ] || fatal "cannot create openssl configuration" [ -f client.cnf ] || fatal "cannot create openssl configuration"
@ -179,6 +190,8 @@ if [ ! -f "$CTL_BASE.pem" -o $RECREATE -eq 1 ]; then
-CAkey "$SVR_BASE.key" \ -CAkey "$SVR_BASE.key" \
-CAcreateserial \ -CAcreateserial \
-$HASH \ -$HASH \
-extfile client.cnf \
-extensions v3_req \
-out "$CTL_BASE.pem" -out "$CTL_BASE.pem"
[ ! -f "CTL_BASE.pem" ] || fatal "cannot create signed client certificate" [ ! -f "CTL_BASE.pem" ] || fatal "cannot create signed client certificate"

View file

@ -82,6 +82,9 @@ static void usage(void) ATTR_NORETURN;
static void ssl_err(const char* s) ATTR_NORETURN; static void ssl_err(const char* s) ATTR_NORETURN;
static void ssl_path_err(const char* s, const char *path) ATTR_NORETURN; static void ssl_path_err(const char* s, const char *path) ATTR_NORETURN;
/** timeout to wait for connection over stream, in msec */
#define UNBOUND_CONTROL_CONNECT_TIMEOUT 5000
/** Give unbound-control usage, and exit (1). */ /** Give unbound-control usage, and exit (1). */
static void static void
usage(void) usage(void)
@ -164,6 +167,9 @@ usage(void)
printf(" view_local_data_remove view name remove local-data in view\n"); printf(" view_local_data_remove view name remove local-data in view\n");
printf(" view_local_datas_remove view remove list of local-data from view\n"); printf(" view_local_datas_remove view remove list of local-data from view\n");
printf(" one entry per line read from stdin\n"); printf(" one entry per line read from stdin\n");
printf(" rpz_enable zone Enable the RPZ zone if it had previously\n");
printf(" been disabled\n");
printf(" rpz_disable zone Disable the RPZ zone\n");
printf("Version %s\n", PACKAGE_VERSION); printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n"); printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT); printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
@ -268,6 +274,9 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
#ifdef USE_IPSECMOD #ifdef USE_IPSECMOD
PR_LL("mem.mod.ipsecmod", shm_stat->mem.ipsecmod); PR_LL("mem.mod.ipsecmod", shm_stat->mem.ipsecmod);
#endif #endif
#ifdef WITH_DYNLIBMODULE
PR_LL("mem.mod.dynlib", shm_stat->mem.dynlib);
#endif
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT
PR_LL("mem.cache.dnscrypt_shared_secret", PR_LL("mem.cache.dnscrypt_shared_secret",
shm_stat->mem.dnscrypt_shared_secret); shm_stat->mem.dnscrypt_shared_secret);
@ -275,6 +284,8 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
shm_stat->mem.dnscrypt_nonce); shm_stat->mem.dnscrypt_nonce);
#endif #endif
PR_LL("mem.streamwait", s->svr.mem_stream_wait); PR_LL("mem.streamwait", s->svr.mem_stream_wait);
PR_LL("mem.http.query_buffer", s->svr.mem_http2_query_buffer);
PR_LL("mem.http.response_buffer", s->svr.mem_http2_response_buffer);
} }
/** print histogram */ /** print histogram */
@ -339,6 +350,7 @@ static void print_extended(struct ub_stats_info* s)
PR_UL("num.query.tls", s->svr.qtls); PR_UL("num.query.tls", s->svr.qtls);
PR_UL("num.query.tls_resume", s->svr.qtls_resume); PR_UL("num.query.tls_resume", s->svr.qtls_resume);
PR_UL("num.query.ipv6", s->svr.qipv6); PR_UL("num.query.ipv6", s->svr.qipv6);
PR_UL("num.query.https", s->svr.qhttps);
/* flags */ /* flags */
PR_UL("num.query.flags.QR", s->svr.qbit_QR); PR_UL("num.query.flags.QR", s->svr.qbit_QR);
@ -539,6 +551,30 @@ setup_ctx(struct config_file* cfg)
return ctx; return ctx;
} }
/** check connect error */
static void
checkconnecterr(int err, const char* svr, struct sockaddr_storage* addr,
socklen_t addrlen, int statuscmd, int useport)
{
#ifndef USE_WINSOCK
if(!useport) log_err("connect: %s for %s", strerror(err), svr);
else log_err_addr("connect", strerror(err), addr, addrlen);
if(err == ECONNREFUSED && statuscmd) {
printf("unbound is stopped\n");
exit(3);
}
#else
int wsaerr = err;
if(!useport) log_err("connect: %s for %s", wsa_strerror(wsaerr), svr);
else log_err_addr("connect", wsa_strerror(wsaerr), addr, addrlen);
if(wsaerr == WSAECONNREFUSED && statuscmd) {
printf("unbound is stopped\n");
exit(3);
}
#endif
exit(1);
}
/** contact the server with TCP connect */ /** contact the server with TCP connect */
static int static int
contact_server(const char* svr, struct config_file* cfg, int statuscmd) contact_server(const char* svr, struct config_file* cfg, int statuscmd)
@ -590,32 +626,77 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
addrfamily = addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET; addrfamily = addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET;
fd = socket(addrfamily, SOCK_STREAM, proto); fd = socket(addrfamily, SOCK_STREAM, proto);
if(fd == -1) { if(fd == -1) {
#ifndef USE_WINSOCK fatal_exit("socket: %s", sock_strerror(errno));
fatal_exit("socket: %s", strerror(errno));
#else
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
fd_set_nonblock(fd);
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) { if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
int err = errno; #ifdef EINPROGRESS
if(!useport) log_err("connect: %s for %s", strerror(err), svr); if(errno != EINPROGRESS) {
else log_err_addr("connect", strerror(err), &addr, addrlen); checkconnecterr(errno, svr, &addr,
if(err == ECONNREFUSED && statuscmd) { addrlen, statuscmd, useport);
printf("unbound is stopped\n"); }
exit(3); #endif
} #else
#else if(WSAGetLastError() != WSAEINPROGRESS &&
int wsaerr = WSAGetLastError(); WSAGetLastError() != WSAEWOULDBLOCK) {
if(!useport) log_err("connect: %s for %s", wsa_strerror(wsaerr), svr); checkconnecterr(WSAGetLastError(), svr, &addr,
else log_err_addr("connect", wsa_strerror(wsaerr), &addr, addrlen); addrlen, statuscmd, useport);
if(wsaerr == WSAECONNREFUSED && statuscmd) {
printf("unbound is stopped\n");
exit(3);
} }
#endif #endif
exit(1);
} }
while(1) {
fd_set rset, wset, eset;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(FD_SET_T fd, &rset);
FD_ZERO(&wset);
FD_SET(FD_SET_T fd, &wset);
FD_ZERO(&eset);
FD_SET(FD_SET_T fd, &eset);
tv.tv_sec = UNBOUND_CONTROL_CONNECT_TIMEOUT/1000;
tv.tv_usec= (UNBOUND_CONTROL_CONNECT_TIMEOUT%1000)*1000;
if(select(fd+1, &rset, &wset, &eset, &tv) == -1) {
fatal_exit("select: %s", sock_strerror(errno));
}
if(!FD_ISSET(fd, &rset) && !FD_ISSET(fd, &wset) &&
!FD_ISSET(fd, &eset)) {
fatal_exit("timeout: could not connect to server");
} else {
/* check nonblocking connect error */
int error = 0;
socklen_t len = (socklen_t)sizeof(error);
if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error,
&len) < 0) {
#ifndef USE_WINSOCK
error = errno; /* on solaris errno is error */
#else
error = WSAGetLastError();
#endif
}
if(error != 0) {
#ifndef USE_WINSOCK
#ifdef EINPROGRESS
if(error == EINPROGRESS)
continue; /* try again later */
#endif
#ifdef EWOULDBLOCK
if(error == EWOULDBLOCK)
continue; /* try again later */
#endif
#else
if(error == WSAEINPROGRESS)
continue; /* try again later */
if(error == WSAEWOULDBLOCK)
continue; /* try again later */
#endif
checkconnecterr(error, svr, &addr, addrlen,
statuscmd, useport);
}
}
break;
}
fd_set_block(fd);
return fd; return fd;
} }
@ -678,11 +759,7 @@ remote_read(SSL* ssl, int fd, char* buf, size_t len)
/* EOF */ /* EOF */
return 0; return 0;
} }
#ifndef USE_WINSOCK fatal_exit("could not recv: %s", sock_strerror(errno));
fatal_exit("could not recv: %s", strerror(errno));
#else
fatal_exit("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
buf[rr] = 0; buf[rr] = 0;
} }
@ -698,11 +775,7 @@ remote_write(SSL* ssl, int fd, const char* buf, size_t len)
ssl_err("could not SSL_write"); ssl_err("could not SSL_write");
} else { } else {
if(send(fd, buf, len, 0) < (ssize_t)len) { if(send(fd, buf, len, 0) < (ssize_t)len) {
#ifndef USE_WINSOCK fatal_exit("could not send: %s", sock_strerror(errno));
fatal_exit("could not send: %s", strerror(errno));
#else
fatal_exit("could not send: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
} }
} }
@ -821,11 +894,7 @@ go(const char* cfgfile, char* svr, int quiet, int argc, char* argv[])
ret = go_cmd(ssl, fd, quiet, argc, argv); ret = go_cmd(ssl, fd, quiet, argc, argv);
if(ssl) SSL_free(ssl); if(ssl) SSL_free(ssl);
#ifndef USE_WINSOCK sock_close(fd);
close(fd);
#else
closesocket(fd);
#endif
if(ctx) SSL_CTX_free(ctx); if(ctx) SSL_CTX_free(ctx);
config_delete(cfg); config_delete(cfg);
return ret; return ret;
@ -883,7 +952,7 @@ int main(int argc, char* argv[])
if(argc == 0) if(argc == 0)
usage(); usage();
if(argc >= 1 && strcmp(argv[0], "start")==0) { if(argc >= 1 && strcmp(argv[0], "start")==0) {
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH) #if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
fatal_exit("could not exec unbound: %s", fatal_exit("could not exec unbound: %s",
strerror(ENOSYS)); strerror(ENOSYS));
#else #else

View file

@ -46,6 +46,9 @@
#include "util/fptr_wlist.h" #include "util/fptr_wlist.h"
#include "util/log.h" #include "util/log.h"
#include "services/mesh.h" #include "services/mesh.h"
#ifdef USE_DNSTAP
#include "dnstap/dtstream.h"
#endif
void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len), uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),

View file

@ -372,11 +372,7 @@ service_send(struct ringbuf* ring, struct timeval* now, sldns_buffer* pkt,
sldns_buffer_limit(pkt), 0, sldns_buffer_limit(pkt), 0,
(struct sockaddr*)srv_addr, srv_len); (struct sockaddr*)srv_addr, srv_len);
if(sent == -1) { if(sent == -1) {
#ifndef USE_WINSOCK log_err("sendto: %s", sock_strerror(errno));
log_err("sendto: %s", strerror(errno));
#else
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
#endif
} else if(sent != (ssize_t)sldns_buffer_limit(pkt)) { } else if(sent != (ssize_t)sldns_buffer_limit(pkt)) {
log_err("sendto: partial send"); log_err("sendto: partial send");
} }
@ -398,13 +394,12 @@ do_proxy(struct proxy* p, int retsock, sldns_buffer* pkt)
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EAGAIN || errno == EINTR) if(errno == EAGAIN || errno == EINTR)
return; return;
log_err("recv: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS || if(WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAEWOULDBLOCK) WSAGetLastError() == WSAEWOULDBLOCK)
return; return;
log_err("recv: %s", wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("recv: %s", sock_strerror(errno));
return; return;
} }
sldns_buffer_set_limit(pkt, (size_t)r); sldns_buffer_set_limit(pkt, (size_t)r);
@ -414,11 +409,7 @@ do_proxy(struct proxy* p, int retsock, sldns_buffer* pkt)
r = sendto(retsock, (void*)sldns_buffer_begin(pkt), (size_t)r, r = sendto(retsock, (void*)sldns_buffer_begin(pkt), (size_t)r,
0, (struct sockaddr*)&p->addr, p->addr_len); 0, (struct sockaddr*)&p->addr, p->addr_len);
if(r == -1) { if(r == -1) {
#ifndef USE_WINSOCK log_err("sendto: %s", sock_strerror(errno));
log_err("sendto: %s", strerror(errno));
#else
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
} }
} }
@ -469,11 +460,7 @@ find_create_proxy(struct sockaddr_storage* from, socklen_t from_len,
if(!p) fatal_exit("out of memory"); if(!p) fatal_exit("out of memory");
p->s = socket(serv_ip6?AF_INET6:AF_INET, SOCK_DGRAM, 0); p->s = socket(serv_ip6?AF_INET6:AF_INET, SOCK_DGRAM, 0);
if(p->s == -1) { if(p->s == -1) {
#ifndef USE_WINSOCK fatal_exit("socket: %s", sock_strerror(errno));
fatal_exit("socket: %s", strerror(errno));
#else
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
fd_set_nonblock(p->s); fd_set_nonblock(p->s);
memmove(&p->addr, from, from_len); memmove(&p->addr, from, from_len);
@ -507,14 +494,12 @@ service_recv(int s, struct ringbuf* ring, sldns_buffer* pkt,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EAGAIN || errno == EINTR) if(errno == EAGAIN || errno == EINTR)
return; return;
fatal_exit("recvfrom: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEWOULDBLOCK || if(WSAGetLastError() == WSAEWOULDBLOCK ||
WSAGetLastError() == WSAEINPROGRESS) WSAGetLastError() == WSAEINPROGRESS)
return; return;
fatal_exit("recvfrom: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
fatal_exit("recvfrom: %s", sock_strerror(errno));
} }
sldns_buffer_set_limit(pkt, (size_t)len); sldns_buffer_set_limit(pkt, (size_t)len);
/* find its proxy element */ /* find its proxy element */
@ -550,15 +535,9 @@ tcp_proxy_delete(struct tcp_proxy* p)
free(s); free(s);
s = sn; s = sn;
} }
#ifndef USE_WINSOCK sock_close(p->client_s);
close(p->client_s);
if(p->server_s != -1) if(p->server_s != -1)
close(p->server_s); sock_close(p->server_s);
#else
closesocket(p->client_s);
if(p->server_s != -1)
closesocket(p->server_s);
#endif
free(p); free(p);
} }
@ -577,14 +556,13 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EAGAIN || errno == EINTR) if(errno == EAGAIN || errno == EINTR)
return; return;
fatal_exit("accept: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEWOULDBLOCK || if(WSAGetLastError() == WSAEWOULDBLOCK ||
WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAECONNRESET) WSAGetLastError() == WSAECONNRESET)
return; return;
fatal_exit("accept: %s", wsa_strerror(WSAGetLastError()));
#endif #endif
fatal_exit("accept: %s", sock_strerror(errno));
} }
p = (struct tcp_proxy*)calloc(1, sizeof(*p)); p = (struct tcp_proxy*)calloc(1, sizeof(*p));
if(!p) fatal_exit("out of memory"); if(!p) fatal_exit("out of memory");
@ -595,11 +573,7 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
p->server_s = socket(addr_is_ip6(srv_addr, srv_len)?AF_INET6:AF_INET, p->server_s = socket(addr_is_ip6(srv_addr, srv_len)?AF_INET6:AF_INET,
SOCK_STREAM, 0); SOCK_STREAM, 0);
if(p->server_s == -1) { if(p->server_s == -1) {
#ifndef USE_WINSOCK fatal_exit("tcp socket: %s", sock_strerror(errno));
fatal_exit("tcp socket: %s", strerror(errno));
#else
fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
fd_set_nonblock(p->client_s); fd_set_nonblock(p->client_s);
fd_set_nonblock(p->server_s); fd_set_nonblock(p->server_s);
@ -607,16 +581,14 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno != EINPROGRESS) { if(errno != EINPROGRESS) {
log_err("tcp connect: %s", strerror(errno)); log_err("tcp connect: %s", strerror(errno));
close(p->server_s);
close(p->client_s);
#else #else
if(WSAGetLastError() != WSAEWOULDBLOCK && if(WSAGetLastError() != WSAEWOULDBLOCK &&
WSAGetLastError() != WSAEINPROGRESS) { WSAGetLastError() != WSAEINPROGRESS) {
log_err("tcp connect: %s", log_err("tcp connect: %s",
wsa_strerror(WSAGetLastError())); wsa_strerror(WSAGetLastError()));
closesocket(p->server_s);
closesocket(p->client_s);
#endif #endif
sock_close(p->server_s);
sock_close(p->client_s);
free(p); free(p);
return; return;
} }
@ -650,13 +622,12 @@ tcp_relay_read(int s, struct tcp_send_list** first,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
return 1; return 1;
log_err("tcp read: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEINPROGRESS || if(WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAEWOULDBLOCK) WSAGetLastError() == WSAEWOULDBLOCK)
return 1; return 1;
log_err("tcp read: %s", wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("tcp read: %s", sock_strerror(errno));
return 0; return 0;
} else if(r == 0) { } else if(r == 0) {
/* connection closed */ /* connection closed */
@ -708,14 +679,12 @@ tcp_relay_write(int s, struct tcp_send_list** first,
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EAGAIN || errno == EINTR) if(errno == EAGAIN || errno == EINTR)
return 1; return 1;
log_err("tcp write: %s", strerror(errno));
#else #else
if(WSAGetLastError() == WSAEWOULDBLOCK || if(WSAGetLastError() == WSAEWOULDBLOCK ||
WSAGetLastError() == WSAEINPROGRESS) WSAGetLastError() == WSAEINPROGRESS)
return 1; return 1;
log_err("tcp write: %s",
wsa_strerror(WSAGetLastError()));
#endif #endif
log_err("tcp write: %s", sock_strerror(errno));
return 0; return 0;
} else if(r == 0) { } else if(r == 0) {
/* closed */ /* closed */
@ -769,11 +738,7 @@ service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now,
log_addr(1, "read tcp answer", &p->addr, p->addr_len); log_addr(1, "read tcp answer", &p->addr, p->addr_len);
if(!tcp_relay_read(p->server_s, &p->answerlist, if(!tcp_relay_read(p->server_s, &p->answerlist,
&p->answerlast, now, delay, pkt)) { &p->answerlast, now, delay, pkt)) {
#ifndef USE_WINSOCK sock_close(p->server_s);
close(p->server_s);
#else
closesocket(p->server_s);
#endif
FD_CLR(FD_SET_T p->server_s, worig); FD_CLR(FD_SET_T p->server_s, worig);
FD_CLR(FD_SET_T p->server_s, rorig); FD_CLR(FD_SET_T p->server_s, rorig);
p->server_s = -1; p->server_s = -1;
@ -901,11 +866,7 @@ proxy_list_clear(struct proxy* p)
"%u returned\n", i++, from, port, (int)p->numreuse+1, "%u returned\n", i++, from, port, (int)p->numreuse+1,
(unsigned)p->numwait, (unsigned)p->numsent, (unsigned)p->numwait, (unsigned)p->numsent,
(unsigned)p->numreturn); (unsigned)p->numreturn);
#ifndef USE_WINSOCK sock_close(p->s);
close(p->s);
#else
closesocket(p->s);
#endif
free(p); free(p);
p = np; p = np;
} }
@ -1034,11 +995,7 @@ service(const char* bind_str, int bindport, const char* serv_str,
/* bind UDP port */ /* bind UDP port */
if((s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET, if((s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
SOCK_DGRAM, 0)) == -1) { SOCK_DGRAM, 0)) == -1) {
#ifndef USE_WINSOCK fatal_exit("socket: %s", sock_strerror(errno));
fatal_exit("socket: %s", strerror(errno));
#else
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
i=0; i=0;
if(bindport == 0) { if(bindport == 0) {
@ -1051,11 +1008,7 @@ service(const char* bind_str, int bindport, const char* serv_str,
exit(1); exit(1);
} }
if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1) { if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
#ifndef USE_WINSOCK log_err("bind: %s", sock_strerror(errno));
log_err("bind: %s", strerror(errno));
#else
log_err("bind: %s", wsa_strerror(WSAGetLastError()));
#endif
if(i--==0) if(i--==0)
fatal_exit("cannot bind any port"); fatal_exit("cannot bind any port");
bindport = 1024 + ((int)arc4random())%64000; bindport = 1024 + ((int)arc4random())%64000;
@ -1065,39 +1018,22 @@ service(const char* bind_str, int bindport, const char* serv_str,
/* and TCP port */ /* and TCP port */
if((listen_s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET, if((listen_s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
SOCK_STREAM, 0)) == -1) { SOCK_STREAM, 0)) == -1) {
#ifndef USE_WINSOCK fatal_exit("tcp socket: %s", sock_strerror(errno));
fatal_exit("tcp socket: %s", strerror(errno));
#else
fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
#ifdef SO_REUSEADDR #ifdef SO_REUSEADDR
if(1) { if(1) {
int on = 1; int on = 1;
if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0) (socklen_t)sizeof(on)) < 0)
#ifndef USE_WINSOCK
fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s", fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
strerror(errno)); sock_strerror(errno));
#else
fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
wsa_strerror(WSAGetLastError()));
#endif
} }
#endif #endif
if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1) { if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
#ifndef USE_WINSOCK fatal_exit("tcp bind: %s", sock_strerror(errno));
fatal_exit("tcp bind: %s", strerror(errno));
#else
fatal_exit("tcp bind: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
if(listen(listen_s, 5) == -1) { if(listen(listen_s, 5) == -1) {
#ifndef USE_WINSOCK fatal_exit("tcp listen: %s", sock_strerror(errno));
fatal_exit("tcp listen: %s", strerror(errno));
#else
fatal_exit("tcp listen: %s", wsa_strerror(WSAGetLastError()));
#endif
} }
fd_set_nonblock(listen_s); fd_set_nonblock(listen_s);
printf("listening on port: %d\n", bindport); printf("listening on port: %d\n", bindport);
@ -1109,13 +1045,8 @@ service(const char* bind_str, int bindport, const char* serv_str,
/* cleanup */ /* cleanup */
verbose(1, "cleanup"); verbose(1, "cleanup");
#ifndef USE_WINSOCK sock_close(s);
close(s); sock_close(listen_s);
close(listen_s);
#else
closesocket(s);
closesocket(listen_s);
#endif
sldns_buffer_free(pkt); sldns_buffer_free(pkt);
ring_delete(ring); ring_delete(ring);
} }

View file

@ -29,6 +29,9 @@ else
HAVE_MINGW=no HAVE_MINGW=no
fi fi
# stop tests from notifying systemd, if that is compiled in.
export -n NOTIFY_SOCKET
cd testdata; cd testdata;
sh ../testcode/mini_tdir.sh clean sh ../testcode/mini_tdir.sh clean
rm -f .perfstats.txt rm -f .perfstats.txt

638
testcode/dohclient.c Normal file
View file

@ -0,0 +1,638 @@
/*
* testcode/dohclient.c - debug program. Perform multiple DNS queries using DoH.
*
* Copyright (c) 2020, 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
*
* Simple DNS-over-HTTPS client. For testing and debugging purposes.
* No authentication of TLS cert.
*/
#include "config.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include "sldns/wire2str.h"
#include "sldns/sbuffer.h"
#include "sldns/str2wire.h"
#include "sldns/parseutil.h"
#include "util/data/msgencode.h"
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"
#include "util/net_help.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
#ifdef HAVE_NGHTTP2
#include <nghttp2/nghttp2.h>
struct http2_session {
nghttp2_session* session;
SSL* ssl;
int fd;
int query_count;
/* Use POST :method if 1 */
int post;
int block_select;
const char* authority;
const char* endpoint;
const char* content_type;
};
struct http2_stream {
int32_t stream_id;
int res_status;
struct sldns_buffer* buf;
char* path;
};
static void usage(char* argv[])
{
printf("usage: %s [options] name type class ...\n", argv[0]);
printf(" sends the name-type-class queries over "
"DNS-over-HTTPS.\n");
printf("-s server IP address to send the queries to, "
"default: 127.0.0.1\n");
printf("-p Port to connect to, default: %d\n",
UNBOUND_DNS_OVER_HTTPS_PORT);
printf("-P Use POST method instead of default GET\n");
printf("-e HTTP endpoint, default: /dns-query\n");
printf("-c Content-type in request, default: "
"application/dns-message\n");
printf("-n no-tls, TLS is disabled\n");
printf("-h This help text\n");
exit(1);
}
/** open TCP socket to svr */
static int
open_svr(const char* svr, int port)
{
struct sockaddr_storage addr;
socklen_t addrlen;
int fd = -1;
int r;
if(!ipstrtoaddr(svr, port, &addr, &addrlen)) {
printf("fatal: bad server specs '%s'\n", svr);
exit(1);
}
fd = socket(addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET,
SOCK_STREAM, 0);
if(fd == -1) {
perror("socket() error");
exit(1);
}
r = connect(fd, (struct sockaddr*)&addr, addrlen);
if(r < 0 && r != EINPROGRESS) {
perror("connect() error");
exit(1);
}
return fd;
}
static ssize_t http2_submit_request_read_cb(
nghttp2_session* ATTR_UNUSED(session),
int32_t ATTR_UNUSED(stream_id), uint8_t* buf, size_t length,
uint32_t* data_flags, nghttp2_data_source* source,
void* ATTR_UNUSED(cb_arg))
{
if(length > sldns_buffer_remaining(source->ptr))
length = sldns_buffer_remaining(source->ptr);
memcpy(buf, sldns_buffer_current(source->ptr), length);
sldns_buffer_skip(source->ptr, length);
if(sldns_buffer_remaining(source->ptr) == 0) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
}
return length;
}
static void
submit_query(struct http2_session* h2_session, struct sldns_buffer* buf)
{
int32_t stream_id;
struct http2_stream* h2_stream;
nghttp2_nv headers[5];
char* qb64;
size_t qb64_size;
size_t qb64_expected_size;
size_t i;
nghttp2_data_provider data_prd;
h2_stream = calloc(1, sizeof(*h2_stream));
if(!h2_stream)
fatal_exit("could not malloc http2 stream");
h2_stream->buf = buf;
if(h2_session->post) {
data_prd.source.ptr = buf;
data_prd.read_callback = http2_submit_request_read_cb;
h2_stream->path = (char*)h2_session->endpoint;
} else {
qb64_expected_size = sldns_b64_ntop_calculate_size(
sldns_buffer_remaining(buf));
qb64 = malloc(qb64_expected_size);
if(!qb64) fatal_exit("out of memory");
qb64_size = sldns_b64url_ntop(sldns_buffer_begin(buf),
sldns_buffer_remaining(buf), qb64, qb64_expected_size);
h2_stream->path = malloc(strlen(
h2_session->endpoint)+strlen("?dns=")+qb64_size+1);
if(!h2_stream->path) fatal_exit("out of memory");
snprintf(h2_stream->path, strlen(h2_session->endpoint)+
strlen("?dns=")+qb64_size+1, "%s?dns=%s",
h2_session->endpoint, qb64);
free(qb64);
}
headers[0].name = (uint8_t*)":method";
if(h2_session->post)
headers[0].value = (uint8_t*)"POST";
else
headers[0].value = (uint8_t*)"GET";
headers[1].name = (uint8_t*)":path";
headers[1].value = (uint8_t*)h2_stream->path;
headers[2].name = (uint8_t*)":scheme";
if(h2_session->ssl)
headers[2].value = (uint8_t*)"https";
else
headers[2].value = (uint8_t*)"http";
headers[3].name = (uint8_t*)":authority";
headers[3].value = (uint8_t*)h2_session->authority;
headers[4].name = (uint8_t*)"content-type";
headers[4].value = (uint8_t*)h2_session->content_type;
printf("Request headers\n");
for(i=0; i<sizeof(headers)/sizeof(headers[0]); i++) {
headers[i].namelen = strlen((char*)headers[i].name);
headers[i].valuelen = strlen((char*)headers[i].value);
headers[i].flags = NGHTTP2_NV_FLAG_NONE;
printf("%s: %s\n", headers[i].name, headers[i].value);
}
stream_id = nghttp2_submit_request(h2_session->session, NULL, headers,
sizeof(headers)/sizeof(headers[0]),
(h2_session->post) ? &data_prd : NULL, h2_stream);
if(stream_id < 0) {
printf("Failed to submit nghttp2 request");
exit(1);
}
h2_session->query_count++;
h2_stream->stream_id = stream_id;
}
static sldns_buffer*
make_query(char* qname, char* qtype, char* qclass)
{
struct query_info qinfo;
struct edns_data edns;
sldns_buffer* buf = sldns_buffer_new(65553);
if(!buf) fatal_exit("out of memory");
qinfo.qname = sldns_str2wire_dname(qname, &qinfo.qname_len);
if(!qinfo.qname) {
printf("cannot parse query name: '%s'\n", qname);
exit(1);
}
qinfo.qtype = sldns_get_rr_type_by_name(qtype);
qinfo.qclass = sldns_get_rr_class_by_name(qclass);
qinfo.local_alias = NULL;
qinfo_query_encode(buf, &qinfo); /* flips buffer */
free(qinfo.qname);
sldns_buffer_write_u16_at(buf, 0, 0x0000);
sldns_buffer_write_u16_at(buf, 2, BIT_RD);
memset(&edns, 0, sizeof(edns));
edns.edns_present = 1;
edns.bits = EDNS_DO;
edns.udp_size = 4096;
if(sldns_buffer_capacity(buf) >=
sldns_buffer_limit(buf)+calc_edns_field_size(&edns))
attach_edns_record(buf, &edns);
return buf;
}
static ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session),
uint8_t* buf, size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{
struct http2_session* h2_session = (struct http2_session*)cb_arg;
int r;
ssize_t ret;
struct timeval tv, *waittv;
fd_set rfd;
ERR_clear_error();
memset(&tv, 0, sizeof(tv));
if(h2_session->block_select && h2_session->query_count <= 0) {
return NGHTTP2_ERR_WOULDBLOCK;
}
if(h2_session->block_select)
waittv = NULL;
else
waittv = &tv;
memset(&rfd, 0, sizeof(rfd));
FD_ZERO(&rfd);
FD_SET(h2_session->fd, &rfd);
r = select(h2_session->fd+1, &rfd, NULL, NULL, waittv);
if(r <= 0) {
return NGHTTP2_ERR_WOULDBLOCK;
}
if(h2_session->ssl) {
r = SSL_read(h2_session->ssl, buf, len);
if(r <= 0) {
int want = SSL_get_error(h2_session->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_EOF;
}
log_crypto_err("could not SSL_read");
return NGHTTP2_ERR_EOF;
}
return r;
}
ret = read(h2_session->fd, buf, len);
if(ret == 0) {
return NGHTTP2_ERR_EOF;
} else if(ret < 0) {
log_err("could not http2 read: %s", strerror(errno));
return NGHTTP2_ERR_EOF;
}
return ret;
}
static ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session),
const uint8_t* buf, size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{
struct http2_session* h2_session = (struct http2_session*)cb_arg;
ssize_t ret;
if(h2_session->ssl) {
int r;
ERR_clear_error();
r = SSL_write(h2_session->ssl, buf, len);
if(r <= 0) {
int want = SSL_get_error(h2_session->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_write");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
}
ret = write(h2_session->fd, buf, len);
if(ret == 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
} else if(ret < 0) {
log_err("could not http2 write: %s", strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return ret;
}
static int http2_stream_close_cb(nghttp2_session* ATTR_UNUSED(session),
int32_t ATTR_UNUSED(stream_id),
nghttp2_error_code ATTR_UNUSED(error_code), void *cb_arg)
{
struct http2_session* h2_session = (struct http2_session*)cb_arg;
struct http2_stream* h2_stream;
if(!(h2_stream = nghttp2_session_get_stream_user_data(
h2_session->session, stream_id))) {
return 0;
}
h2_session->query_count--;
sldns_buffer_free(h2_stream->buf);
if(!h2_session->post)
free(h2_stream->path);
free(h2_stream);
h2_stream = NULL;
return 0;
}
static int http2_data_chunk_recv_cb(nghttp2_session* ATTR_UNUSED(session),
uint8_t ATTR_UNUSED(flags), int32_t stream_id, const uint8_t* data,
size_t len, void* cb_arg)
{
struct http2_session* h2_session = (struct http2_session*)cb_arg;
struct http2_stream* h2_stream;
if(!(h2_stream = nghttp2_session_get_stream_user_data(
h2_session->session, stream_id))) {
return 0;
}
if(sldns_buffer_remaining(h2_stream->buf) < len) {
log_err("received data chunck does not fit into buffer");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
sldns_buffer_write(h2_stream->buf, data, len);
return 0;
}
static int http2_frame_recv_cb(nghttp2_session *session,
const nghttp2_frame *frame, void* ATTR_UNUSED(cb_arg))
{
struct http2_stream* h2_stream;
if(!(h2_stream = nghttp2_session_get_stream_user_data(
session, frame->hd.stream_id)))
return 0;
if(frame->hd.type == NGHTTP2_HEADERS &&
frame->headers.cat == NGHTTP2_HCAT_RESPONSE) {
sldns_buffer_clear(h2_stream->buf);
}
if(((frame->hd.type != NGHTTP2_DATA &&
frame->hd.type != NGHTTP2_HEADERS) ||
frame->hd.flags & NGHTTP2_FLAG_END_STREAM) &&
h2_stream->res_status == 200) {
char* pktstr;
sldns_buffer_flip(h2_stream->buf);
pktstr = sldns_wire2str_pkt(
sldns_buffer_begin(h2_stream->buf),
sldns_buffer_limit(h2_stream->buf));
printf("%s\n", pktstr);
free(pktstr);
return 0;
}
return 0;
}
static int http2_header_cb(nghttp2_session* ATTR_UNUSED(session),
const nghttp2_frame* frame, const uint8_t* name, size_t namelen,
const uint8_t* value, size_t ATTR_UNUSED(valuelen),
uint8_t ATTR_UNUSED(flags), void* cb_arg)
{
struct http2_stream* h2_stream;
struct http2_session* h2_session = (struct http2_session*)cb_arg;
printf("%s %s\n", name, value);
if(namelen == 7 && memcmp(":status", name, namelen) == 0) {
if(!(h2_stream = nghttp2_session_get_stream_user_data(
h2_session->session, frame->hd.stream_id))) {
return 0;
}
h2_stream->res_status = atoi((char*)value);
}
return 0;
}
static struct http2_session*
http2_session_create()
{
struct http2_session* h2_session = calloc(1,
sizeof(struct http2_session));
nghttp2_session_callbacks* callbacks;
if(!h2_session)
fatal_exit("out of memory");
if(nghttp2_session_callbacks_new(&callbacks) == NGHTTP2_ERR_NOMEM) {
log_err("failed to initialize nghttp2 callback");
return NULL;
}
nghttp2_session_callbacks_set_recv_callback(callbacks, http2_recv_cb);
nghttp2_session_callbacks_set_send_callback(callbacks, http2_send_cb);
nghttp2_session_callbacks_set_on_stream_close_callback(callbacks,
http2_stream_close_cb);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks,
http2_data_chunk_recv_cb);
nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
http2_frame_recv_cb);
nghttp2_session_callbacks_set_on_header_callback(callbacks,
http2_header_cb);
nghttp2_session_client_new(&h2_session->session, callbacks, h2_session);
nghttp2_session_callbacks_del(callbacks);
return h2_session;
}
static void
http2_session_delete(struct http2_session* h2_session)
{
nghttp2_session_del(h2_session->session);
free(h2_session);
}
static void
http2_submit_setting(struct http2_session* h2_session)
{
int ret;
nghttp2_settings_entry settings[1] = {
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
100}};
ret = nghttp2_submit_settings(h2_session->session, NGHTTP2_FLAG_NONE,
settings, 1);
if(ret) {
printf("http2: submit_settings failed, "
"error: %s\n", nghttp2_strerror(ret));
exit(1);
}
}
static void
http2_write(struct http2_session* h2_session)
{
if(nghttp2_session_want_write(h2_session->session)) {
if(nghttp2_session_send(h2_session->session)) {
printf("nghttp2 session send failed\n");
exit(1);
}
}
}
static void
http2_read(struct http2_session* h2_session)
{
if(nghttp2_session_want_read(h2_session->session)) {
if(nghttp2_session_recv(h2_session->session)) {
printf("nghttp2 session mem_recv failed\n");
exit(1);
}
}
}
static void
run(struct http2_session* h2_session, int port, int no_tls, int count, char** q)
{
int i;
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
int fd;
struct sldns_buffer* buf = NULL;
fd = open_svr(h2_session->authority, port);
h2_session->fd = fd;
if(!no_tls) {
ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
if(!ctx) fatal_exit("cannot create ssl ctx");
SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)"\x02h2", 3);
ssl = outgoing_ssl_fd(ctx, fd);
if(!ssl) {
printf("cannot create ssl\n");
exit(1);
}
h2_session->ssl = ssl;
while(1) {
int r;
ERR_clear_error();
if( (r=SSL_do_handshake(ssl)) == 1)
break;
r = SSL_get_error(ssl, r);
if(r != SSL_ERROR_WANT_READ &&
r != SSL_ERROR_WANT_WRITE) {
log_crypto_err("could not ssl_handshake");
exit(1);
}
}
}
http2_submit_setting(h2_session);
http2_write(h2_session);
http2_read(h2_session); /* Read setting from remote peer */
h2_session->block_select = 1;
/* hande query */
for(i=0; i<count; i+=3) {
buf = make_query(q[i], q[i+1], q[i+2]);
submit_query(h2_session, buf);
}
http2_write(h2_session);
while(h2_session->query_count) {
http2_read(h2_session);
http2_write(h2_session);
}
/* shutdown */
http2_session_delete(h2_session);
if(ssl) {
SSL_shutdown(ssl);
SSL_free(ssl);
}
if(ctx) {
SSL_CTX_free(ctx);
}
close(fd);
}
/** getopt global, in case header files fail to declare it. */
extern int optind;
/** getopt global, in case header files fail to declare it. */
extern char* optarg;
int main(int argc, char** argv)
{
int c;
int port = UNBOUND_DNS_OVER_HTTPS_PORT, no_tls = 0;
struct http2_session* h2_session;
#ifdef USE_WINSOCK
WSADATA wsa_data;
if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
printf("WSAStartup failed\n");
return 1;
}
#endif
log_init(0, 0, 0);
checklock_start();
h2_session = http2_session_create();
if(!h2_session) fatal_exit("out of memory");
if(argc == 1) {
usage(argv);
}
h2_session->authority = "127.0.0.1";
h2_session->post = 0;
h2_session->endpoint = "/dns-query";
h2_session->content_type = "application/dns-message";
while((c=getopt(argc, argv, "c:e:hns:p:P")) != -1) {
switch(c) {
case 'c':
h2_session->content_type = optarg;
break;
case 'e':
h2_session->endpoint = optarg;
break;
case 'n':
no_tls = 1;
break;
case 'p':
if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
printf("error parsing port, "
"number expected: %s\n", optarg);
return 1;
}
port = atoi(optarg);
break;
case 'P':
h2_session->post = 1;
break;
case 's':
h2_session->authority = optarg;
break;
case 'h':
case '?':
default:
usage(argv);
}
}
argc -= optind;
argv += optind;
if(argc%3!=0) {
printf("Invalid input. Specify qname, qtype, and qclass.\n");
return 1;
}
run(h2_session, port, no_tls, argc, argv);
checklock_stop();
#ifdef USE_WINSOCK
WSACleanup();
#endif
return 0;
}
#else
int main(int ATTR_UNUSED(argc), char** ATTR_UNUSED(argv))
{
printf("Compiled without nghttp2, cannot run test.\n");
return 1;
}
#endif /* HAVE_NGHTTP2 */

View file

@ -52,6 +52,7 @@
#include "util/data/msgreply.h" #include "util/data/msgreply.h"
#include "util/data/msgencode.h" #include "util/data/msgencode.h"
#include "util/data/dname.h" #include "util/data/dname.h"
#include "util/edns.h"
#include "util/config_file.h" #include "util/config_file.h"
#include "services/listen_dnsport.h" #include "services/listen_dnsport.h"
#include "services/outside_network.h" #include "services/outside_network.h"
@ -63,6 +64,7 @@
#include "sldns/sbuffer.h" #include "sldns/sbuffer.h"
#include "sldns/wire2str.h" #include "sldns/wire2str.h"
#include "sldns/str2wire.h" #include "sldns/str2wire.h"
#include "daemon/remote.h"
#include <signal.h> #include <signal.h>
struct worker; struct worker;
struct daemon_remote; struct daemon_remote;
@ -868,9 +870,13 @@ struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports), listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
size_t bufsize, int ATTR_UNUSED(tcp_accept_count), size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
int ATTR_UNUSED(tcp_idle_timeout), int ATTR_UNUSED(tcp_idle_timeout),
int ATTR_UNUSED(harden_large_queries),
uint32_t ATTR_UNUSED(http_max_streams),
char* ATTR_UNUSED(http_endpoint),
int ATTR_UNUSED(http_notls),
struct tcl_list* ATTR_UNUSED(tcp_conn_limit), struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv), void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
comm_point_callback_type* cb, void* cb_arg) comm_point_callback_type* cb, void *cb_arg)
{ {
struct replay_runtime* runtime = (struct replay_runtime*)base; struct replay_runtime* runtime = (struct replay_runtime*)base;
struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport)); struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport));
@ -1040,7 +1046,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param), void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx), int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni), int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
struct dt_env* ATTR_UNUSED(dtenv)) struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect))
{ {
struct replay_runtime* runtime = (struct replay_runtime*)base; struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1, struct outside_network* outnet = calloc(1,
@ -1180,7 +1186,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
socklen_t addrlen, uint8_t* zone, size_t zonelen, socklen_t addrlen, uint8_t* zone, size_t zonelen,
struct module_qstate* qstate, comm_point_callback_type* callback, struct module_qstate* qstate, comm_point_callback_type* callback,
void* callback_arg, sldns_buffer* ATTR_UNUSED(buff), void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
struct module_env* ATTR_UNUSED(env)) struct module_env* env)
{ {
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
struct fake_pending* pend = (struct fake_pending*)calloc(1, struct fake_pending* pend = (struct fake_pending*)calloc(1,
@ -1209,6 +1215,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
sldns_buffer_flip(pend->buffer); sldns_buffer_flip(pend->buffer);
if(1) { if(1) {
struct edns_data edns; struct edns_data edns;
struct edns_string_addr* client_string_addr;
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen,
zone, zonelen, qstate, qstate->region)) { zone, zonelen, qstate, qstate->region)) {
free(pend); free(pend);
@ -1220,9 +1227,18 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
edns.edns_version = EDNS_ADVERTISED_VERSION; edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE; edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits = 0; edns.bits = 0;
edns.opt_list = qstate->edns_opts_back_out;
if(dnssec) if(dnssec)
edns.bits = EDNS_DO; edns.bits = EDNS_DO;
edns.padding_block_size = 0;
if((client_string_addr = edns_string_addr_lookup(
&env->edns_strings->client_strings,
addr, addrlen))) {
edns_opt_list_append(&qstate->edns_opts_back_out,
env->edns_strings->client_string_opcode,
client_string_addr->string_len,
client_string_addr->string, qstate->region);
}
edns.opt_list = qstate->edns_opts_back_out;
attach_edns_record(pend->buffer, &edns); attach_edns_record(pend->buffer, &edns);
} }
memcpy(&pend->addr, addr, addrlen); memcpy(&pend->addr, addr, addrlen);
@ -1290,7 +1306,14 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
log_info("double delete of pending serviced query"); log_info("double delete of pending serviced query");
} }
int resolve_interface_names(struct config_file* ATTR_UNUSED(cfg),
char*** ATTR_UNUSED(resif), int* ATTR_UNUSED(num_resif))
{
return 1;
}
struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg), struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg),
char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs),
int* ATTR_UNUSED(reuseport)) int* ATTR_UNUSED(reuseport))
{ {
return calloc(1, 1); return calloc(1, 1);
@ -1490,6 +1513,18 @@ int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
return 0; return 0;
} }
int reuse_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);
return 0;
}
int reuse_id_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);
return 0;
}
/* timers in testbound for autotrust. statistics tested in tdir. */ /* timers in testbound for autotrust. statistics tested in tdir. */
struct comm_timer* comm_timer_create(struct comm_base* base, struct comm_timer* comm_timer_create(struct comm_base* base,
void (*cb)(void*), void* cb_arg) void (*cb)(void*), void* cb_arg)
@ -1732,7 +1767,7 @@ struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
} }
int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
struct sockaddr* addr, socklen_t addrlen) struct sockaddr* addr, socklen_t addrlen, int ATTR_UNUSED(is_connected))
{ {
struct fake_commpoint* fc = (struct fake_commpoint*)c; struct fake_commpoint* fc = (struct fake_commpoint*)c;
struct replay_runtime* runtime = fc->runtime; struct replay_runtime* runtime = fc->runtime;
@ -1825,4 +1860,21 @@ tcp_req_info_get_stream_buffer_size(void)
return 0; return 0;
} }
size_t
http2_get_query_buffer_size(void)
{
return 0;
}
size_t
http2_get_response_buffer_size(void)
{
return 0;
}
void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
{
}
/*********** End of Dummy routines ***********/ /*********** End of Dummy routines ***********/

View file

@ -233,12 +233,7 @@ perfsetup(struct perfinfo* info)
addr_is_ip6(&info->dest, info->destlen)? addr_is_ip6(&info->dest, info->destlen)?
AF_INET6:AF_INET, SOCK_DGRAM, 0); AF_INET6:AF_INET, SOCK_DGRAM, 0);
if(info->io[i].fd == -1) { if(info->io[i].fd == -1) {
#ifndef USE_WINSOCK fatal_exit("socket: %s", sock_strerror(errno));
fatal_exit("socket: %s", strerror(errno));
#else
fatal_exit("socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
} }
if(info->io[i].fd > info->maxfd) if(info->io[i].fd > info->maxfd)
info->maxfd = info->io[i].fd; info->maxfd = info->io[i].fd;
@ -260,11 +255,7 @@ perffree(struct perfinfo* info)
if(!info) return; if(!info) return;
if(info->io) { if(info->io) {
for(i=0; i<info->io_num; i++) { for(i=0; i<info->io_num; i++) {
#ifndef USE_WINSOCK sock_close(info->io[i].fd);
close(info->io[i].fd);
#else
closesocket(info->io[i].fd);
#endif
} }
free(info->io); free(info->io);
} }
@ -285,11 +276,7 @@ perfsend(struct perfinfo* info, size_t n, struct timeval* now)
/*log_hex("send", info->qlist_data[info->qlist_idx], /*log_hex("send", info->qlist_data[info->qlist_idx],
info->qlist_len[info->qlist_idx]);*/ info->qlist_len[info->qlist_idx]);*/
if(r == -1) { if(r == -1) {
#ifndef USE_WINSOCK log_err("sendto: %s", sock_strerror(errno));
log_err("sendto: %s", strerror(errno));
#else
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
#endif
} else if(r != (ssize_t)info->qlist_len[info->qlist_idx]) { } else if(r != (ssize_t)info->qlist_len[info->qlist_idx]) {
log_err("partial sendto"); log_err("partial sendto");
} }
@ -309,11 +296,7 @@ perfreply(struct perfinfo* info, size_t n, struct timeval* now)
r = recv(info->io[n].fd, (void*)sldns_buffer_begin(info->buf), r = recv(info->io[n].fd, (void*)sldns_buffer_begin(info->buf),
sldns_buffer_capacity(info->buf), 0); sldns_buffer_capacity(info->buf), 0);
if(r == -1) { if(r == -1) {
#ifndef USE_WINSOCK log_err("recv: %s", sock_strerror(errno));
log_err("recv: %s", strerror(errno));
#else
log_err("recv: %s", wsa_strerror(WSAGetLastError()));
#endif
} else { } else {
info->by_rcode[LDNS_RCODE_WIRE(sldns_buffer_begin( info->by_rcode[LDNS_RCODE_WIRE(sldns_buffer_begin(
info->buf))]++; info->buf))]++;

View file

@ -26,15 +26,22 @@ cd testdata
TPKG=../testcode/mini_tdir.sh TPKG=../testcode/mini_tdir.sh
#RUNLIST=`(ls -1d *.tdir|grep -v '^0[016]')` #RUNLIST=`(ls -1d *.tdir|grep -v '^0[016]')`
RUNLIST=`(ls -1d *.tdir)` RUNLIST=`(ls -1d *.tdir)`
if test "$#" = "1"; then RUNLIST="$1"; fi if test "$#" = "1"; then
RUNLIST="$1";
if echo "$RUNLIST" | grep '/$' >/dev/null; then
RUNLIST=`echo "$RUNLIST" | sed -e 's?/$??'`
fi
fi
# fix up tdir that was edited on keyboard interrupt. # fix up tdir that was edited on keyboard interrupt.
cleanup() { cleanup() {
echo cleanup echo cleanup
if test -f "$t.bak"; then mv "$t.bak" "$t"; fi if test -f "$t.bak"; then rm -fr "${t}"; mv "$t.bak" "$t"; fi
exit 0 exit 0
} }
trap cleanup INT trap cleanup INT
# stop tests from notifying systemd, if that is compiled in.
export -n NOTIFY_SOCKET
for t in $RUNLIST for t in $RUNLIST
do do

View file

@ -200,6 +200,7 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
static void static void
recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf) recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
{ {
size_t i;
char* pktstr; char* pktstr;
uint16_t len; uint16_t len;
if(!udp) { if(!udp) {
@ -270,7 +271,13 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
len = (size_t)l; len = (size_t)l;
} }
printf("\nnext received packet\n"); printf("\nnext received packet\n");
log_buf(0, "data", buf); printf("data[%d] ", (int)sldns_buffer_limit(buf));
for(i=0; i<sldns_buffer_limit(buf); i++) {
const char* hex = "0123456789ABCDEF";
printf("%c%c", hex[(sldns_buffer_read_u8_at(buf, i)&0xf0)>>4],
hex[sldns_buffer_read_u8_at(buf, i)&0x0f]);
}
printf("\n");
pktstr = sldns_wire2str_pkt(sldns_buffer_begin(buf), len); pktstr = sldns_wire2str_pkt(sldns_buffer_begin(buf), len);
printf("%s", pktstr); printf("%s", pktstr);
@ -381,11 +388,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
SSL_free(ssl); SSL_free(ssl);
SSL_CTX_free(ctx); SSL_CTX_free(ctx);
} }
#ifndef USE_WINSOCK sock_close(fd);
close(fd);
#else
closesocket(fd);
#endif
sldns_buffer_free(buf); sldns_buffer_free(buf);
printf("orderly exit\n"); printf("orderly exit\n");
} }

Some files were not shown because too many files have changed in this diff Show more