IPSECMOD_SRC=ipsecmod/ipsecmod.c ipsecmod/ipsecmod-whitelist.c
IPSECMOD_OBJ=@IPSECMOD_OBJ@
IPSECMOD_HEADER=@IPSECMOD_HEADER@
+CACHEDB_SRC=@CACHEDB_SRC@
+CACHEDB_OBJ=@CACHEDB_OBJ@
COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \
util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \
util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
-cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
+$(CACHEDB_SRC) respip/respip.c $(CHECKLOCK_SRC) \
$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
autotrust.lo val_anchor.lo rpz.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
-val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
+val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo $(CACHEDB_OBJ) authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \
testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \
testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \
-testcode/unitecs.c testcode/unitauth.c
+testcode/unitecs.c testcode/unitauth.c testcode/unitzonemd.c \
+testcode/unittcpreuse.c
UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \
unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \
-readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo
+readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo unitzonemd.lo \
+unittcpreuse.lo
UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
$(COMPAT_OBJ)
DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
DELAYER_OBJ=delayer.lo
DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
+READZONE_SRC=testcode/readzone.c
+READZONE_OBJ=readzone.lo
+READZONE_OBJ_LINK=$(READZONE_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ)
IPSET_SRC=@IPSET_SRC@
IPSET_OBJ=@IPSET_OBJ@
DNSTAP_SOCKET_SRC=dnstap/unbound-dnstap-socket.c
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) \
- $(DOHCLIENT_SRC)
+ $(DOHCLIENT_SRC) $(READZONE_SRC)
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\
$(COMPAT_OBJ) $(PYUNBOUND_OBJ) \
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) \
- $(DOHCLIENT_OBJ)
+ $(DOHCLIENT_OBJ) $(READZONE_OBJ)
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)
lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \
petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \
$(DNSTAP_SOCKET_TESTBIN) dohclient$(EXEEXT) \
- testbound$(EXEEXT) unittest$(EXEEXT)
+ testbound$(EXEEXT) unittest$(EXEEXT) readzone$(EXEEXT)
tests: all $(TEST_BIN)
check: test
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
- $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
+ $(LINK) -o $@ $(HOST_OBJ_LINK) libunbound.la $(SSLLIB) $(LIBS)
unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ_LINK) libunbound.la
- $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat $(SSLLIB) $(LIBS)
+ $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) libunbound.la -lexpat $(SSLLIB) $(LIBS)
unbound-service-install$(EXEEXT): $(SVCINST_OBJ_LINK)
$(LINK) -o $@ $(SVCINST_OBJ_LINK) $(LIBS)
$(LINK) -o $@ $(SVCUNINST_OBJ_LINK) $(LIBS)
anchor-update$(EXEEXT): $(ANCHORUPD_OBJ_LINK) libunbound.la
- $(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
+ $(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) libunbound.la $(LIBS)
unittest$(EXEEXT): $(UNITTEST_OBJ_LINK)
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
- $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
+ $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) libunbound.la $(SSLLIB) $(LIBS)
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
delayer$(EXEEXT): $(DELAYER_OBJ_LINK)
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS)
+readzone$(EXEEXT): $(READZONE_OBJ_LINK)
+ $(LINK) -o $@ $(READZONE_OBJ_LINK) $(SSLLIB) $(LIBS)
+
signit$(EXEEXT): testcode/signit.c
$(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ -o $@ testcode/signit.c $(LDFLAGS) -lldns $(SSLLIB) $(LIBS)
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
dynlibmod.lo dynlibdmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h
+cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h
+redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h
# dnscrypt
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
# Pyunbound python unbound wrapper
_unbound.la: libunbound_wrap.lo libunbound.la
- $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) -L. -L.libs -lunbound
+ $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) -L. -L.libs libunbound.la $(LIBS)
util/config_file.c: util/configparser.h
util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h
rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h
as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_priv.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outside_network.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
- $(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
+ $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/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/edns.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 \
$(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)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/edns-subnet/edns-subnet.h \
- $(srcdir)/util/iana_ports.inc
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/iana_ports.inc
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_secalgo.h
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \
+ $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_sigcrypt.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.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
+ $(srcdir)/libunbound/worker.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
-mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h
+mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/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 \
$(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)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h \
-
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/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
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)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h
ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/util/tube.h \
-
+ $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
-
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h \
-
+ $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \
val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
-
-val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h
+val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \
val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/sbuffer.h \
-
+ $(srcdir)/sldns/sbuffer.h
val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
-
+ $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/wire2str.h
val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
-edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h \
- $(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
+edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h
+subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h
addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h
-subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h \
- $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.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
+subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/regional.h
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/testcode/checklocks.h
-dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.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
+ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h
+ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
-unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.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/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
+unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h
unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/wire2str.h
+unitzonemd.lo unitzonemd.o: $(srcdir)/testcode/unitzonemd.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/testcode/unitmain.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/authzone.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h \
+ $(srcdir)/validator/val_anchor.h
+unittcpreuse.lo unittcpreuse.o: $(srcdir)/testcode/unittcpreuse.c config.h $(srcdir)/services/outside_network.h \
+$(srcdir)/util/random.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/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
-cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
- $(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
+cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/netevent.h $(srcdir)/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)/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/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)/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)/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)/util/rtt.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h \
+ $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
+remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/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)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/keyraw.h
-remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \
$(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
- $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h $(srcdir)/edns-subnet/subnetmod.h \
- $(srcdir)/util/data/dname.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
-
+ $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
- $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/ub_event.h
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
- $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
- $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h \
- $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/util/shm_side/shm_main.h $(srcdir)/dnstap/dtstream.h
+ $(srcdir)/services/modstack.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/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_utils.h \
+ $(srcdir)/iterator/iter_resptype.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/dnstap/dtstream.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)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/util/log.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/daemon/daemon.h \
+ $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
- $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
- $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h \
- $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/util/shm_side/shm_main.h $(srcdir)/dnstap/dtstream.h
+ $(srcdir)/services/modstack.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/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_utils.h \
+ $(srcdir)/iterator/iter_resptype.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/dnstap/dtstream.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/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
-daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/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)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/keyraw.h
+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)/util/rtt.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h \
+ $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
- $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h $(srcdir)/edns-subnet/subnetmod.h \
- $(srcdir)/util/data/dname.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
-
+ $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/daemon/remote.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/storage/lruhash.h $(srcdir)/util/module.h \
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
- $(PYTHONMOD_HEADER) $(srcdir)/edns-subnet/subnet-whitelist.h
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_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)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
-libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
- $(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
- $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
+libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/sldns/str2wire.h
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 \
$(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)/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 \
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
-
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
-unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \
- $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h \
- $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h \
- $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h
+unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/listen_dnsport.h
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
-
-petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
-
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.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 \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
- $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
-
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/daemon/worker.h \
+ $(srcdir)/libunbound/worker.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
+ $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
+ $(srcdir)/libunbound/unbound-event.h
+pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h \
+ $(srcdir)/pythonmod/pythonmod_utils.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/net_help.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/regional.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h
win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \
+ $(srcdir)/util/net_help.h
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
$(srcdir)/winrc/w_inst.h
$(srcdir)/winrc/w_inst.h
anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
-keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/rrdef.h \
-
+keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/rrdef.h
sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h
wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/keyraw.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
+ $(srcdir)/sldns/keyraw.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h
parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/sbuffer.h
parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h
$(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 \
-
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/util/net_help.h
+readzone.lo readzone.o: $(srcdir)/testcode/readzone.c
ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
getentropy_freebsd.lo getentropy_freebsd.o: $(srcdir)/compat/getentropy_freebsd.c
-getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h \
-
+getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c
-getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h \
-
+getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h
[![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound)
[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
+[![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest)
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
fast and lean and incorporates modern features based on open standards. If you
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
-# Version 37
+# Version 41
+# 2021-07-30 fix for openssl use of lib64 directory.
+# 2021-06-14 fix nonblocking test to use host instead of target for mingw test.
+# 2021-05-17 fix nonblocking socket test from grep on mingw32 to mingw for
+# 64bit compatibility.
+# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS.
# 2021-01-05 fix defun for aclocal
# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE
# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
HAVE_SSL=yes
dnl assume /usr is already in the lib and dynlib paths.
if test "$ssldir" != "/usr" -a "$ssldir" != ""; then
- LDFLAGS="$LDFLAGS -L$ssldir/lib"
- LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
- ACX_RUNTIME_PATH_ADD([$ssldir/lib])
+ if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then
+ LDFLAGS="$LDFLAGS -L$ssldir/lib64"
+ LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib64"
+ ACX_RUNTIME_PATH_ADD([$ssldir/lib64])
+ else
+ LDFLAGS="$LDFLAGS -L$ssldir/lib"
+ LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
+ ACX_RUNTIME_PATH_ADD([$ssldir/lib])
+ fi
fi
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
[
echo '$3' >conftest.c
echo 'void f(){ $2 }' >>conftest.c
-if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then
+if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
eval "cv_cc_deprecated_$cache=no"
else
eval "cv_cc_deprecated_$cache=yes"
AC_DEFUN([ACX_CHECK_NONBLOCKING_BROKEN],
[
AC_MSG_CHECKING([if nonblocking sockets work])
-if echo $target | grep mingw32 >/dev/null; then
+if echo $host | grep mingw >/dev/null; then
AC_MSG_RESULT([no (windows)])
AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).])
else
static int
cachedb_intcache_lookup(struct module_qstate* qstate)
{
+ uint8_t* dpname=NULL;
+ size_t dpnamelen=0;
struct dns_msg* msg;
+ if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo,
+ &dpname, &dpnamelen))
+ return 0; /* no cache for these queries */
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype,
qstate->qinfo.qclass, qstate->query_flags,
qstate->region, qstate->env->scratch,
- 1 /* no partial messages with only a CNAME */
+ 1, /* no partial messages with only a CNAME */
+ dpname, dpnamelen
);
if(!msg && qstate->env->neg_cache &&
iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
# Attempt to guess a canonical system name.
# Copyright 1992-2021 Free Software Foundation, Inc.
-timestamp='2021-01-25'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2021-06-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# Please send patches to <config-patches@gnu.org>.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
exit 1
fi
+# Just in case it came from the environment.
+GUESS=
+
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# prevent multiple calls if $tmp is already set
test "$tmp" && return 0
: "${TMPDIR=/tmp}"
- # shellcheck disable=SC2039
- { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
+ # shellcheck disable=SC2039,SC3028
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
,,) echo "int x;" > "$dummy.c"
for driver in cc gcc c89 c99 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$driver"
+ CC_FOR_BUILD=$driver
break
fi
done
PATH=$PATH:/.attbin ; export PATH
fi
-UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
-UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
-UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
-UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "$UNAME_SYSTEM" in
+case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
LIBC=unknown
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
+ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "$cc_set_libc"
# Second heuristic to detect musl libc.
if [ "$LIBC" = unknown ] &&
# Note: order is significant - the case branches are not exclusive.
-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
- UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
/usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
- echo unknown))
- case "$UNAME_MACHINE_ARCH" in
+ echo unknown)`
+ case $UNAME_MACHINE_ARCH in
aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
- endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
- machine="${arch}${endian}"-unknown
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
;;
- *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+ *) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
os=netbsdelf
;;
;;
esac
# Determine ABI tags.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "$UNAME_VERSION" in
+ case $UNAME_VERSION in
Debian*)
release='-gnu'
;;
*)
- release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "$machine-${os}${release}${abi-}"
- exit ;;
+ GUESS=$machine-${os}${release}${abi-}
+ ;;
*:Bitrig:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+ ;;
*:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+ ;;
+ *:SecBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+ ;;
*:LibertyBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+ ;;
*:MidnightBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+ ;;
*:ekkoBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+ ;;
*:SolidBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+ ;;
*:OS108:*:*)
- echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+ ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:MirBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:Sortix:*:*)
- echo "$UNAME_MACHINE"-unknown-sortix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sortix
+ ;;
*:Twizzler:*:*)
- echo "$UNAME_MACHINE"-unknown-twizzler
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-twizzler
+ ;;
*:Redox:*:*)
- echo "$UNAME_MACHINE"-unknown-redox
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-redox
+ ;;
mips:OSF1:*.*)
- echo mips-dec-osf1
- exit ;;
+ GUESS=mips-dec-osf1
+ ;;
alpha:OSF1:*:*)
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ trap '' 0
case $UNAME_RELEASE in
*4.0)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1)
- case "$ALPHA_CPU_TYPE" in
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
+ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+ ;;
Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
+ GUESS=m68k-unknown-sysv4
+ ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-amigaos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-amigaos
+ ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-morphos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-morphos
+ ;;
*:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
+ GUESS=i370-ibm-openedition
+ ;;
*:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
+ GUESS=s390-ibm-zvmoe
+ ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
+ GUESS=powerpc-ibm-os400
+ ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix"$UNAME_RELEASE"
- exit ;;
+ GUESS=arm-acorn-riscix$UNAME_RELEASE
+ ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
+ GUESS=arm-unknown-riscos
+ ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
+ GUESS=hppa1.1-hitachi-hiuxmpp
+ ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "$( (/bin/universe) 2>/dev/null)" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
+ case `(/bin/universe) 2>/dev/null` in
+ att) GUESS=pyramid-pyramid-sysv3 ;;
+ *) GUESS=pyramid-pyramid-bsd ;;
+ esac
+ ;;
NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
+ GUESS=pyramid-pyramid-svr4
+ ;;
DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
+ GUESS=sparc-icl-nx6
+ ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case $(/usr/bin/uname -p) in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
+ case `/usr/bin/uname -p` in
+ sparc) GUESS=sparc-icl-nx7 ;;
+ esac
+ ;;
s390x:SunOS:*:*)
- echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+ ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-hal-solaris2$SUN_REL
+ ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris2$SUN_REL
+ ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-pc-auroraux$UNAME_RELEASE
+ ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
set_cc_for_build
SUN_ARCH=i386
SUN_ARCH=x86_64
fi
fi
- echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+ ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris3$SUN_REL
+ ;;
sun4*:SunOS:*:*)
- case "$(/usr/bin/arch -k)" in
+ case `/usr/bin/arch -k` in
Series*|S4*)
- UNAME_RELEASE=$(uname -v)
+ UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+ GUESS=sparc-sun-sunos$SUN_REL
+ ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
+ ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
- case "$(/bin/arch)" in
+ case `/bin/arch` in
sun3)
- echo m68k-sun-sunos"$UNAME_RELEASE"
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
- echo sparc-sun-sunos"$UNAME_RELEASE"
+ GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
- exit ;;
+ ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-auspex-sunos$UNAME_RELEASE
+ ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-milan-mint$UNAME_RELEASE
+ ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-hades-mint$UNAME_RELEASE
+ ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-mint$UNAME_RELEASE
+ ;;
m68k:machten:*:*)
- echo m68k-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-machten$UNAME_RELEASE
+ ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-machten$UNAME_RELEASE
+ ;;
RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
+ GUESS=mips-dec-mach_bsd4.3
+ ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dec-ultrix$UNAME_RELEASE
+ ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=vax-dec-ultrix$UNAME_RELEASE
+ ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix"$UNAME_RELEASE"
- exit ;;
+ GUESS=clipper-intergraph-clix$UNAME_RELEASE
+ ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
- dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
- SYSTEM_NAME=$("$dummy" "$dummyarg") &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-mips-riscos$UNAME_RELEASE
+ ;;
Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
+ GUESS=powerpc-motorola-powermax
+ ;;
Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
+ GUESS=powerpc-harris-powerunix
+ ;;
m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
+ GUESS=m88k-harris-cxux7
+ ;;
m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
+ GUESS=m88k-motorola-sysv4
+ ;;
m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
test "$TARGET_BINARY_INTERFACE"x = x
then
- echo m88k-dg-dgux"$UNAME_RELEASE"
+ GUESS=m88k-dg-dgux$UNAME_RELEASE
else
- echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
- echo i586-dg-dgux"$UNAME_RELEASE"
+ GUESS=i586-dg-dgux$UNAME_RELEASE
fi
- exit ;;
+ ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
+ GUESS=m88k-dolphin-sysv3
+ ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
+ GUESS=m88k-tektronix-sysv3
+ ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
+ GUESS=m68k-tektronix-bsd
+ ;;
*:IRIX*:*:*)
- echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
- exit ;;
+ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+ GUESS=mips-sgi-irix$IRIX_REL
+ ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX '
+ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
+ GUESS=i386-ibm-aix
+ ;;
ia64:AIX:*:*)
if test -x /usr/bin/oslevel ; then
- IBM_REV=$(/usr/bin/oslevel)
+ IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+ ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
set_cc_for_build
exit(0);
}
EOF
- if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
- echo "$SYSTEM_NAME"
+ GUESS=$SYSTEM_NAME
else
- echo rs6000-ibm-aix3.2.5
+ GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
+ GUESS=rs6000-ibm-aix3.2.4
else
- echo rs6000-ibm-aix3.2
+ GUESS=rs6000-ibm-aix3.2
fi
- exit ;;
+ ;;
*:AIX:*:[4567])
- IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if test -x /usr/bin/lslpp ; then
- IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
- awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+ ;;
*:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
+ GUESS=rs6000-ibm-aix
+ ;;
ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
+ GUESS=romp-ibm-bsd4.4
+ ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
+ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
+ ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
+ GUESS=rs6000-bull-bosx
+ ;;
DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
+ GUESS=m68k-bull-sysv3
+ ;;
9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
+ GUESS=m68k-hp-bsd
+ ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
+ GUESS=m68k-hp-bsd4.4
+ ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- case "$UNAME_MACHINE" in
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ case $UNAME_MACHINE in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if test -x /usr/bin/getconf; then
- sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
- sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
- case "$sc_cpu_version" in
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "$sc_kernel_bits" in
+ case $sc_kernel_bits in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
HP_ARCH=hppa64
fi
fi
- echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
- exit ;;
+ GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+ ;;
ia64:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- echo ia64-hp-hpux"$HPUX_REV"
- exit ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ GUESS=ia64-hp-hpux$HPUX_REV
+ ;;
3050*:HI-UX:*:*)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
exit (0);
}
EOF
- $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
+ GUESS=unknown-hitachi-hiuxwe2
+ ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
- echo hppa1.1-hp-bsd
- exit ;;
+ GUESS=hppa1.1-hp-bsd
+ ;;
9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
+ GUESS=hppa1.0-hp-bsd
+ ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
+ GUESS=hppa1.0-hp-mpeix
+ ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
- echo hppa1.1-hp-osf
- exit ;;
+ GUESS=hppa1.1-hp-osf
+ ;;
hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-osf
+ ;;
i*86:OSF1:*:*)
if test -x /usr/sbin/sysversion ; then
- echo "$UNAME_MACHINE"-unknown-osf1mk
+ GUESS=$UNAME_MACHINE-unknown-osf1mk
else
- echo "$UNAME_MACHINE"-unknown-osf1
+ GUESS=$UNAME_MACHINE-unknown-osf1
fi
- exit ;;
+ ;;
parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
+ GUESS=hppa1.1-hp-lites
+ ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
+ GUESS=c1-convex-bsd
+ ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
+ GUESS=c34-convex-bsd
+ ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
+ GUESS=c38-convex-bsd
+ ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
+ GUESS=c4-convex-bsd
+ ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=ymp-cray-unicos$CRAY_REL
+ ;;
CRAY*[A-Z]90:*:*:*)
echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=t90-cray-unicos$CRAY_REL
+ ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=alphaev5-cray-unicosmk$CRAY_REL
+ ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=sv1-cray-unicos$CRAY_REL
+ ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=craynv-cray-unicosmp$CRAY_REL
+ ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+ ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+ ;;
*:BSD/OS:*:*)
- echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+ ;;
arm:FreeBSD:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
else
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
fi
- exit ;;
+ ;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
- case "$UNAME_PROCESSOR" in
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+ ;;
i*:CYGWIN*:*)
- echo "$UNAME_MACHINE"-pc-cygwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-cygwin
+ ;;
*:MINGW64*:*)
- echo "$UNAME_MACHINE"-pc-mingw64
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw64
+ ;;
*:MINGW*:*)
- echo "$UNAME_MACHINE"-pc-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw32
+ ;;
*:MSYS*:*)
- echo "$UNAME_MACHINE"-pc-msys
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msys
+ ;;
i*:PW*:*)
- echo "$UNAME_MACHINE"-pc-pw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-pw32
+ ;;
*:Interix*:*)
- case "$UNAME_MACHINE" in
+ case $UNAME_MACHINE in
x86)
- echo i586-pc-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=i586-pc-interix$UNAME_RELEASE
+ ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=x86_64-unknown-interix$UNAME_RELEASE
+ ;;
IA64)
- echo ia64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=ia64-unknown-interix$UNAME_RELEASE
+ ;;
esac ;;
i*:UWIN*:*)
- echo "$UNAME_MACHINE"-pc-uwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-uwin
+ ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-pc-cygwin
- exit ;;
+ GUESS=x86_64-pc-cygwin
+ ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=powerpcle-unknown-solaris2$SUN_REL
+ ;;
*:GNU:*:*)
# the GNU system
- echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
- exit ;;
+ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+ ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
- exit ;;
+ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+ ;;
*:Minix:*:*)
- echo "$UNAME_MACHINE"-unknown-minix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-minix
+ ;;
aarch64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
alpha:Linux:*:*)
- case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- arc:Linux:*:* | arceb:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
arm*:Linux:*:*)
set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
- exit ;;
+ ;;
avr32*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
cris:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
crisv32:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
e2k:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
frv:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
hexagon:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+ ;;
ia64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
k1om:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m32r*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m68*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
mips:Linux:*:* | mips64:Linux:*:*)
set_cc_for_build
IS_GLIBC=0
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
+ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+ eval "$cc_set_vars"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=or1k-unknown-linux-$LIBC
+ ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=sparc-unknown-linux-$LIBC
+ ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=hppa64-unknown-linux-$LIBC
+ ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
- case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
- PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
- PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
- *) echo hppa-unknown-linux-"$LIBC" ;;
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+ *) GUESS=hppa-unknown-linux-$LIBC ;;
esac
- exit ;;
+ ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64-unknown-linux-$LIBC
+ ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc-unknown-linux-$LIBC
+ ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64le-unknown-linux-$LIBC
+ ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpcle-unknown-linux-$LIBC
+ ;;
riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+ ;;
sh64*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sh*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
tile*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
vax:Linux:*:*)
- echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+ ;;
x86_64:Linux:*:*)
set_cc_for_build
LIBCABI=$LIBC
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_X32 >/dev/null
then
- LIBCABI="$LIBC"x32
+ LIBCABI=${LIBC}x32
fi
fi
- echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
+ ;;
xtensa*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
+ GUESS=i386-sequent-sysv4
+ ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+ ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo "$UNAME_MACHINE"-pc-os2-emx
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-os2-emx
+ ;;
i*86:XTS-300:*:STOP)
- echo "$UNAME_MACHINE"-unknown-stop
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-stop
+ ;;
i*86:atheos:*:*)
- echo "$UNAME_MACHINE"-unknown-atheos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-atheos
+ ;;
i*86:syllable:*:*)
- echo "$UNAME_MACHINE"-pc-syllable
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-syllable
+ ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-unknown-lynxos$UNAME_RELEASE
+ ;;
i*86:*DOS:*:*)
- echo "$UNAME_MACHINE"-pc-msdosdjgpp
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+ ;;
i*86:*:4.*:*)
- UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
- exit ;;
+ ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
- case $(/bin/uname -X | grep "^Machine") in
+ case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
- UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
- echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv32
+ GUESS=$UNAME_MACHINE-pc-sysv32
fi
- exit ;;
+ ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
+ GUESS=i586-pc-msdosdjgpp
+ ;;
Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
+ GUESS=i386-pc-mach3
+ ;;
paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
+ GUESS=i860-intel-osf1
+ ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
+ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
- exit ;;
+ ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
- echo m68010-convergent-sysv
- exit ;;
+ GUESS=m68010-convergent-sysv
+ ;;
mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
+ GUESS=m68k-convergent-sysv
+ ;;
M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
+ GUESS=m68k-diab-dnix
+ ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+ ;;
mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
+ GUESS=m68k-atari-sysv4
+ ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+ ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+ ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+ ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dde-sysv$UNAME_RELEASE
+ ;;
RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- echo "$UNAME_MACHINE"-sni-sysv4
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ GUESS=$UNAME_MACHINE-sni-sysv4
else
- echo ns32k-sni-sysv
+ GUESS=ns32k-sni-sysv
fi
- exit ;;
+ ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ GUESS=i586-unisys-sysv4
+ ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
+ GUESS=hppa1.1-stratus-sysv4
+ ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
+ GUESS=i860-stratus-sysv4
+ ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo "$UNAME_MACHINE"-stratus-vos
- exit ;;
+ GUESS=$UNAME_MACHINE-stratus-vos
+ ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
+ GUESS=hppa1.1-stratus-vos
+ ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-aux$UNAME_RELEASE
+ ;;
news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
+ GUESS=mips-sony-newsos6
+ ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if test -d /usr/nec; then
- echo mips-nec-sysv"$UNAME_RELEASE"
+ GUESS=mips-nec-sysv$UNAME_RELEASE
else
- echo mips-unknown-sysv"$UNAME_RELEASE"
+ GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
- exit ;;
+ ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
+ GUESS=powerpc-be-beos
+ ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
+ GUESS=powerpc-apple-beos
+ ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
+ GUESS=i586-pc-beos
+ ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
+ GUESS=i586-pc-haiku
+ ;;
x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
+ GUESS=x86_64-unknown-haiku
+ ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx4-nec-superux$UNAME_RELEASE
+ ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx5-nec-superux$UNAME_RELEASE
+ ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx6-nec-superux$UNAME_RELEASE
+ ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx7-nec-superux$UNAME_RELEASE
+ ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8-nec-superux$UNAME_RELEASE
+ ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8r-nec-superux$UNAME_RELEASE
+ ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sxace-nec-superux$UNAME_RELEASE
+ ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+ ;;
*:Rhapsody:*:*)
- echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+ ;;
arm64:Darwin:*:*)
- echo aarch64-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=aarch64-apple-darwin$UNAME_RELEASE
+ ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
# uname -m returns i386 or x86_64
UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+ ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+ ;;
*:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
+ GUESS=i386-pc-qnx
+ ;;
NEO-*:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=neo-tandem-nsk$UNAME_RELEASE
+ ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nse-tandem-nsk$UNAME_RELEASE
+ ;;
NSR-*:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsr-tandem-nsk$UNAME_RELEASE
+ ;;
NSV-*:NONSTOP_KERNEL:*:*)
- echo nsv-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsv-tandem-nsk$UNAME_RELEASE
+ ;;
NSX-*:NONSTOP_KERNEL:*:*)
- echo nsx-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsx-tandem-nsk$UNAME_RELEASE
+ ;;
*:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
+ GUESS=mips-compaq-nonstopux
+ ;;
BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
+ GUESS=bs2000-siemens-sysv
+ ;;
DS/*:UNIX_System_V:*:*)
- echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+ ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- # shellcheck disable=SC2154
- if test "$cputype" = 386; then
+ if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
+ elif test "x${cputype-}" != x; then
+ UNAME_MACHINE=$cputype
fi
- echo "$UNAME_MACHINE"-unknown-plan9
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-plan9
+ ;;
*:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
+ GUESS=pdp10-unknown-tops10
+ ;;
*:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
+ GUESS=pdp10-unknown-tenex
+ ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
+ GUESS=pdp10-dec-tops20
+ ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
+ GUESS=pdp10-xkl-tops20
+ ;;
*:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
+ GUESS=pdp10-unknown-tops20
+ ;;
*:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
+ GUESS=pdp10-unknown-its
+ ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-sei-seiux$UNAME_RELEASE
+ ;;
*:DragonFly:*:*)
- echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+ ;;
*:*VMS:*:*)
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- case "$UNAME_MACHINE" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case $UNAME_MACHINE in
+ A*) GUESS=alpha-dec-vms ;;
+ I*) GUESS=ia64-dec-vms ;;
+ V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
+ GUESS=i386-pc-xenix
+ ;;
i*86:skyos:*:*)
- echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
- exit ;;
+ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+ ;;
i*86:rdos:*:*)
- echo "$UNAME_MACHINE"-pc-rdos
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-rdos
+ ;;
*:AROS:*:*)
- echo "$UNAME_MACHINE"-unknown-aros
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-aros
+ ;;
x86_64:VMkernel:*:*)
- echo "$UNAME_MACHINE"-unknown-esx
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-esx
+ ;;
amd64:Isilon\ OneFS:*:*)
- echo x86_64-unknown-onefs
- exit ;;
+ GUESS=x86_64-unknown-onefs
+ ;;
*:Unleashed:*:*)
- echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+ ;;
esac
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+ echo "$GUESS"
+ exit
+fi
+
# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <<EOF
#define __ARCHITECTURE__ "m68k"
#endif
int version;
- version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
}
EOF
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
echo "$0: unable to guess system type" >&2
-case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+case $UNAME_MACHINE:$UNAME_SYSTEM in
mips:Linux | mips64:Linux)
# If we got here on MIPS GNU/Linux, output extra information.
cat >&2 <<EOF
https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
EOF
-year=$(echo $timestamp | sed 's,-.*,,')
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
# shellcheck disable=SC2003
-if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
cat >&2 <<EOF
If $0 has already been updated, send the following data and any
config.guess timestamp = $timestamp
-uname -m = $( (uname -m) 2>/dev/null || echo unknown)
-uname -r = $( (uname -r) 2>/dev/null || echo unknown)
-uname -s = $( (uname -s) 2>/dev/null || echo unknown)
-uname -v = $( (uname -v) 2>/dev/null || echo unknown)
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
-/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
-/bin/uname -X = $( (/bin/uname -X) 2>/dev/null)
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-hostinfo = $( (hostinfo) 2>/dev/null)
-/bin/universe = $( (/bin/universe) 2>/dev/null)
-/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null)
-/bin/arch = $( (/bin/arch) 2>/dev/null)
-/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null)
-/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
/* Whether daemon is deprecated */
#undef DEPRECATED_DAEMON
+/* Deprecate RSA 1024 bit length, makes that an unsupported key */
+#undef DEPRECATE_RSA_1024
+
/* Define this to enable kernel based UDP source port randomization. */
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
#undef HAVE_OPENSSL_INIT_SSL
+/* Define to 1 if you have the <openssl/param_build.h> header file. */
+#undef HAVE_OPENSSL_PARAM_BUILD_H
+
/* Define to 1 if you have the <openssl/rand.h> header file. */
#undef HAVE_OPENSSL_RAND_H
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
+/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
+#undef HAVE_OSSL_PARAM_BLD_NEW
+
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
+/* Define to 1 if you have the `SSL_CTX_set_alpn_protos' function. */
+#undef HAVE_SSL_CTX_SET_ALPN_PROTOS
+
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
+#undef HAVE_SSL_GET0_ALPN_SELECTED
+
/* Define to 1 if you have the `SSL_get0_peername' function. */
#undef HAVE_SSL_GET0_PEERNAME
+/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */
+#undef HAVE_SSL_GET1_PEER_CERTIFICATE
+
/* Define to 1 if you have the `SSL_set1_host' function. */
#undef HAVE_SSL_SET1_HOST
/* Define if you enable libevent */
#undef USE_LIBEVENT
+/* Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a
+ default outgoing port range. This is only for the libunbound on Linux and
+ does not affect unbound resolving daemon itself. This may severely limit
+ the number of available outgoing ports and thus decrease randomness. Define
+ this only when the target system restricts (e.g. some of SELinux enabled
+ distributions) the use of non-ephemeral ports. */
+#undef USE_LINUX_IP_LOCAL_PORT_RANGE
+
/* Define if you want to use internal select based events */
#undef USE_MINI_EVENT
# Configuration validation subroutine script.
# Copyright 1992-2021 Free Software Foundation, Inc.
-timestamp='2021-01-08'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2021-07-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
vendor=hp
;;
i*86v32)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv32
;;
i*86v4*)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv4
;;
i*86v)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv
;;
i*86sol2)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=solaris2
;;
;;
leon-*|leon[3-9]-*)
cpu=sparc
- vendor=$(echo "$basic_machine" | sed 's/-.*//')
+ vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
*-*)
cpu=mipsisa64sb1el
;;
sh5e[lb]-*)
- cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
spur-*)
cpu=spur
cpu=x86_64
;;
xscale-* | xscalee[bl]-*)
- cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
arm64-*)
cpu=aarch64
| alphapca5[67] | alpha64pca5[67] \
| am33_2.0 \
| amdgcn \
- | arc | arceb \
+ | arc | arceb | arc32 | arc64 \
| arm | arm[lb]e | arme[lb] | armv* \
| avr | avr32 \
| asmjs \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r3 | mipsisa32r3el \
+ | mipsisa32r5 | mipsisa32r5el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r3 | mipsisa64r3el \
+ | mipsisa64r5 | mipsisa64r5el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
case $basic_os in
gnu/linux*)
kernel=linux
- os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
+ os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
;;
os2-emx)
kernel=os2
- os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
+ os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
;;
nto-qnx*)
kernel=nto
- os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
+ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
;;
*-*)
# shellcheck disable=SC2162
# Default OS when just kernel was specified
nto*)
kernel=nto
- os=$(echo $basic_os | sed -e 's|nto|qnx|')
+ os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
;;
linux*)
kernel=linux
- os=$(echo $basic_os | sed -e 's|linux|gnu|')
+ os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
;;
*)
kernel=
os=cnk
;;
solaris1 | solaris1.*)
- os=$(echo $os | sed -e 's|solaris1|sunos4|')
+ os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
;;
solaris)
os=solaris2
os=sco3.2v4
;;
sco3.2.[4-9]*)
- os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
+ os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
;;
sco*v* | scout)
# Don't match below
os=lynxos
;;
mac[0-9]*)
- os=$(echo "$os" | sed -e 's|mac|macos|')
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
opened*)
os=openedition
os=os400
;;
sunos5*)
- os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
sunos6*)
- os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
wince*)
os=wince
;;
# Preserve the version number of sinix5.
sinix5.*)
- os=$(echo $os | sed -e 's|sinix|sysv|')
+ os=`echo "$os" | sed -e 's|sinix|sysv|'`
;;
sinix*)
os=sysv4
| nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
| clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
- | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
| bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
| ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
| udi* | lites* | ieee* | go32* | aux* | hcos* \
- | chorusrdb* | cegcc* | glidix* \
+ | chorusrdb* | cegcc* | glidix* | serenity* \
| cygwin* | msys* | pe* | moss* | proelf* | rtems* \
| midipix* | mingw32* | mingw64* | mint* \
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for unbound 1.13.1.
+# Generated by GNU Autoconf 2.71 for unbound 1.13.2.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.13.1'
-PACKAGE_STRING='unbound 1.13.1'
+PACKAGE_VERSION='1.13.2'
+PACKAGE_STRING='unbound 1.13.2'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
IPSET_SRC
IPSECMOD_HEADER
IPSECMOD_OBJ
+CACHEDB_OBJ
+CACHEDB_SRC
DNSCRYPT_OBJ
DNSCRYPT_SRC
ENABLE_DNSCRYPT
enable_gost
enable_ecdsa
enable_dsa
+with_deprecate_rsa_1024
enable_ed25519
enable_ed448
enable_event_api
enable_ipset
with_libmnl
enable_explicit_port_randomisation
+enable_linux_ip_local_port_range
with_libunbound_only
'
ac_precious_vars='build_alias
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures unbound 1.13.1 to adapt to many kinds of systems.
+\`configure' configures unbound 1.13.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of unbound 1.13.1:";;
+ short | recursive ) echo "Configuration of unbound 1.13.2:";;
esac
cat <<\_ACEOF
--disable-explicit-port-randomisation
disable explicit source port randomisation and rely
on the kernel to provide random source ports
+ --enable-linux-ip-local-port-range
+ Define this to enable use of
+ /proc/sys/net/ipv4/ip_local_port_range as a default
+ outgoing port range. This is only for the libunbound
+ on Linux and does not affect unbound resolving
+ daemon itself. This may severely limit the number of
+ available outgoing ports and thus decrease
+ randomness. Define this only when the target system
+ restricts (e.g. some of SELinux enabled
+ distributions) the use of non-ephemeral ports.
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
/usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
/usr)
--with-libbsd Use portable libbsd functions
+ --with-deprecate-rsa-1024
+ Deprecate RSA 1024 bit length, makes that an
+ unsupported key, for use when OpenSSL FIPS refuses
+ 1024 bit verification
--with-libevent=pathname
use libevent (will check /usr/local /opt/local
/usr/lib /usr/pkg /usr/sfw /usr or you can specify
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-unbound configure 1.13.1
+unbound configure 1.13.2
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by unbound $as_me 1.13.1, which was
+It was created by unbound $as_me 1.13.2, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
UNBOUND_VERSION_MINOR=13
-UNBOUND_VERSION_MICRO=1
+UNBOUND_VERSION_MICRO=2
LIBUNBOUND_CURRENT=9
-LIBUNBOUND_REVISION=12
+LIBUNBOUND_REVISION=13
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.12.0 had 9:10:1
# 1.13.0 had 9:11:1
# 1.13.1 had 9:12:1
+# 1.13.2 had 9:13:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
esac
# are we on MinGW?
-if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
+if uname -s 2>&1 | grep MINGW >/dev/null; then on_mingw="yes"
else
- if echo $host $target | grep mingw32 >/dev/null; then on_mingw="yes"
+ if echo $host | grep mingw >/dev/null; then on_mingw="yes"
else on_mingw="no"; fi
fi
+# pkg-config is only needed for these options, do not require it otherwise
+if test "$enable_systemd" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
PKG_CONFIG=""
fi
fi
+fi
# Checks for header files.
ac_fn_c_check_header_compile "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
-ac_fn_c_check_header_compile "$LINENO" "TargetConditionals.h" "ac_cv_header_TargetConditionals_h" "$ac_includes_default"
+ac_fn_c_check_header_compile "$LINENO" "TargetConditionals.h" "ac_cv_header_TargetConditionals_h" "$ac_includes_default
+"
if test "x$ac_cv_header_TargetConditionals_h" = xyes
then :
printf "%s\n" "#define HAVE_TARGETCONDITIONALS_H 1" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if nonblocking sockets work" >&5
printf %s "checking if nonblocking sockets work... " >&6; }
-if echo $target | grep mingw32 >/dev/null; then
+if echo $host | grep mingw >/dev/null; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (windows)" >&5
printf "%s\n" "no (windows)" >&6; }
done
# check if we can use SO_REUSEPORT
-if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
+reuseport_default=0
+if echo "$host" | $GREP -i -e linux >/dev/null; then reuseport_default=1; fi
+if echo "$host" | $GREP -i -e dragonfly >/dev/null; then reuseport_default=1; fi
+if test "$reuseport_default" = 1; then
printf "%s\n" "#define REUSEPORT_DEFAULT 1" >>confdefs.h
printf "%s\n" "found in $ssldir" >&6; }
HAVE_SSL=yes
if test "$ssldir" != "/usr" -a "$ssldir" != ""; then
- LDFLAGS="$LDFLAGS -L$ssldir/lib"
- LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
+ if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then
+ LDFLAGS="$LDFLAGS -L$ssldir/lib64"
+ LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib64"
+
+ if test "x$enable_rpath" = xyes; then
+ if echo "$ssldir/lib64" | grep "^/" >/dev/null; then
+ RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib64"
+ fi
+ fi
+
+ else
+ LDFLAGS="$LDFLAGS -L$ssldir/lib"
+ LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
if test "x$enable_rpath" = xyes; then
if echo "$ssldir/lib" | grep "^/" >/dev/null; then
fi
fi
+ fi
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for EVP_sha256 in -lcrypto" >&5
then :
printf "%s\n" "#define HAVE_OPENSSL_CORE_NAMES_H 1" >>confdefs.h
+fi
+ac_fn_c_check_header_compile "$LINENO" "openssl/param_build.h" "ac_cv_header_openssl_param_build_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_openssl_param_build_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_OPENSSL_PARAM_BUILD_H 1" >>confdefs.h
+
fi
ac_fn_c_check_func "$LINENO" "OPENSSL_config" "ac_cv_func_OPENSSL_config"
printf "%s\n" "#define HAVE_EVP_MAC_CTX_SET_PARAMS 1" >>confdefs.h
fi
+ac_fn_c_check_func "$LINENO" "OSSL_PARAM_BLD_new" "ac_cv_func_OSSL_PARAM_BLD_new"
+if test "x$ac_cv_func_OSSL_PARAM_BLD_new" = xyes
+then :
+ printf "%s\n" "#define HAVE_OSSL_PARAM_BLD_NEW 1" >>confdefs.h
+
+fi
# these check_funcs need -lssl
then :
printf "%s\n" "#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB 1" >>confdefs.h
+fi
+ac_fn_c_check_func "$LINENO" "SSL_get0_alpn_selected" "ac_cv_func_SSL_get0_alpn_selected"
+if test "x$ac_cv_func_SSL_get0_alpn_selected" = xyes
+then :
+ printf "%s\n" "#define HAVE_SSL_GET0_ALPN_SELECTED 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "SSL_CTX_set_alpn_protos" "ac_cv_func_SSL_CTX_set_alpn_protos"
+if test "x$ac_cv_func_SSL_CTX_set_alpn_protos" = xyes
+then :
+ printf "%s\n" "#define HAVE_SSL_CTX_SET_ALPN_PROTOS 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "SSL_get1_peer_certificate" "ac_cv_func_SSL_get1_peer_certificate"
+if test "x$ac_cv_func_SSL_get1_peer_certificate" = xyes
+then :
+ printf "%s\n" "#define HAVE_SSL_GET1_PEER_CERTIFICATE 1" >>confdefs.h
+
fi
LIBS="$BAKLIBS"
;;
esac
+
+# Check whether --with-deprecate-rsa-1024 was given.
+if test ${with_deprecate_rsa_1024+y}
+then :
+ withval=$with_deprecate_rsa_1024;
+fi
+
+if test "$with_deprecate_rsa_1024" = "yes"; then
+
+printf "%s\n" "#define DEPRECATE_RSA_1024 1" >>confdefs.h
+
+fi
+
# Check whether --enable-ed25519 was given.
if test ${enable_ed25519+y}
then :
case "$enable_tfo_client" in
yes)
- case `uname` in
- Linux) ac_fn_check_decl "$LINENO" "MSG_FASTOPEN" "ac_cv_have_decl_MSG_FASTOPEN" "$ac_includes_default
+ case "$host_os" in
+ linux*) ac_fn_check_decl "$LINENO" "MSG_FASTOPEN" "ac_cv_have_decl_MSG_FASTOPEN" "$ac_includes_default
#include <netinet/tcp.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
printf "%s\n" "#define USE_MSG_FASTOPEN 1" >>confdefs.h
- ;;
- Darwin) ac_fn_check_decl "$LINENO" "CONNECT_RESUME_ON_READ_WRITE" "ac_cv_have_decl_CONNECT_RESUME_ON_READ_WRITE" "$ac_includes_default
+ ;;
+ darwin*) ac_fn_check_decl "$LINENO" "CONNECT_RESUME_ON_READ_WRITE" "ac_cv_have_decl_CONNECT_RESUME_ON_READ_WRITE" "$ac_includes_default
#include <sys/socket.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
printf "%s\n" "#define USE_OSX_MSG_FASTOPEN 1" >>confdefs.h
- ;;
+ ;;
esac
- ;;
+ ;;
no|*)
;;
esac
echo '
#include <stdlib.h>
+#include <unistd.h>
' >conftest.c
echo 'void f(){ (void)daemon(0, 0); }' >>conftest.c
-if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then
+if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
eval "cv_cc_deprecated_$cache=no"
else
eval "cv_cc_deprecated_$cache=yes"
done
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
-if echo $target_os | grep darwin8 > /dev/null; then
+if echo $host_os | grep darwin8 > /dev/null; then
printf "%s\n" "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
yes)
COMMON_OBJ_ALL_SYMBOLS=""
UBSYMS=""
- EXTRALINK="-L. -L.libs -lunbound"
+ EXTRALINK="libunbound.la"
printf "%s\n" "#define EXPORT_ALL_SYMBOLS 1" >>confdefs.h
printf "%s\n" "#define USE_CACHEDB 1" >>confdefs.h
+ CACHEDB_SRC="cachedb/cachedb.c cachedb/redis.c"
+
+ CACHEDB_OBJ="cachedb.lo redis.lo"
+
;;
no|*)
# nothing
;;
esac
+if echo "$host" | $GREP -i -e linux >/dev/null; then
+ # Check whether --enable-linux-ip-local-port-range was given.
+if test ${enable_linux_ip_local_port_range+y}
+then :
+ enableval=$enable_linux_ip_local_port_range;
+fi
+
+ case "$enable_linux_ip_local_port_range" in
+ yes)
+
+printf "%s\n" "#define USE_LINUX_IP_LOCAL_PORT_RANGE 1" >>confdefs.h
+
+ ;;
+ no|*)
+ ;;
+ esac
+fi
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5
printf %s "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; }
-version=1.13.1
+version=1.13.2
date=`date +'%b %e, %Y'`
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by unbound $as_me 1.13.1, which was
+This file was extended by unbound $as_me 1.13.2, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-unbound config.status 1.13.1
+unbound config.status 1.13.2
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[13])
-m4_define([VERSION_MICRO],[1])
+m4_define([VERSION_MICRO],[2])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
-LIBUNBOUND_REVISION=12
+LIBUNBOUND_REVISION=13
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.12.0 had 9:10:1
# 1.13.0 had 9:11:1
# 1.13.1 had 9:12:1
+# 1.13.2 had 9:13:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
esac
# are we on MinGW?
-if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
+if uname -s 2>&1 | grep MINGW >/dev/null; then on_mingw="yes"
else
- if echo $host $target | grep mingw32 >/dev/null; then on_mingw="yes"
+ if echo $host | grep mingw >/dev/null; then on_mingw="yes"
else on_mingw="no"; fi
fi
AC_CHECK_TOOL(STRIP, strip)
ACX_LIBTOOL_C_ONLY
+# pkg-config is only needed for these options, do not require it otherwise
+if test "$enable_systemd" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
PKG_PROG_PKG_CONFIG
+fi
# Checks for header files.
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])
])
# 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],,, [AC_INCLUDES_DEFAULT])
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
# check if we can use SO_REUSEPORT
-if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
+reuseport_default=0
+if echo "$host" | $GREP -i -e linux >/dev/null; then reuseport_default=1; fi
+if echo "$host" | $GREP -i -e dragonfly >/dev/null; then reuseport_default=1; fi
+if test "$reuseport_default" = 1; then
AC_DEFINE(REUSEPORT_DEFAULT, 1, [if REUSEPORT is enabled by default])
else
AC_DEFINE(REUSEPORT_DEFAULT, 0, [if REUSEPORT is enabled by default])
else
AC_MSG_RESULT([no])
fi
-AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h 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 EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params])
+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 openssl/param_build.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 EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new])
# these check_funcs need -lssl
BAKLIBS="$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 SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb])
+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 SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
;;
esac
+AC_ARG_WITH(deprecate-rsa-1024, AS_HELP_STRING([--with-deprecate-rsa-1024],[Deprecate RSA 1024 bit length, makes that an unsupported key, for use when OpenSSL FIPS refuses 1024 bit verification]))
+if test "$with_deprecate_rsa_1024" = "yes"; then
+ AC_DEFINE([DEPRECATE_RSA_1024], [1], [Deprecate RSA 1024 bit length, makes that an unsupported key])
+fi
+
AC_ARG_ENABLE(ed25519, AS_HELP_STRING([--disable-ed25519],[Disable ED25519 support]))
use_ed25519="no"
case "$enable_ed25519" in
AC_ARG_ENABLE(tfo-client, AS_HELP_STRING([--enable-tfo-client],[Enable TCP Fast Open for client mode]))
case "$enable_tfo_client" in
yes)
- case `uname` in
- Linux) AC_CHECK_DECL([MSG_FASTOPEN], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO])],
- [AC_MSG_ERROR([TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client])],
- [AC_INCLUDES_DEFAULT
+ case "$host_os" in
+ linux*) AC_CHECK_DECL([MSG_FASTOPEN], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO])],
+ [AC_MSG_ERROR([TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client])],
+ [AC_INCLUDES_DEFAULT
#include <netinet/tcp.h>
])
- AC_DEFINE_UNQUOTED([USE_MSG_FASTOPEN], [1], [Define this to enable client TCP Fast Open.])
- ;;
- Darwin) AC_CHECK_DECL([CONNECT_RESUME_ON_READ_WRITE], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO])],
- [AC_MSG_ERROR([TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client])],
- [AC_INCLUDES_DEFAULT
+ AC_DEFINE_UNQUOTED([USE_MSG_FASTOPEN], [1], [Define this to enable client TCP Fast Open.])
+ ;;
+ darwin*) AC_CHECK_DECL([CONNECT_RESUME_ON_READ_WRITE], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO])],
+ [AC_MSG_ERROR([TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client])],
+ [AC_INCLUDES_DEFAULT
#include <sys/socket.h>
])
- AC_DEFINE_UNQUOTED([USE_OSX_MSG_FASTOPEN], [1], [Define this to enable client TCP Fast Open.])
- ;;
+ AC_DEFINE_UNQUOTED([USE_OSX_MSG_FASTOPEN], [1], [Define this to enable client TCP Fast Open.])
+ ;;
esac
- ;;
+ ;;
no|*)
;;
esac
if test $ac_cv_func_daemon = yes; then
ACX_FUNC_DEPRECATED([daemon], [(void)daemon(0, 0);], [
#include <stdlib.h>
+#include <unistd.h>
])
fi
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
-if echo $target_os | grep darwin8 > /dev/null; then
+if echo $host_os | grep darwin8 > /dev/null; then
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
fi
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
yes)
COMMON_OBJ_ALL_SYMBOLS=""
UBSYMS=""
- EXTRALINK="-L. -L.libs -lunbound"
+ EXTRALINK="libunbound.la"
AC_DEFINE(EXPORT_ALL_SYMBOLS, 1, [Define this if you enabled-allsymbols from libunbound to link binaries to it for smaller install size, but the libunbound export table is polluted by internal symbols])
;;
no|*)
case "$enable_cachedb" in
yes)
AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support])
+ AC_SUBST([CACHEDB_SRC], ["cachedb/cachedb.c cachedb/redis.c"])
+ AC_SUBST([CACHEDB_OBJ], ["cachedb.lo redis.lo"])
;;
no|*)
# nothing
;;
esac
+if echo "$host" | $GREP -i -e linux >/dev/null; then
+ AC_ARG_ENABLE(linux-ip-local-port-range, AC_HELP_STRING([--enable-linux-ip-local-port-range], [Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Define this only when the target system restricts (e.g. some of SELinux enabled distributions) the use of non-ephemeral ports.]))
+ case "$enable_linux_ip_local_port_range" in
+ yes)
+ AC_DEFINE([USE_LINUX_IP_LOCAL_PORT_RANGE], [1], [Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Define this only when the target system restricts (e.g. some of SELinux enabled distributions) the use of non-ephemeral ports.])
+ ;;
+ no|*)
+ ;;
+ esac
+fi
+
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# on openBSD, the implicit rule make $< work.
free(daemon->ports);
daemon->ports = NULL;
}
- if(!resolve_interface_names(daemon->cfg, &resif, &num_resif))
+ if(!resolve_interface_names(daemon->cfg->ifs,
+ daemon->cfg->num_ifs, NULL, &resif, &num_resif))
return 0;
/* see if we want to reuseport */
#ifdef SO_REUSEPORT
fatal_exit("Could not set up per-view response IP sets");
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
have_view_respip_cfg;
-
+
+ /* setup modules */
+ daemon_setup_modules(daemon);
+
/* read auth zonefiles */
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
- &daemon->use_rpz))
+ &daemon->use_rpz, daemon->env, &daemon->mods))
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 */
- daemon_setup_modules(daemon);
-
/* response-ip-xxx options don't work as expected without the respip
* module. To avoid run-time operational surprise we reject such
* configuration. */
{
#ifndef S_SPLINT_S
size_t leftover;
- if(d == 0) {
+ if(d <= 0) {
avg->tv_sec = 0;
avg->tv_usec = 0;
return;
avg->tv_usec = sum->tv_usec / d;
/* handle fraction from seconds divide */
leftover = sum->tv_sec - avg->tv_sec*d;
- avg->tv_usec += (leftover*1000000)/d;
+ if(leftover <= 0)
+ leftover = 0;
+ avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
+ if(avg->tv_sec < 0)
+ avg->tv_sec = 0;
+ if(avg->tv_usec < 0)
+ avg->tv_usec = 0;
#endif
}
struct listen_port* l = NULL;
log_assert(cfg->remote_control_enable && cfg->control_port);
if(cfg->control_ifs.first) {
- struct config_strlist* p;
- for(p = cfg->control_ifs.first; p; p = p->next) {
- if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) {
+ char** rcif = NULL;
+ int i, num_rcif = 0;
+ if(!resolve_interface_names(NULL, 0, cfg->control_ifs.first,
+ &rcif, &num_rcif)) {
+ return NULL;
+ }
+ for(i=0; i<num_rcif; i++) {
+ if(!add_open(rcif[i], cfg->control_port, &l, 1, cfg)) {
listening_ports_free(l);
+ config_del_strarray(rcif, num_rcif);
return NULL;
}
}
+ config_del_strarray(rcif, num_rcif);
} else {
/* defaults */
if(cfg->do_ip6 &&
(void)ssl_printf(ssl, "removed %d zones\n", num);
}
+/** check syntax of newly added RR */
+static int
+check_RR_syntax(RES* ssl, char* str, int line)
+{
+ uint8_t rr[LDNS_RR_BUF_SIZE];
+ size_t len = sizeof(rr), dname_len = 0;
+ int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
+ NULL, 0, NULL, 0);
+ if(s != 0) {
+ char linestr[32];
+ if(line == 0)
+ linestr[0]=0;
+ else snprintf(linestr, sizeof(linestr), "line %d ", line);
+ if(!ssl_printf(ssl, "error parsing local-data at %sposition %d '%s': %s\n",
+ linestr, LDNS_WIREPARSE_OFFSET(s), str,
+ sldns_get_errorstr_parse(s)))
+ return 0;
+ return 0;
+ }
+ return 1;
+}
+
/** Add new RR data */
static int
-perform_data_add(RES* ssl, struct local_zones* zones, char* arg)
+perform_data_add(RES* ssl, struct local_zones* zones, char* arg, int line)
{
+ if(!check_RR_syntax(ssl, arg, line)) {
+ return 0;
+ }
if(!local_zones_add_RR(zones, arg)) {
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
return 0;
static void
do_data_add(RES* ssl, struct local_zones* zones, char* arg)
{
- if(!perform_data_add(ssl, zones, arg))
+ if(!perform_data_add(ssl, zones, arg, 0))
return;
send_ok(ssl);
}
do_datas_add(RES* ssl, struct local_zones* zones)
{
char buf[2048];
- int num = 0;
+ int num = 0, line = 0;
while(ssl_read_line(ssl, buf, sizeof(buf))) {
if(buf[0] == 0x04 && buf[1] == 0)
break; /* end of transmission */
- if(!perform_data_add(ssl, zones, buf)) {
- if(!ssl_printf(ssl, "error for input line: %s\n", buf))
- return;
- }
- else
+ line++;
+ if(perform_data_add(ssl, zones, buf, line))
num++;
}
(void)ssl_printf(ssl, "added %d datas\n", num);
uint8_t* nm = NULL;
struct auth_zones* az = worker->env.auth_zones;
struct auth_zone* z = NULL;
+ struct auth_xfer* xfr = NULL;
+ char* reason = NULL;
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
return;
if(az) {
if(z) {
lock_rw_wrlock(&z->lock);
}
+ xfr = auth_xfer_find(az, nm, nmlen, LDNS_RR_CLASS_IN);
+ if(xfr) {
+ lock_basic_lock(&xfr->lock);
+ }
lock_rw_unlock(&az->lock);
}
free(nm);
if(!z) {
+ if(xfr) {
+ lock_basic_unlock(&xfr->lock);
+ }
(void)ssl_printf(ssl, "error no auth-zone %s\n", arg);
return;
}
if(!auth_zone_read_zonefile(z, worker->env.cfg)) {
lock_rw_unlock(&z->lock);
+ if(xfr) {
+ lock_basic_unlock(&xfr->lock);
+ }
(void)ssl_printf(ssl, "error failed to read %s\n", arg);
return;
}
+
+ z->zone_expired = 0;
+ if(xfr) {
+ xfr->zone_expired = 0;
+ if(!xfr_find_soa(z, xfr)) {
+ if(z->data.count == 0) {
+ lock_rw_unlock(&z->lock);
+ lock_basic_unlock(&xfr->lock);
+ (void)ssl_printf(ssl, "zone %s has no contents\n", arg);
+ return;
+ }
+ lock_rw_unlock(&z->lock);
+ lock_basic_unlock(&xfr->lock);
+ (void)ssl_printf(ssl, "error: no SOA in zone after read %s\n", arg);
+ return;
+ }
+ if(xfr->have_zone)
+ xfr->lease_time = *worker->env.now;
+ lock_basic_unlock(&xfr->lock);
+ }
+
+ auth_zone_verify_zonemd(z, &worker->env, &worker->env.mesh->mods,
+ &reason, 0, 0);
+ if(reason && z->zone_expired) {
+ lock_rw_unlock(&z->lock);
+ (void)ssl_printf(ssl, "error zonemd for %s failed: %s\n",
+ arg, reason);
+ free(reason);
+ return;
+ } else if(reason && strcmp(reason, "ZONEMD verification successful")
+ ==0) {
+ (void)ssl_printf(ssl, "%s: %s\n", arg, reason);
+ }
lock_rw_unlock(&z->lock);
+ free(reason);
send_ok(ssl);
}
if (!rc->use_cert) {
verbose(VERB_ALGO, "unauthenticated remote control connection");
} else if(SSL_get_verify_result(s->ssl) == X509_V_OK) {
+#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
+ X509* x = SSL_get1_peer_certificate(s->ssl);
+#else
X509* x = SSL_get_peer_certificate(s->ssl);
+#endif
if(!x) {
verbose(VERB_DETAIL, "remote control connection "
"provided no client certificate");
size_t total = numthread * perthread + misc;
size_t avail;
struct rlimit rlim;
+ size_t memsize_expect = cfg->msg_cache_size + cfg->rrset_cache_size
+ + (cfg->do_tcp?cfg->stream_wait_size:0)
+ + (cfg->ip_ratelimit?cfg->ip_ratelimit_size:0)
+ + (cfg->ratelimit?cfg->ratelimit_size:0)
+ + (cfg->dnscrypt?cfg->dnscrypt_shared_secret_cache_size + cfg->dnscrypt_nonce_cache_size:0)
+ + cfg->infra_cache_numhosts * (sizeof(struct infra_key)+sizeof(struct infra_data));
+ if(strstr(cfg->module_conf, "validator") && (cfg->trust_anchor_file_list || cfg->trust_anchor_list || cfg->auto_trust_anchor_file_list || cfg->trusted_keys_file_list)) {
+ memsize_expect += cfg->key_cache_size + cfg->neg_cache_size;
+ }
+#ifdef HAVE_NGHTTP2_NGHTTP2_H
+ if(cfg_has_https(cfg)) {
+ memsize_expect += cfg->http_query_buffer_size + cfg->http_response_buffer_size;
+ }
+#endif
+
+#ifdef RLIMIT_AS
+ if(getrlimit(RLIMIT_AS, &rlim) == 0) {
+ if(rlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
+ rlim.rlim_cur < (rlim_t)memsize_expect) {
+ log_warn("the ulimit(max memory size) is smaller than the expected memory usage (added size of caches). %u < %u bytes", (unsigned)rlim.rlim_cur, (unsigned)memsize_expect);
+ }
+ }
+#endif
+ if(getrlimit(RLIMIT_DATA, &rlim) == 0) {
+ if(rlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
+ rlim.rlim_cur < (rlim_t)memsize_expect) {
+ log_warn("the ulimit(data seg size) is smaller than the expected memory usage (added size of caches). %u < %u bytes", (unsigned)rlim.rlim_cur, (unsigned)memsize_expect);
+ }
+ }
if(total > 1024 &&
strncmp(ub_event_get_version(), "mini-event", 10) == 0) {
#include "util/edns.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
+#include "iterator/iter_utils.h"
#include "validator/autotrust.h"
#include "validator/val_anchor.h"
#include "respip/respip.h"
}
}
-int
-worker_handle_reply(struct comm_point* c, void* arg, int error,
- struct comm_reply* reply_info)
-{
- struct module_qstate* q = (struct module_qstate*)arg;
- struct worker* worker = q->env->worker;
- struct outbound_entry e;
- e.qstate = q;
- e.qsent = NULL;
-
- if(error != 0) {
- mesh_report_reply(worker->env.mesh, &e, reply_info, error);
- worker_mem_report(worker, NULL);
- return 0;
- }
- /* sanity check. */
- if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
- || LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
- LDNS_PACKET_QUERY
- || LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
- /* error becomes timeout for the module as if this reply
- * never arrived. */
- mesh_report_reply(worker->env.mesh, &e, reply_info,
- NETEVENT_TIMEOUT);
- worker_mem_report(worker, NULL);
- return 0;
- }
- mesh_report_reply(worker->env.mesh, &e, reply_info, NETEVENT_NOERROR);
- worker_mem_report(worker, NULL);
- return 0;
-}
-
int
worker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info)
}
#endif
#ifdef USE_DNSTAP
- if(worker->dtenv.log_client_query_messages)
- dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
- c->buffer);
+ /*
+ * sending src (client)/dst (local service) addresses over DNSTAP from incoming request handler
+ */
+ if(worker->dtenv.log_client_query_messages) {
+ log_addr(VERB_ALGO, "request from client", &repinfo->addr, repinfo->addrlen);
+ log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+ dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
+ }
#endif
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
repinfo->addrlen);
if(is_secure_answer) worker->stats.ans_secure++;
}
#ifdef USE_DNSTAP
- if(worker->dtenv.log_client_response_messages)
- dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
- c->type, c->buffer);
+ /*
+ * sending src (client)/dst (local service) addresses over DNSTAP from send_reply code label (when we serviced local zone for ex.)
+ */
+ if(worker->dtenv.log_client_response_messages) {
+ log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+ log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
+ dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
+ }
#endif
if(worker->env.cfg->log_replies)
{
&worker_alloc_cleanup, worker,
cfg->do_udp || cfg->udp_upstream_without_downstream,
worker->daemon->connect_sslctx, cfg->delay_close,
- cfg->tls_use_sni, dtenv, cfg->udp_connect);
+ cfg->tls_use_sni, dtenv, cfg->udp_connect,
+ cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
+ cfg->tcp_auth_query_timeout);
if(!worker->back) {
log_err("could not create outgoing sockets");
worker_delete(worker);
return 0;
}
+ iterator_set_ip46_support(&worker->daemon->mods, worker->daemon->env,
+ worker->back);
/* start listening to commands */
if(!tube_setup_bg_listen(worker->cmd, worker->base,
&worker_handle_control_cmd, worker)) {
return 0;
}
worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
+ if(!worker->env.mesh) {
+ log_err("malloc failure");
+ worker_delete(worker);
+ return 0;
+ }
/* Pass on daemon variables that we would need in the mesh area */
worker->env.mesh->use_response_ip = worker->daemon->use_response_ip;
worker->env.mesh->use_rpz = worker->daemon->use_rpz;
worker->env.kill_sub = &mesh_state_delete;
worker->env.detect_cycle = &mesh_detect_cycle;
worker->env.scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
+ if(!worker->env.scratch_buffer) {
+ log_err("malloc failure");
+ worker_delete(worker);
+ return 0;
+ }
if(!(worker->env.fwds = forwards_create()) ||
!forwards_apply_cfg(worker->env.fwds, cfg)) {
log_err("Could not set forward zones");
#endif
) {
auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env);
+ auth_zones_pickup_zonemd_verify(worker->env.auth_zones,
+ &worker->env);
}
#ifdef USE_DNSTAP
if(worker->daemon->cfg->dnstap
}
}
#endif /* USE_DNSTAP */
- if(!worker->env.mesh || !worker->env.scratch_buffer) {
- worker_delete(worker);
- return 0;
- }
worker_mem_report(worker, NULL);
/* if statistics enabled start timer */
if(worker->env.cfg->stat_interval > 0) {
return 0;
}
-int libworker_handle_reply(struct comm_point* ATTR_UNUSED(c),
- void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
- struct comm_reply* ATTR_UNUSED(reply_info))
-{
- log_assert(0);
- return 0;
-}
-
int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
return cert_id;
}
+#ifdef SODIUM_MISUSE_HANDLER
static void
sodium_misuse_handler(void)
{
" unbound in a chroot, make sure /dev/urandom is available. See"
" https://www.unbound.net/documentation/unbound.conf.html");
}
+#endif
/**
static void
dt_msg_fill_net(struct dt_msg *dm,
- struct sockaddr_storage *ss,
+ struct sockaddr_storage *qs,
+ struct sockaddr_storage *rs,
enum comm_point_type cptype,
- ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
- uint32_t *port, protobuf_c_boolean *has_port)
+ ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
+ uint32_t *qport, protobuf_c_boolean *has_qport,
+ ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
+ uint32_t *rport, protobuf_c_boolean *has_rport)
{
- log_assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET);
- if (ss->ss_family == AF_INET6) {
- struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
+ log_assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
+ if (qs->ss_family == AF_INET6) {
+ struct sockaddr_in6 *q = (struct sockaddr_in6 *) qs;
/* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
dm->m.has_socket_family = 1;
/* addr: query_address or response_address */
- addr->data = s->sin6_addr.s6_addr;
- addr->len = 16; /* IPv6 */
- *has_addr = 1;
+ qaddr->data = q->sin6_addr.s6_addr;
+ qaddr->len = 16; /* IPv6 */
+ *has_qaddr = 1;
/* port: query_port or response_port */
- *port = ntohs(s->sin6_port);
- *has_port = 1;
- } else if (ss->ss_family == AF_INET) {
- struct sockaddr_in *s = (struct sockaddr_in *) ss;
+ *qport = ntohs(q->sin6_port);
+ *has_qport = 1;
+ } else if (qs->ss_family == AF_INET) {
+ struct sockaddr_in *q = (struct sockaddr_in *) qs;
/* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
dm->m.has_socket_family = 1;
/* addr: query_address or response_address */
- addr->data = (uint8_t *) &s->sin_addr.s_addr;
- addr->len = 4; /* IPv4 */
- *has_addr = 1;
+ qaddr->data = (uint8_t *) &q->sin_addr.s_addr;
+ qaddr->len = 4; /* IPv4 */
+ *has_qaddr = 1;
/* port: query_port or response_port */
- *port = ntohs(s->sin_port);
- *has_port = 1;
+ *qport = ntohs(q->sin_port);
+ *has_qport = 1;
}
+ /*
+ * This block is to fill second set of fields in DNSTAP-message defined as request_/response_ names.
+ * Additional responsive structure is: struct sockaddr_storage *rs
+ */
+ if (rs && rs->ss_family == AF_INET6) {
+ struct sockaddr_in6 *r = (struct sockaddr_in6 *) rs;
+
+ /* addr: query_address or response_address */
+ raddr->data = r->sin6_addr.s6_addr;
+ raddr->len = 16; /* IPv6 */
+ *has_raddr = 1;
+
+ /* port: query_port or response_port */
+ *rport = ntohs(r->sin6_port);
+ *has_rport = 1;
+ } else if (rs && rs->ss_family == AF_INET) {
+ struct sockaddr_in *r = (struct sockaddr_in *) rs;
+
+ /* addr: query_address or response_address */
+ raddr->data = (uint8_t *) &r->sin_addr.s_addr;
+ raddr->len = 4; /* IPv4 */
+ *has_raddr = 1;
+
+ /* port: query_port or response_port */
+ *rport = ntohs(r->sin_port);
+ *has_rport = 1;
+ }
+
log_assert(cptype == comm_udp || cptype == comm_tcp);
if (cptype == comm_udp) {
/* socket_protocol */
void
dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock,
+ struct sockaddr_storage *rsock,
enum comm_point_type cptype,
sldns_buffer *qmsg)
{
/* query_message */
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
- /* socket_family, socket_protocol, query_address, query_port */
+ /* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, qsock, cptype,
+ dt_msg_fill_net(&dm, qsock, rsock, cptype,
&dm.m.query_address, &dm.m.has_query_address,
- &dm.m.query_port, &dm.m.has_query_port);
+ &dm.m.query_port, &dm.m.has_query_port,
+ &dm.m.response_address, &dm.m.has_response_address,
+ &dm.m.response_port, &dm.m.has_response_port);
+
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
void
dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock,
+ struct sockaddr_storage *rsock,
enum comm_point_type cptype,
sldns_buffer *rmsg)
{
/* response_message */
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
- /* socket_family, socket_protocol, query_address, query_port */
+ /* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, qsock, cptype,
+ dt_msg_fill_net(&dm, qsock, rsock, cptype,
&dm.m.query_address, &dm.m.has_query_address,
- &dm.m.query_port, &dm.m.has_query_port);
+ &dm.m.query_port, &dm.m.has_query_port,
+ &dm.m.response_address, &dm.m.has_response_address,
+ &dm.m.response_port, &dm.m.has_response_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
void
dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock,
+ struct sockaddr_storage *qsock,
enum comm_point_type cptype,
uint8_t *zone, size_t zone_len,
sldns_buffer *qmsg)
/* query_message */
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
- /* socket_family, socket_protocol, response_address, response_port */
+ /* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, rsock, cptype,
+ dt_msg_fill_net(&dm, rsock, qsock, cptype,
&dm.m.response_address, &dm.m.has_response_address,
- &dm.m.response_port, &dm.m.has_response_port);
+ &dm.m.response_port, &dm.m.has_response_port,
+ &dm.m.query_address, &dm.m.has_query_address,
+ &dm.m.query_port, &dm.m.has_query_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
void
dt_msg_send_outside_response(struct dt_env *env,
- struct sockaddr_storage *rsock,
- enum comm_point_type cptype,
- uint8_t *zone, size_t zone_len,
- uint8_t *qbuf, size_t qbuf_len,
- const struct timeval *qtime,
- const struct timeval *rtime,
- sldns_buffer *rmsg)
+ struct sockaddr_storage *rsock,
+ struct sockaddr_storage *qsock,
+ enum comm_point_type cptype,
+ uint8_t *zone, size_t zone_len,
+ uint8_t *qbuf, size_t qbuf_len,
+ const struct timeval *qtime,
+ const struct timeval *rtime,
+ sldns_buffer *rmsg)
{
struct dt_msg dm;
uint16_t qflags;
- log_assert(qbuf_len >= sizeof(qflags));
+ (void)qbuf_len; log_assert(qbuf_len >= sizeof(qflags));
memcpy(&qflags, qbuf, sizeof(qflags));
qflags = ntohs(qflags);
/* response_message */
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
- /* socket_family, socket_protocol, response_address, response_port */
+ /* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, rsock, cptype,
+ dt_msg_fill_net(&dm, rsock, qsock, cptype,
&dm.m.response_address, &dm.m.has_response_address,
- &dm.m.response_port, &dm.m.has_response_port);
+ &dm.m.response_port, &dm.m.has_response_port,
+ &dm.m.query_address, &dm.m.has_query_address,
+ &dm.m.query_port, &dm.m.has_query_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
+5 August 2021: Wouter
+ - Tag for 1.13.2rc1 release.
+ - Fix #520: Unbound 1.13.2rc1 fails to build python module.
+
+4 August 2021: George
+ - Merge PR #415 from sibeream: Use
+ /proc/sys/net/ipv4/ip_local_port_range to determine available outgoing
+ ports. (New --enable-linux-ip-local-port-range configuration option)
+ - Bump MAX_RESTART_COUNT to 11 from 8; in relation to #438. This
+ allows longer CNAME chains in Unbound.
+
+4 August 2021: Wouter
+ - In unit test use openssl set security level to allow keys in test.
+ - Fix static analysis warnings about localzone locks that are unused.
+ - Fix missing locks in zonemd unit test.
+ - Fix readzone compile under debug config.
+ - Fix out of sourcedir run of zonemd unit tests.
+ - Fix libnettle zonemd unit test.
+ - Fix unit test zonemd_reload for use in run_vm.
+
+3 August 2021: George
+ - Listen to read or write events after the SSL handshake.
+ Sticky events on windows would stick on read when write was needed.
+
+3 August 2021: Wouter
+ - Merge PR #517 from dyunwei: #420 breaks the mesh reply list
+ function that need to reuse the dns answer.
+ - Annotate assertion into error printout; we think it may be an
+ error, but the situation looks harmless.
+ - Fix sign comparison warning on FreeBSD.
+
+2 August 2021: Wouter
+ - Prepare for OpenSSL 3.0.0 provider API usage, move the sldns
+ keyraw functions to produce EVP_PKEY results.
+ - Move RSA and DSA to use OpenSSL 3.0.0 API.
+ - Move ECDSA functions to use OpenSSL 3.0.0 API.
+ - iana portlist update.
+ - Fix verbose printout failure in tcp reuse unit test.
+
+30 July 2021: Wouter
+ - Fix #515: Compilation against openssl 3.0.0 beta2 is failing to
+ build unbound.
+ - For #515: Fix compilation with openssl 3.0.0 beta2, lib64 dir and
+ SSL_get_peer_certificate.
+ - Move acx_nlnetlabs.m4 to version 41, with lib64 openssl dir check.
+
+26 July 2021: George
+ - Merge #513: Stream reuse, attempt to fix #411, #439, #469. This
+ introduces a couple of fixes for the stream reuse functionality
+ that could result in broken internal structures.
+
+26 July 2021: Wouter
+ - Merge #512: unbound.service.in: upgrade hardening to latest
+ standards.
+ - Fix readzone unknown type print for memory resize.
+
+21 July 2021: Wouter
+ - Fix that ldns_zone_new_frm_fp_l counts the line number for an empty
+ line after a comment.
+
+16 July 2021: George
+ - Introduce 'http-user-agent:' and 'hide-http-user-agent:' options.
+
+16 July 2021: Wouter
+ - Merge #510 from ndptech: Don't call a function which hasn't been
+ defined.
+ - Fix for #510: in depth, use ifdefs for windows api event calls.
+ - Fix spelling in doc/unbound.doxygen comment.
+ - Fix spelling in localzone.h comment.
+ - Fix unbound-control local_data and local_datas to print detailed
+ syntax errors.
+ - review fix to remove duplicate error printout.
+ - Insert header into testcode/readzone.c, it was missing.
+ - Fix from lint for ignored return value.
+ - Fix for older parsers for function call in serve expired get cached.
+
+6 July 2021: Wouter
+ - iana portlist update.
+
+5 July 2021: George
+ - Fix compiler warnings for #491.
+ - Fix clang-analysis warnings for testcode/readzone.c.
+
+4 July 2021: George
+ - Fix Wunused-result compile warnings.
+
+2 July 2021: Tom
+ - Merge PR #491: Add SVCB and HTTPS types and handling according to
+ draft-ietf-dnsop-svcb-https.
+
+2 July 2021: Wouter
+ - Fix #506: Python Module Seems to Leak Memory if it Experiences an
+ Unhandled Exception.
+
+25 June 2021: Wouter
+ - Fix up permissions on rpl data file in tests.
+ - Fix testbound newline treatment in moment_read and tempfile write.
+ - Fix configure grep for reuseport default for failure.
+ - Fix compat ctime_r return value
+ - Fix configure does not require pkg-config if not needed.
+ - Fix unit test in the ctime_r calls for autotrust and in testbound.
+ - Fix auth zone download on windows to unlink before rename.
+
+24 June 2021: Wouter
+ - Add analyzer and port compile github workflow.
+
+23 June 2021: Wouter
+ - Fix #503: DNS over HTTPS response truncated.
+ - Fix warnings reported by the gcc analyzer.
+
+21 June 2021: George
+ - Fix #495: Documentation or implementation of "verbosity" option.
+
+18 June 2021: Wouter
+ - Fix a number of warnings reported by the gcc analyzer.
+
+15 June 2021: George
+ - Merge #440 by kimheino: Various fixes to contrib/unbound_munin_ file.
+
+14 June 2021: Wouter
+ - Fix configure nonblocking test and onmingw test to use host.
+
+10 June 2021: Wouter
+ - Fix #500: SPEC file in version 1.13.1 references version 1.4;
+ unable to build RPM from source.
+ - Fix contrib/unbound.spec, fixed url and comment.
+
+9 June 2021: George
+ - Merge #486 by fobster: Make VAL_MAX_RESTART_COUNT configurable.
+ - Generated lexer and parser for #486; updated example.conf.
+ - Fix #413 (based on patch by k-ronny): unbound: does not compile
+ on macOS 11.1-x86_64 host.
+ - Use host_os instead of target_os in configure for Darwin8 build.
+
+8 June 2021: George
+ - Fix unused variable warning when compiling with --enable-dnstap.
+
+7 June 2021: George
+ - Merge #448 from shoeper: Update unbound-control.8.in, fix
+ rpz_disable typo.
+ - Fix #425: Document auth-zone supports communication with DNS
+ primary on nondefault port.
+
+1 June 2021: George
+ - Fix test for zonemd-check option.
+
+27 May 2021: Wouter
+ - Merge #496 from banburybill: Use build system endianness if
+ available, otherwise try to work it out.
+ - zonemd-check: yesno option, default no, enables the processing
+ of ZONEMD records for that zone.
+
+25 May 2021: Wouter
+ - Move the NSEC3 max iterations count in line with the 150 value
+ used by BIND, Knot and PowerDNS. This sets the default value
+ for it in the configuration to 150 for all key sizes.
+ - Fix #492: module-config respip missing in unbound.conf.5.in man
+ page. Merges #494 from he32.
+ - For #492: Fix font highlighting for the man page on emacs.
+
+21 May 2021: Wouter
+ - Test code has -q option for quiet output.
+
+19 May 2021: George
+ - Fix for #411, #439, #469: Reset the DNS message ID when moving queries
+ between TCP streams.
+ - Refactor for uniform way to produce random DNS message IDs.
+
+17 May 2021: Wouter
+ - Fix #489: Compile using MSYS2 MinGW 64-bit.
+
+12 May 2021: Wouter
+ - Fix that auth-zone zonefiles use last TTL if no TTL is specified.
+
+10 May 2021: Wouter
+ - Merge PR #487: ifdef RLIMIT_AS in recently added check.
+
+7 May 2021: Wouter
+ - Fix #485: Unbound occasionally reports broken stats.
+ - Add ./configure --with-deprecate-rsa-1024 that turns off RSA 1024.
+ - Remove case fallthrough from deprecate-rsa-1024 code.
+
+4 May 2021: George
+ - Fix for #367: only attempt to get the interface for queries that are no
+ longer on the tcp_waiting_list.
+ - Add more logging for out-of-memory cases.
+
+4 May 2021: Wouter
+ - Merge #478: Allow configuration of TCP timeout while waiting for
+ response.
+ - Fix to squelch tcp socket bind failures when the interface is gone.
+ - Rerun flex and bison.
+
+3 May 2021: Wouter
+ - Fix #481: Fix comment in configuration file.
+
+29 April 2021: Wouter
+ - Add that log-servfail prints an IP address and more information
+ about one of the last failures for that query.
+
+28 April 2021: George
+ - Fix compiler warning for signed/unsigned comparison for
+ max_reuse_tcp_queries.
+
+28 April 2021: Wouter
+ - Fix #474: always_null and others inside view.
+
+26 April 2021: Wouter
+ - Merge #470 from edevil: Allow configuration of persistent TCP
+ connections.
+
+22 April 2021: Wouter
+ - Merge #466 from FGasper: Support OpenSSLs that lack
+ SSL_get0_alpn_selected.
+ - Fix #468: OpenSSL 1.0.1 can no longer build Unbound.
+ - Further fix for #468: detect SSL_CTX_set_alpn_protos for build with
+ OpenSSL 1.0.1.
+ - Fix that testcode dohclient has OpenSSL initialisation calls.
+
+13 April 2021: George
+ - Fix documentation comment for files previously residing in checkconf/.
+ - Remove unused functions worker_handle_reply and libworker_handle_reply.
+
+13 April 2021: Wouter
+ - Fix that nxdomain synthesis does not happen above the stub or
+ forward definition.
+
+12 April 2021: George
+ - Fix (increase) verbosity level for iterator error log in
+ processQueryTargets().
+
+12 April 2021: Wouter
+ - Fix permission denied sendto log, squelch the log messages
+ unless high verbosity is set.
+
+9 April 2021: Wouter
+ - rebuild configure to set EXTRALINK to libunbound.la for #460.
+
+7 April 2021: Wouter
+ - Fix for #411: Depth protect for crash on deleted element timeout.
+
+1 April 2021: Wouter
+ - Merge #460 from orbea: build: Link with the libtool archive.
+ - Fix to stop IPv6 PMTU discovery.
+
+31 March 2021: George
+ - Clean makedist.sh.
+
+31 March 2021: Wouter
+ - Fix stack-protector change to not override other CFLAGS options.
+
+30 March 2021: George
+ - Disable the use of stack-protector for cross compiled 32-bit windows
+ builds; relates to #444.
+
+25 March 2021: Wouter
+ - Fix #429: Also fix end of transfer for http download of auth zones.
+
+24 March 2021: Wouter
+ - Fix deprecation test to work for iOS TVOS and WatchOS, it uses
+ CFLAGS and CPPFLAGS and also checks if the item is unavailable.
+ - Travis, fix script to fail when tasks fail.
+ - Travis, fix warning in ubsan compile.
+ - Fix configure Targetconfiditionals.h header check, to use compile.
+ - Fix that cachedb does not produce empty object files when disabled.
+
+23 March 2021: Wouter
+ - Travis enable all tests again. Clang analyzer only a couple times,
+ when there is a difference. homebrew updates disabled, so it does
+ not hang. removed trailing slashes from configure paths. Moved iOS
+ tests to allow-failure.
+ - travis, analyzer disabled on test without debug, that does not
+ run anway. Turn off failing tests except one. Update iOS test
+ to xcode image 12.2.
+
+22 March 2021: George
+ - Fix unused-function warning when compiling with --enable-dnscrypt.
+ - Fix for #367: fix memory leak when cannot bind to listening port.
+ - Reformat pythonmod/pythonmod_utils.{c,h}.
+
+22 March 2021: Wouter
+ - Merge #449 from orbea: build: Add missing linker flags.
+ - iana portlist update.
+ - Comment out nonworking OSX and IOS travis tests, vm fails to start.
+ - Fix compile error in listen_dnsport on Android.
+ - Fix memory leak reported by asan in rpz SOA record query name.
+
+19 March 2021: Wouter
+ - Fix for #447: squelch connection refused tcp connection failures
+ from the log, unless verbosity is high.
+
+17 March 2021: Wouter
+ - Fix #441: Minimal NSEC range not accepted for top level domains.
+
+11 March 2021: Wouter
+ - Fix parse of LOC RR type for decimetres.
+
+5 March 2021: Wouter
+ - Workaround for #439: prevent loops in the reuse rbtree.
+ - Debug output for #411 and #439: printout internal error and details.
+
+4 March 2021: Wouter
+ - iana portlist update.
+ - Fix spurious errors about "Could not generate request: out of
+ memory". The mesh detect cycle routine no longer wrongly stops
+ the check when the calling mesh state is unique.
+
+26 February 2021: George
+ - Fix for #367: rc_ports don't have ub_sock; skip cleaning up.
+
+26 February 2021: Wouter
+ - Fix: Resolve interface names on control-interface too.
+
+25 February 2021: Wouter
+ - Merge PR #367 : DNSTAP log local address. With code from PR #365
+ and fixes #368 : dnstap does not log the DNS message ID for
+ FORWARDER_QUERY.
+ - Fix to allow rpz with wildcard that applies to all TLDs at once.
+
+24 February 2021: George
+ - Fix #384: (1) A minor request to improve the log (2) A minor bug in one
+ log message.
+ - ipsecmod: Better logging for detecting a cycle when attaching the
+ A/AAAA subquery.
+
+24 February 2021: Wouter
+ - On startup of unbound it checks if rlimits on memory size look
+ sufficient for the configured cache size, and logs warning if not.
+ - Fix function documentation.
+ - Fix unit test for added ulimit checks.
+ - spelling fix in header.
+
+23 February 2021: Wouter
+ - Fix for zonemd, that domain-insecure zones work without dnssec.
+ - Fix for zonemd, do not reject insecure result from trust anchor
+ validation step in dnssec chain of trust.
+
+22 February 2021: Wouter
+ - Fix #431: Squelch permission denied errors for tcp connect
+ and udp connect from the logs, unless at high verbosity.
+ - Fix for zonemd, that nxdomain for the chain of trust is allowed
+ for island zones, it is treated as an insecure zone for verification.
+
+18 February 2021: Wouter
+ - Merge PR #317: ZONEMD Zone Verification, with RFC 8976 support.
+ ZONEMD records are checked for zones loaded as auth-zone,
+ with DNSSEC if available. There is an added option
+ zonemd-permissive-mode that makes it log but not fail wrong zones.
+ With zonemd-reject-absence for an auth-zone the presence of a
+ zonemd can be mandated for specific zones.
+ - Fix doxygen and pydoc warnings.
+ - Fix #429: rpz: url: with https: broken (regression in 1.13.1).
+ - rpz skip nsec3param records, and nicer log for unsupported actions.
+
+15 February 2021: Wouter
+ - Fix #422: IPv6 fallback issues when IPv6 is not properly
+ enabled/configured.
+ - Fix to make tests work with support indicators set for iterator.
+ - Fix build on Python 3.10.
+
+10 February 2021: Wouter
+ - Merge PR #420 from dyunwei: DOH not responsing with
+ "http2_query_read_done failure" logged.
+
+9 February 2021: Wouter
+ - Fix for Python 3.9, no longer use deprecated functions of
+ PyEval_CallObject (now PyObject_Call), PyEval_InitThreads (now
+ none), PyParser_SimpleParseFile (now Py_CompileString).
+
+4 February 2021: Wouter
+ - release 1.13.1rc2 tag on branch-1.13.1 with added changes of 2 feb.
+ This became 1.13.1 release tag on 9 feb. The main branch is set
+ to version 1.13.2.
+
2 February 2021: Wouter
- branch-1.13.1 is created, with release-1.13.1rc1 tag.
- Fix dynlibmod link on rhel8 for -ldl inclusion.
-README for Unbound 1.13.1
+README for Unbound 1.13.2
Copyright 2007 NLnet Labs
http://unbound.net
#
# Example configuration file.
#
-# See unbound.conf(5) man page, version 1.13.1.
+# See unbound.conf(5) man page, version 1.13.2.
#
# this is a comment.
# enable to not answer trustanchor.unbound queries.
# hide-trustanchor: no
+ # enable to not set the User-Agent HTTP header.
+ # hide-http-user-agent: no
+
# the identity to report. Leave "" or default to return hostname.
# identity: ""
# NSID identity (hex string, or "ascii_somestring"). default disabled.
# nsid: "aabbccdd"
+ # User-Agent HTTP header to use. Leave "" or default to use package name
+ # and version.
+ # http-user-agent: ""
+
# the target fetch policy.
# series of integers describing the policy per dependency depth.
# The number of values in the list determines the maximum dependency
# Use several entries, one per domain name, to track multiple zones.
#
# If you want to perform DNSSEC validation, run unbound-anchor before
- # you start unbound (i.e. in the system boot scripts). And enable:
+ # you start unbound (i.e. in the system boot scripts).
+ # And then enable the auto-trust-anchor-file config item.
# Please note usage of unbound-anchor root anchor is at your own risk
# and under the terms of our LICENSE (see that file in the source).
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
# val-sig-skew-min: 3600
# val-sig-skew-max: 86400
+ # The maximum number the validator should restart validation with
+ # another authority in case of failed validation.
+ # val-max-restart: 5
+
# Should additional section of secure message also be kept clean of
# unsecure data. Useful to shield the users of this validator from
# potential bogus data in the additional section. All unsigned data
# keysize. Keep this table very short, as linear search is done.
# A message with an NSEC3 with larger count is marked insecure.
# List in ascending order the keysize and count values.
- # val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
+ # val-nsec3-keysize-iterations: "1024 150 2048 150 4096 150"
+
+ # if enabled, ZONEMD verification failures do not block the zone.
+ # zonemd-permissive-mode: no
# instruct the auto-trust-anchor-file probing to add anchors after ttl.
# add-holddown: 2592000 # 30 days
# ipsecmod-allow: "example.com"
# ipsecmod-allow: "nlnetlabs.nl"
+ # Timeout for REUSE entries in milliseconds.
+ # tcp-reuse-timeout: 60000
+ # Max number of queries on a reuse connection.
+ # max-reuse-tcp-queries: 200
+ # Timeout in milliseconds for TCP queries to auth servers.
+ # tcp-auth-query-timeout: 3000
+
# Python config section. To enable:
# o use --with-pythonmodule to configure before compiling.
# name: "example.org"
# for-downstream: yes
# for-upstream: yes
+# zonemd-check: no
+# zonemd-reject-absence: no
# zonefile: "example.org.zone"
# Views
-.TH "libunbound" "3" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "libunbound" "3" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.13.1 functions.
+\- Unbound DNS validating resolver 1.13.2 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
-.TH "unbound-anchor" "8" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "unbound-anchor" "8" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
-.TH "unbound-checkconf" "8" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "unbound-checkconf" "8" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
-.TH "unbound-control" "8" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "unbound-control" "8" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
Add new local data, the given resource record. Like \fBlocal\-data\fR
config statement, except for when no covering zone exists. In that case
this remote control command creates a transparent zone with the same
-name as this record. This command is not good at returning detailed syntax
-errors.
+name as this record.
.TP
.B local_data_remove \fIname
Remove all RR data from local name. If the name already has no items,
.B rpz_enable \fIzone\fR
Enable the RPZ zone if it had previously been disabled.
.TP
-.B rpz_enable \fIzone\fR
+.B rpz_disable \fIzone\fR
Disable the RPZ zone.
.TP
.B view_list_local_zones \fIview\fR
-.TH "unbound\-host" "1" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "unbound\-host" "1" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
-.TH "unbound" "8" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "unbound" "8" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" unbound.8 -- unbound manual
.\"
.\"
.SH "NAME"
.B unbound
-\- Unbound DNS validating resolver 1.13.1.
+\- Unbound DNS validating resolver 1.13.2.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
-.TH "unbound.conf" "5" "Feb 9, 2021" "NLnet Labs" "unbound 1.13.1"
+.TH "unbound.conf" "5" "Aug 12, 2021" "NLnet Labs" "unbound 1.13.2"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
clause.
.TP
.B verbosity: \fI<number>
-The verbosity number, level 0 means no verbosity, only errors. Level 1
-gives operational information. Level 2 gives detailed operational
-information. Level 3 gives query level information, output per query.
-Level 4 gives algorithm level information. Level 5 logs client
-identification for cache misses. Default is level 1.
+The verbosity number, level 0 means no verbosity, only errors. Level 1
+gives operational information. Level 2 gives detailed operational
+information including short information per query. Level 3 gives query level
+information, output per query. Level 4 gives algorithm level information.
+Level 5 logs client identification for cache misses. Default is level 1.
The verbosity can also be increased from the commandline, see \fIunbound\fR(8).
.TP
.B statistics\-interval: \fI<seconds>
falls below 20% of the total number configured. A minimum timeout of
200 milliseconds is observed regardless of the option value used.
.TP
+.B tcp-reuse-timeout: \fI<msec>\fR
+The period Unbound will keep TCP persistent connections open to
+authority servers. This option defaults to 60000 milliseconds.
+.TP
+.B max-reuse-tcp-queries: \fI<number>\fR
+The maximum number of queries that can be sent on a persistent TCP
+connection.
+This option defaults to 200 queries.
+.TP
+.B tcp-auth-query-timeout: \fI<number>\fR
+Timeout in milliseconds for TCP queries to auth servers.
+This option defaults to 3000 milliseconds.
+.TP
.B edns-tcp-keepalive: \fI<yes or no>\fR
Enable or disable EDNS TCP Keepalive. Default is no.
.TP
.B pad\-queries\-block\-size: \fI<number>
The block size with which to pad queries sent over TLS upstreams.
Default is 128.
+.TP
.B tls\-use\-sni: \fI<yes or no>
Enable or disable sending the SNI extension on TLS connections.
Default is yes.
Set the version to report. If set to "", the default, then the package
version is returned.
.TP
+.B hide\-http\-user\-agent: \fI<yes or no>
+If enabled the HTTP header User-Agent is not set. Use with caution as some
+webserver configurations may reject HTTP requests lacking this header.
+If needed, it is better to explicitly set the
+.B http\-user\-agent
+below.
+.TP
+.B http\-user\-agent: \fI<string>
+Set the HTTP User-Agent header for outgoing HTTP requests. If set to "",
+the default, then the package name and version are used.
+.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
from the query ID, for speed and thread safety). Default is yes.
.TP
.B minimal-responses: \fI<yes or no>
-If yes, Unbound doesn't insert authority/additional sections into response
+If yes, Unbound does not insert authority/additional sections into response
messages when those sections are not required. This reduces response
size significantly, and may avoid TCP fallback for some responses.
This may cause a slight speedup. The default is yes, even though the DNS
.TP
.B module\-config: \fI<"module names">
Module configuration, a list of module names separated by spaces, surround
-the string with quotes (""). The modules can be validator, iterator.
-Setting this to "iterator" will result in a non\-validating server.
-Setting this to "validator iterator" will turn on DNSSEC validation.
-The ordering of the modules is important.
-You must also set trust\-anchors for validation to be useful.
-The default is "validator iterator". When the server is built with
-EDNS client subnet support the default is "subnetcache validator iterator".
+the string with quotes (""). The modules can be \fIrespip\fR,
+\fIvalidator\fR, or \fIiterator\fR (and possibly more, see below).
+Setting this to just "\fIiterator\fR" will result in a non\-validating
+server.
+Setting this to "\fIvalidator iterator\fR" will turn on DNSSEC validation.
+The ordering of the modules is significant, the order decides the
+order of processing.
+You must also set \fItrust\-anchors\fR for validation to be useful.
+Adding \fIrespip\fR to the front will cause RPZ processing to be done on
+all queries.
+The default is "\fIvalidator iterator\fR".
+.IP
+When the server is built with
+EDNS client subnet support the default is "\fIsubnetcache validator
+iterator\fR".
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 subnetcachedb module has to be listed just before
+the iterator.
The python module can be listed in different places, it then processes the
output of the module it is just before. The dynlib module can be listed pretty
much anywhere, it is only a very thin wrapper that allows dynamic libraries to
min and max very high makes the validator check the signature timestamps
less strictly.
.TP
+.B val\-max\-restart: \fI<number>
+The maximum number the validator should restart validation with
+another authority in case of failed validation. Default is 5.
+.TP
.B val\-bogus\-ttl: \fI<number>
The time to live for bogus data. This is data that has failed validation;
due to invalid signatures or other checks. The TTL from that data cannot be
.TP
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
List of keysize and iteration count values, separated by spaces, surrounded
-by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
+by quotes. Default is "1024 150 2048 150 4096 150". This determines the
maximum allowed NSEC3 iteration count before a message is simply marked
insecure instead of performing the many hashing iterations. The list must
be in ascending order and have at least one entry. If you set it to
"1024 65535" there is no restriction to NSEC3 iteration values.
This table must be kept short; a very long list could cause slower operation.
.TP
+.B zonemd\-permissive\-mode: \fI<yes or no>
+If enabled the ZONEMD verification failures are only logged and do not cause
+the zone to be blocked and only return servfail. Useful for testing out
+if it works, or if the operator only wants to be notified of a problem without
+disrupting service. Default is no.
+.TP
.B add\-holddown: \fI<seconds>
Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011
autotrust updates to add new trust anchors only after they have been
(both tagged and untagged) and regardless the type configured using
access\-control\-tag\-action.
.TP 5
+.B response\-ip: \fI<IP-netblock> <action>
+This requires use of the "respip" module.
+.IP
+If the IP address in an AAAA or A RR in the answer section of a
+response matches the specified IP netblock, the specified action will
+apply.
+\fI<action>\fR has generally the same semantics as that for
+\fIaccess-control-tag-action\fR, but there are some exceptions.
+.IP
+Actions for \fIresponse-ip\fR are different from those for
+\fIlocal-zone\fR in that in case of the former there is no point of
+such conditions as "the query matches it but there is no local data".
+Because of this difference, the semantics of \fIresponse-ip\fR actions
+are modified or simplified as follows: The \fIstatic, refuse,
+transparent, typetransparent,\fR and \fInodefault\fR actions are
+invalid for \fIresponse-ip\fR.
+Using any of these will cause the configuration to be rejected as
+faulty. The \fIdeny\fR action is non-conditional, i.e. it always
+results in dropping the corresponding query.
+The resolution result before applying the deny action is still cached
+and can be used for other queries.
+.TP 5
+.B response-ip-data: \fI<IP-netblock> <"resource record string">
+This requires use of the "respip" module.
+.IP
+This specifies the action data for \fIresponse-ip\fR with action being
+to redirect as specified by "\fIresource record string\fR". "Resource
+record string" is similar to that of \fIaccess-control-tag-action\fR,
+but it must be of either AAAA, A or CNAME types.
+If the IP-netblock is an IPv6/IPV4 prefix, the record
+must be AAAA/A respectively, unless it is a CNAME (which can be used
+for both versions of IP netblocks). If it is CNAME there must not be
+more than one \fIresponse-ip-data\fR for the same IP-netblock.
+Also, CNAME and other types of records must not coexist for the same
+IP-netblock, following the normal rules for CNAME records.
+The textual domain name for the CNAME does not have to be explicitly
+terminated with a dot ("."); the root name is assumed to be the origin
+for the name.
+.TP 5
+.B response-ip-tag: \fI<IP-netblock> <"list of tags">
+This requires use of the "respip" module.
+.IP
+Assign tags to response IP-netblocks. If the IP address in an AAAA or
+A RR in the answer section of a response matches the specified
+IP-netblock, the specified tags are assigned to the IP address.
+Then, if an \fIaccess-control-tag\fR is defined for the client and it
+includes one of the tags for the response IP, the corresponding
+\fIaccess-control-tag-action\fR will apply.
+Tag matching rule is the same as that for \fIaccess-control-tag\fR and
+\fIlocal-zones\fR.
+Unlike \fIlocal-zone-tag\fR, \fIresponse-ip-tag\fR can be defined for
+an IP-netblock even if no \fIresponse-ip\fR is defined for that
+netblock.
+If multiple \fIresponse-ip-tag\fR options are specified for the same
+IP-netblock in different statements, all but the first will be
+ignored.
+However, this will not be flagged as a configuration error, but the
+result is probably not what was intended.
+.IP
+Actions specified in an
+\fIaccess-control-tag-action\fR that has a matching tag with
+\fIresponse-ip-tag\fR can be those that are "invalid" for
+\fIresponse-ip\fR listed above, since \fIaccess-control-tag-action\fRs
+can be shared with local zones.
+For these actions, if they behave differently depending on whether
+local data exists or not in case of local zones, the behavior for
+\fIresponse-ip-data\fR will generally result in NOERROR/NODATA instead
+of NXDOMAIN, since the \fIresponse-ip\fR data are inherently type
+specific, and non-existence of data does not indicate anything about
+the existence or non-existence of the qname itself.
+For example, if the matching tag action is \fIstatic\fR but there is
+no data for the corresponding \fIresponse-ip\fR configuration, then
+the result will be NOERROR/NODATA.
+The only case where NXDOMAIN is returned is when an
+\fIalways_nxdomain\fR action applies.
+.TP 5
.B ratelimit: \fI<number or 0>
Enable ratelimiting of queries sent to nameserver for performing recursion.
If 0, the default, it is disabled. This option is experimental at this time.
.B primary: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
primaries can be specified. They are all tried if one fails.
-With the "ip#name" notation a AXFR over TLS can be used.
+To use a nondefault port for DNS communication append '@' with the port number.
+You can append a '#' and a name, then AXFR over TLS can be used and the tls authentication certificates will be checked with that name. If you combine
+the '@' and '#', the '@' comes first.
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
the zonefile as a text file from a webserver that would work.
the zone data. Turn it on when you want unbound to provide recursion for
downstream clients, and use the zone data as a local copy to speed up lookups.
.TP
+.B zonemd\-check: \fI<yes or no>
+Enable this option to check ZONEMD records in the zone. Default is disabled.
+The ZONEMD record is a checksum over the zone data. This includes glue in
+the zone and data from the zone file, and excludes comments from the zone file.
+When there is a DNSSEC chain of trust, DNSSEC signatures are checked too.
+.TP
+.B zonemd\-reject\-absence: \fI<yes or no>
+Enable this option to reject the absence of the ZONEMD record. Without it,
+when zonemd is not there it is not checked. It is useful to enable for a
+nonDNSSEC signed zone where the operator wants to require the verification
+of a ZONEMD, hence a missing ZONEMD is a failure. The action upon
+failure is controlled by the \fBzonemd\-permissive\-mode\fR option, for
+log only or also block the zone. The default is no.
+.IP
+Without the option absence of a ZONEMD is only a failure when the zone is
+DNSSEC signed, and we have a trust anchor, and the DNSSEC verification of
+the absence of the ZONEMD fails. With the option enabled, the absence of
+a ZONEMD is always a failure, also for nonDNSSEC signed zones.
+.TP
.B zonefile: \fI<filename>
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
.B primary: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
primaries can be specified. They are all tried if one fails.
+To use a nondefault port for DNS communication append '@' with the port number.
+You can append a '#' and a name, then AXFR over TLS can be used and the tls authentication certificates will be checked with that name. If you combine
+the '@' and '#', the '@' comes first.
+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
+the zonefile as a text file from a webserver that would work.
+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
+IP address to avoid a circular dependency on retrieving that IP address.
.TP
.B master: \fI<IP address or host name>
Alternate syntax for \fBprimary\fR.
FORMULA_FONTSIZE = 10
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
- if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo)) {
+ if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)) {
qstate->no_cache_store = 0;
}
subnet_data_delete, NULL);
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
if(!sn_env->subnet_msg_cache) {
- log_err("subnet: could not create cache");
+ log_err("subnetcache: could not create cache");
free(sn_env);
env->modinfo[id] = NULL;
return 0;
sn_env->whitelist = ecs_whitelist_create();
if(!sn_env->whitelist ||
!ecs_whitelist_apply_cfg(sn_env->whitelist, env->cfg)) {
- log_err("subnet: could not create ECS whitelist");
+ log_err("subnetcache: could not create ECS whitelist");
slabhash_delete(sn_env->subnet_msg_cache);
free(sn_env);
env->modinfo[id] = NULL;
return 0;
}
- verbose(VERB_QUERY, "subnet: option registered (%d)",
+ verbose(VERB_QUERY, "subnetcache: option registered (%d)",
env->cfg->client_subnet_opcode);
/* Create new mesh state for all queries. */
env->unique_mesh = 1;
if(!edns_register_option(env->cfg->client_subnet_opcode,
env->cfg->client_subnet_always_forward /* bypass cache */,
0 /* no aggregation */, env)) {
- log_err("subnet: could not register opcode");
+ log_err("subnetcache: could not register opcode");
ecs_whitelist_delete(sn_env->whitelist);
slabhash_delete(sn_env->subnet_msg_cache);
free(sn_env);
/* Step 2, find the correct tree */
if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
lock_rw_unlock(&lru_entry->lock);
- log_err("Subnet cache insertion failed");
+ log_err("subnetcache: cache insertion failed");
return;
}
lock_quick_lock(&sne->alloc.lock);
lock_quick_unlock(&sne->alloc.lock);
if (!rep) {
lock_rw_unlock(&lru_entry->lock);
- log_err("Subnet cache insertion failed");
+ log_err("subnetcache: cache insertion failed");
return;
}
/* We have not asked for subnet data */
if (!sq->subnet_sent) {
if (s_in->subnet_validdata)
- verbose(VERB_QUERY, "subnet: received spurious data");
+ verbose(VERB_QUERY, "subnetcache: received spurious data");
if (sq->subnet_downstream) /* Copy back to client */
cp_edns_bad_response(c_out, c_in);
return module_finished;
* consequence the answer ended up in the regular cache. It
* is still usefull to put it in the edns subnet cache for
* when a client explicitly asks for subnet specific answer. */
- verbose(VERB_QUERY, "subnet: Authority indicates no support");
+ verbose(VERB_QUERY, "subnetcache: Authority indicates no support");
if(!sq->started_no_cache_store) {
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
s_out->subnet_source_mask))
{
/* we can not accept, restart query without option */
- verbose(VERB_QUERY, "subnet: forged data");
+ verbose(VERB_QUERY, "subnetcache: forged data");
s_out->subnet_validdata = 0;
(void)edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
struct subnet_env *sne = qstate->env->modinfo[id];
struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id];
- verbose(VERB_QUERY, "subnet[module %d] operate: extstate:%s "
+ verbose(VERB_QUERY, "subnetcache[module %d] operate: extstate:%s "
"event:%s", id, strextstate(qstate->ext_state[id]),
strmodulevent(event));
- log_query_info(VERB_QUERY, "subnet operate: query", &qstate->qinfo);
+ log_query_info(VERB_QUERY, "subnetcache operate: query", &qstate->qinfo);
if((event == module_event_new || event == module_event_pass) &&
sq == NULL) {
/* No clients are interested in result or we could not
* parse it, we don't do client subnet */
sq->ecs_server_out.subnet_validdata = 0;
- verbose(VERB_ALGO, "subnet: pass to next module");
+ verbose(VERB_ALGO, "subnetcache: pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
}
if (lookup_and_reply(qstate, id, sq)) {
sne->num_msg_cache++;
lock_rw_unlock(&sne->biglock);
- verbose(VERB_QUERY, "subnet: answered from cache");
+ verbose(VERB_QUERY, "subnetcache: answered from cache");
qstate->ext_state[id] = module_finished;
ecs_opt_list_append(&sq->ecs_client_out,
/* pass request to next module */
verbose(VERB_ALGO,
- "subnet: not found in cache. pass to next module");
+ "subnetcache: not found in cache. pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
}
/* We are being revisited */
if(event == module_event_pass || event == module_event_new) {
/* Just pass it on, we already did the work */
- verbose(VERB_ALGO, "subnet: pass to next module");
+ verbose(VERB_ALGO, "subnetcache: pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
}
qstate->ext_state[id] = module_finished;
return;
}
- log_err("subnet: bad event %s", strmodulevent(event));
+ log_err("subnetcache: bad event %s", strmodulevent(event));
qstate->ext_state[id] = module_error;
return;
}
* The module function block
*/
static struct module_func_block subnetmod_block = {
- "subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
+ "subnetcache", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
};
ask.qclass = qclass;
ask.local_alias = NULL;
log_query_info(VERB_ALGO, "ipsecmod: generate request", &ask);
+
+ /* Explicitly check for cycle before trying to attach. Will result in
+ * cleaner error message. The attach_sub code also checks for cycle but the
+ * message will be out of memory in both cases then. */
+ fptr_ok(fptr_whitelist_modenv_detect_cycle(qstate->env->detect_cycle));
+ if((*qstate->env->detect_cycle)(qstate, &ask,
+ (uint16_t)(BIT_RD|flags), 0, 0)) {
+ verbose(VERB_ALGO, "Could not generate request: cycle detected");
+ return 0;
+ }
+
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
(uint16_t)(BIT_RD|flags), 0, 0, &newq)){
if(!qstate->env->cfg->ipsecmod_ignore_bogus &&
rrset_data->security == sec_status_bogus) {
log_err("ipsecmod: bogus IPSECKEY");
+ errinf(qstate, "ipsecmod: bogus IPSECKEY");
ipsecmod_error(qstate, id);
return;
}
if(!call_hook(qstate, iq, ie) &&
qstate->env->cfg->ipsecmod_strict) {
log_err("ipsecmod: ipsecmod-hook failed");
+ errinf(qstate, "ipsecmod: ipsecmod-hook failed");
ipsecmod_error(qstate, id);
return;
}
qstate->qinfo.qname_len, LDNS_RR_TYPE_IPSECKEY,
qstate->qinfo.qclass, 0)) {
log_err("ipsecmod: could not generate subquery.");
+ errinf(qstate, "ipsecmod: could not generate subquery.");
ipsecmod_error(qstate, id);
}
return;
if((event == module_event_new || event == module_event_pass) &&
iq == NULL) {
if(!ipsecmod_new(qstate, id)) {
+ errinf(qstate, "ipsecmod: could not ipsecmod_new");
ipsecmod_error(qstate, id);
return;
}
}
if(event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
+ errinf(qstate, "ipsecmod: got called with event error");
ipsecmod_error(qstate, id);
return;
}
}
log_err("ipsecmod: bad event %s", strmodulevent(event));
+ errinf(qstate, "ipsecmod: operate got bad event");
ipsecmod_error(qstate, id);
return;
}
/**
* Check if right hand name in NSEC is within zone
+ * @param pkt: the packet buffer for decompression.
* @param rrset: the NSEC rrset
* @param zonename: the zone name.
* @return true if BAD.
*/
-static int sanitize_nsec_is_overreach(struct rrset_parse* rrset,
- uint8_t* zonename)
+static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
+ struct rrset_parse* rrset, uint8_t* zonename)
{
struct rr_parse* rr;
uint8_t* rhs;
size_t len;
log_assert(rrset->type == LDNS_RR_TYPE_NSEC);
for(rr = rrset->rr_first; rr; rr = rr->next) {
+ size_t pos = sldns_buffer_position(pkt);
+ size_t rhspos;
rhs = rr->ttl_data+4+2;
len = sldns_read_uint16(rr->ttl_data+4);
- if(!dname_valid(rhs, len)) {
- /* malformed domain name in rdata */
+ rhspos = rhs-sldns_buffer_begin(pkt);
+ sldns_buffer_set_position(pkt, rhspos);
+ if(pkt_dname_len(pkt) == 0) {
+ /* malformed */
+ sldns_buffer_set_position(pkt, pos);
return 1;
}
- if(!dname_subdomain_c(rhs, zonename)) {
+ if(sldns_buffer_position(pkt)-rhspos > len) {
+ /* outside of rdata boundaries */
+ sldns_buffer_set_position(pkt, pos);
+ return 1;
+ }
+ sldns_buffer_set_position(pkt, pos);
+ if(!pkt_sub(pkt, rhs, zonename)) {
/* overreaching */
return 1;
}
}
/* check if right hand side of NSEC is within zone */
if(rrset->type == LDNS_RR_TYPE_NSEC &&
- sanitize_nsec_is_overreach(rrset, zonename)) {
+ sanitize_nsec_is_overreach(pkt, rrset, zonename)) {
remove_rrset("sanitize: removing overreaching NSEC "
"RRset:", pkt, msg, prev, &rrset);
continue;
#include "services/cache/infra.h"
#include "services/cache/dns.h"
#include "services/cache/rrset.h"
+#include "services/outside_network.h"
#include "util/net_help.h"
#include "util/module.h"
#include "util/log.h"
prev = NULL;
a = dp->result_list;
for(i = 0; i < got_num; i++) {
+ if(!a) break; /* robustness */
swap_to_front = 0;
if(a->addr.ss_family != AF_INET6 && attempt == -1) {
/* if we only have ip4 at low attempt count,
prev = NULL;
a = dp->result_list;
for(i = 0; i < got_num; i++) {
+ if(!a) break; /* robustness */
swap_to_front = 0;
if(a->addr.ss_family != AF_INET && attempt == -1) {
/* if we only have ip6 at low attempt count,
}
int
-iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
+iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
+ uint8_t** retdpname, size_t* retdpnamelen)
{
struct iter_hints_stub *stub;
struct delegpt *dp;
dname_str(stub->dp->name, dpname);
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
}
+ if(retdpname) {
+ *retdpname = stub->dp->name;
+ *retdpnamelen = stub->dp->namelen;
+ }
return (stub->dp->no_cache);
}
dname_str(dp->name, dpname);
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
}
+ if(retdpname) {
+ *retdpname = dp->name;
+ *retdpnamelen = dp->namelen;
+ }
return (dp->no_cache);
}
+ if(retdpname) {
+ *retdpname = NULL;
+ *retdpnamelen = 0;
+ }
return 0;
}
+
+void iterator_set_ip46_support(struct module_stack* mods,
+ struct module_env* env, struct outside_network* outnet)
+{
+ int m = modstack_find(mods, "iterator");
+ struct iter_env* ie = NULL;
+ if(m == -1)
+ return;
+ ie = (struct iter_env*)env->modinfo[m];
+ if(outnet->pending == NULL)
+ return; /* we are in testbound, no rbtree for UDP */
+ if(outnet->num_ip4 == 0)
+ ie->supports_ipv4 = 0;
+ if(outnet->num_ip6 == 0)
+ ie->supports_ipv6 = 0;
+}
struct module_qstate;
struct sock_list;
struct ub_packed_rrset_key;
+struct module_stack;
+struct outside_network;
/**
* Process config options and set iterator module state.
* can be prefetch-updates.
* @param region: to copy modified (cache is better) rrs back to.
* @param flags: with BIT_CD for dns64 AAAA translated queries.
- * @return void, because we are not interested in alloc errors,
+ * return void, because we are not interested in alloc errors,
* the iterator and validator can operate on the results in their
* scratch space (the qstate.region) and are not dependent on the cache.
* It is useful to log the alloc failure (for the server operator),
* Lookup if no_cache is set in stub or fwd.
* @param qstate: query state with env with hints and fwds.
* @param qinf: query name to lookup for.
+ * @param retdpname: returns NULL or the deepest enclosing name of fwd or stub.
+ * This is the name under which the closest lookup is going to happen.
+ * Used for NXDOMAIN checks, above that it is an nxdomain from a
+ * different server and zone. You can pass NULL to not get it.
+ * @param retdpnamelen: returns the length of the dpname.
* @return true if no_cache is set in stub or fwd.
*/
int iter_stub_fwd_no_cache(struct module_qstate *qstate,
- struct query_info *qinf);
+ struct query_info *qinf, uint8_t** retdpname, size_t* retdpnamelen);
+
+/**
+ * Set support for IP4 and IP6 depending on outgoing interfaces
+ * in the outside network. If none, no support, so no use to lookup
+ * the AAAA and then attempt to use it if there is no outgoing-interface
+ * for it.
+ * @param mods: modstack to find iterator module in.
+ * @param env: module env, find iterator module (if one) in there.
+ * @param outnet: outside network structure.
+ */
+void iterator_set_ip46_support(struct module_stack* mods,
+ struct module_env* env, struct outside_network* outnet);
#endif /* ITERATOR_ITER_UTILS_H */
return 1;
}
+/** add response specific error information for log servfail */
+static void
+errinf_reply(struct module_qstate* qstate, struct iter_qstate* iq)
+{
+ if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
+ return;
+ if((qstate->reply && qstate->reply->addrlen != 0) ||
+ (iq->fail_reply && iq->fail_reply->addrlen != 0)) {
+ char from[256], frm[512];
+ if(qstate->reply && qstate->reply->addrlen != 0)
+ addr_to_str(&qstate->reply->addr, qstate->reply->addrlen,
+ from, sizeof(from));
+ else
+ addr_to_str(&iq->fail_reply->addr, iq->fail_reply->addrlen,
+ from, sizeof(from));
+ snprintf(frm, sizeof(frm), "from %s", from);
+ errinf(qstate, frm);
+ }
+ if(iq->scrub_failures || iq->parse_failures) {
+ if(iq->scrub_failures)
+ errinf(qstate, "upstream response failed scrub");
+ if(iq->parse_failures)
+ errinf(qstate, "could not parse upstream response");
+ } else if(iq->response == NULL && iq->timeout_count != 0) {
+ errinf(qstate, "upstream server timeout");
+ } else if(iq->response == NULL) {
+ errinf(qstate, "no server to query");
+ if(iq->dp) {
+ if(iq->dp->target_list == NULL)
+ errinf(qstate, "no addresses for nameservers");
+ else errinf(qstate, "nameserver addresses not usable");
+ if(iq->dp->nslist == NULL)
+ errinf(qstate, "have no nameserver names");
+ if(iq->dp->bogus)
+ errinf(qstate, "NS record was dnssec bogus");
+ }
+ }
+ if(iq->response && iq->response->rep) {
+ if(FLAGS_GET_RCODE(iq->response->rep->flags) != 0) {
+ char rcode[256], rc[32];
+ (void)sldns_wire2str_rcode_buf(
+ FLAGS_GET_RCODE(iq->response->rep->flags),
+ rc, sizeof(rc));
+ snprintf(rcode, sizeof(rcode), "got %s", rc);
+ errinf(qstate, rcode);
+ } else {
+ /* rcode NOERROR */
+ if(iq->response->rep->an_numrrsets == 0) {
+ errinf(qstate, "nodata answer");
+ }
+ }
+ }
+}
+
/** see if last resort is possible - does config allow queries to parent */
static int
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
struct iter_env* ie, int id)
{
- uint8_t* delname;
- size_t delnamelen;
+ uint8_t* delname, *dpname=NULL;
+ size_t delnamelen, dpnamelen=0;
struct dns_msg* msg = NULL;
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
/* This either results in a query restart (CNAME cache response), a
* terminating response (ANSWER), or a cache miss (null). */
- if (iter_stub_fwd_no_cache(qstate, &iq->qchase)) {
+ if (iter_stub_fwd_no_cache(qstate, &iq->qchase, &dpname, &dpnamelen)) {
/* Asked to not query cache. */
verbose(VERB_ALGO, "no-cache set, going to the network");
qstate->no_cache_lookup = 1;
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
iq->qchase.qname_len, iq->qchase.qtype,
iq->qchase.qclass, qstate->query_flags,
- qstate->region, qstate->env->scratch, 0);
+ qstate->region, qstate->env->scratch, 0, dpname,
+ dpnamelen);
if(!msg && qstate->env->neg_cache &&
iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) {
/* lookup in negative cache; may result in
* of a response. */
errinf(qstate, "all the configured stub or forward servers failed,");
errinf_dname(qstate, "at zone", iq->dp->name);
+ errinf_reply(qstate, iq);
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
errinf(qstate, "all servers for this domain failed,");
errinf_dname(qstate, "at zone", iq->dp->name);
+ errinf_reply(qstate, iq);
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
/* fail -- no more targets, no more hope of targets, no hope
* of a response. */
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
qstate->query_flags, qstate->region,
- qstate->env->scratch, 0);
+ qstate->env->scratch, 0, iq->dp->name,
+ iq->dp->namelen);
if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
LDNS_RCODE_NOERROR)
/* no need to send query if it is already
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
target->tls_auth_name, qstate);
if(!outq) {
- log_addr(VERB_DETAIL, "error sending query to auth server",
+ log_addr(VERB_QUERY, "error sending query to auth server",
&target->addr, target->addrlen);
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok)
infra_ratelimit_dec(qstate->env->infra_cache, iq->dp->name,
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
+ iq->response = NULL;
+ iq->fail_reply = NULL;
verbose(VERB_ALGO, "cleared outbound list for next round");
return next_state(iq, QUERYTARGETS_STATE);
} else if(type == RESPONSE_TYPE_CNAME) {
}
/* parse message */
+ iq->fail_reply = qstate->reply;
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
sizeof(struct msg_parse));
if(!prs) {
sldns_buffer_set_position(pkt, 0);
if(parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
verbose(VERB_ALGO, "parse error on reply packet");
+ iq->parse_failures++;
goto handle_it;
}
/* edns is not examined, but removed from message to help cache */
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
- LDNS_RCODE_NOERROR)
+ LDNS_RCODE_NOERROR) {
+ iq->parse_failures++;
goto handle_it;
+ }
/* Copy the edns options we may got from the back end */
if(edns.opt_list) {
iq->num_current_queries--;
verbose(VERB_DETAIL, "Capsforid: scrub failed, starting fallback with no response");
}
+ iq->scrub_failures++;
goto handle_it;
}
* its subqueries */
#define MAX_TARGET_NX 5
/** max number of query restarts. Determines max number of CNAME chain. */
-#define MAX_RESTART_COUNT 8
+#define MAX_RESTART_COUNT 11
/** max number of referrals. Makes sure resolver does not run away */
#define MAX_REFERRAL_COUNT 130
/** max number of queries-sent-out. Make sure large NS set does not loop */
int auth_zone_response;
/** True if the auth_zones should not be consulted for the query */
int auth_zone_avoid;
+ /** true if there have been scrubbing failures of reply packets */
+ int scrub_failures;
+ /** true if there have been parse failures of reply packets */
+ int parse_failures;
+ /** a failure printout address for last received answer */
+ struct comm_reply* fail_reply;
};
/**
} else {
log_init(cfg->logfile, cfg->use_syslog, NULL);
}
+ cfg_apply_local_port_policy(cfg, 65536);
config_apply(cfg);
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
return UB_NOMEM;
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
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,
+ ctx->env, &ctx->mods))
return UB_INITFAIL;
if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg))
return UB_INITFAIL;
ports, numports, cfg->unwanted_threshold,
cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
- cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect);
+ cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect,
+ cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
+ cfg->tcp_auth_query_timeout);
w->env->outnet = w->back;
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
if(rep->rrset_count != 0)
res->ttl = (int)rep->ttl;
res->data = (char**)calloc(1, sizeof(char*));
+ if(!res->data)
+ return 0; /* out of memory */
res->len = (int*)calloc(1, sizeof(int));
- return (res->data && res->len);
+ if(!res->len) {
+ free(res->data);
+ res->data = NULL;
+ return 0; /* out of memory */
+ }
+ return 1;
}
data = (struct packed_rrset_data*)answer->entry.data;
if(query_dname_compare(rq->qname, answer->rk.dname) != 0) {
return 0; /* out of memory */
} else res->canonname = NULL;
res->data = (char**)calloc(data->count+1, sizeof(char*));
+ if(!res->data)
+ return 0; /* out of memory */
res->len = (int*)calloc(data->count+1, sizeof(int));
- if(!res->data || !res->len)
+ if(!res->len) {
+ free(res->data);
+ res->data = NULL;
return 0; /* out of memory */
+ }
for(i=0; i<data->count; i++) {
/* remove rdlength from rdata */
res->len[i] = (int)(data->rr_len[i] - 2);
res->data[i] = memdup(data->rr_data[i]+2, (size_t)res->len[i]);
- if(!res->data[i])
+ if(!res->data[i]) {
+ size_t j;
+ for(j=0; j<i; j++) {
+ free(res->data[j]);
+ res->data[j] = NULL;
+ }
+ free(res->data);
+ res->data = NULL;
+ free(res->len);
+ res->len = NULL;
return 0; /* out of memory */
+ }
}
/* ttl for positive answers, from CNAME and answer RRs */
if(data->count != 0) {
return e;
}
-int
-libworker_handle_reply(struct comm_point* c, void* arg, int error,
- struct comm_reply* reply_info)
-{
- struct module_qstate* q = (struct module_qstate*)arg;
- struct libworker* lw = (struct libworker*)q->env->worker;
- struct outbound_entry e;
- e.qstate = q;
- e.qsent = NULL;
-
- if(error != 0) {
- mesh_report_reply(lw->env->mesh, &e, reply_info, error);
- return 0;
- }
- /* sanity check. */
- if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
- || LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
- LDNS_PACKET_QUERY
- || LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
- /* error becomes timeout for the module as if this reply
- * never arrived. */
- mesh_report_reply(lw->env->mesh, &e, reply_info,
- NETEVENT_TIMEOUT);
- return 0;
- }
- mesh_report_reply(lw->env->mesh, &e, reply_info, NETEVENT_NOERROR);
- return 0;
-}
-
int
libworker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info)
return 0;
}
-int worker_handle_reply(struct comm_point* ATTR_UNUSED(c),
- void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
- struct comm_reply* ATTR_UNUSED(reply_info))
-{
- log_assert(0);
- return 0;
-}
-
int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
size_t zonelen, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q);
-/** process incoming replies from the network */
-int libworker_handle_reply(struct comm_point* c, void* arg, int error,
- struct comm_reply* reply_info);
-
/** process incoming serviced query replies from the network */
int libworker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info);
int worker_handle_request(struct comm_point* c, void* arg, int error,
struct comm_reply* repinfo);
-/** process incoming replies from the network */
-int worker_handle_reply(struct comm_point* c, void* arg, int error,
- struct comm_reply* reply_info);
-
/** process incoming serviced query replies from the network */
int worker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info);
struct resp_addr* prev;
prev = (struct resp_addr*)rbtree_previous((struct rbnode_type*)node);
lock_rw_destroy(&node->lock);
- rbtree_delete(&set->ip_tree, node);
+ (void)rbtree_delete(&set->ip_tree, node);
/* no free'ing, all allocated in region */
if(!prev)
addr_tree_init_parents((rbtree_type*)set);
#include "sldns/parseutil.h"
#include "sldns/keyraw.h"
#include "validator/val_nsec3.h"
+#include "validator/val_nsec.h"
#include "validator/val_secalgo.h"
+#include "validator/val_sigcrypt.h"
+#include "validator/val_anchor.h"
+#include "validator/val_utils.h"
#include <ctype.h>
/** bytes to use for NSEC3 hash buffer. 20 for sha1 */
return 1;
}
+/** offline verify for zonemd, while reading a zone file to immediately
+ * spot bad hashes in zonefile as they are read.
+ * Creates temp buffers, but uses anchors and validation environment
+ * from the module_env. */
+static void
+zonemd_offline_verify(struct auth_zone* z, struct module_env* env_for_val,
+ struct module_stack* mods)
+{
+ struct module_env env;
+ time_t now = 0;
+ if(!z->zonemd_check)
+ return;
+ env = *env_for_val;
+ env.scratch_buffer = sldns_buffer_new(env.cfg->msg_buffer_size);
+ if(!env.scratch_buffer) {
+ log_err("out of memory");
+ goto clean_exit;
+ }
+ env.scratch = regional_create();
+ if(!env.now) {
+ env.now = &now;
+ now = time(NULL);
+ }
+ if(!env.scratch) {
+ log_err("out of memory");
+ goto clean_exit;
+ }
+ auth_zone_verify_zonemd(z, &env, mods, NULL, 1, 0);
+
+clean_exit:
+ /* clean up and exit */
+ sldns_buffer_free(env.scratch_buffer);
+ regional_destroy(env.scratch);
+}
+
/** read all auth zones from file (if they have) */
static int
-auth_zones_read_zones(struct auth_zones* az, struct config_file* cfg)
+auth_zones_read_zones(struct auth_zones* az, struct config_file* cfg,
+ struct module_env* env, struct module_stack* mods)
{
struct auth_zone* z;
lock_rw_wrlock(&az->lock);
lock_rw_unlock(&az->lock);
return 0;
}
+ if(z->zonefile && z->zonefile[0]!=0 && env)
+ zonemd_offline_verify(z, env, mods);
lock_rw_unlock(&z->lock);
}
lock_rw_unlock(&az->lock);
return 1;
}
+/** fetch the content of a ZONEMD RR from the rdata */
+static int zonemd_fetch_parameters(struct auth_rrset* zonemd_rrset, size_t i,
+ uint32_t* serial, int* scheme, int* hashalgo, uint8_t** hash,
+ size_t* hashlen)
+{
+ size_t rr_len;
+ uint8_t* rdata;
+ if(i >= zonemd_rrset->data->count)
+ return 0;
+ rr_len = zonemd_rrset->data->rr_len[i];
+ if(rr_len < 2+4+1+1)
+ return 0; /* too short, for rdlen+serial+scheme+algo */
+ rdata = zonemd_rrset->data->rr_data[i];
+ *serial = sldns_read_uint32(rdata+2);
+ *scheme = rdata[6];
+ *hashalgo = rdata[7];
+ *hashlen = rr_len - 8;
+ if(*hashlen == 0)
+ *hash = NULL;
+ else *hash = rdata+8;
+ return 1;
+}
+
+/**
+ * See if the ZONEMD scheme, hash occurs more than once.
+ * @param zonemd_rrset: the zonemd rrset to check with the RRs in it.
+ * @param index: index of the original, this is allowed to have that
+ * scheme and hashalgo, but other RRs should not have it.
+ * @param scheme: the scheme to check for.
+ * @param hashalgo: the hash algorithm to check for.
+ * @return true if it occurs more than once.
+ */
+static int zonemd_is_duplicate_scheme_hash(struct auth_rrset* zonemd_rrset,
+ size_t index, int scheme, int hashalgo)
+{
+ size_t j;
+ for(j=0; j<zonemd_rrset->data->count; j++) {
+ uint32_t serial2 = 0;
+ int scheme2 = 0, hashalgo2 = 0;
+ uint8_t* hash2 = NULL;
+ size_t hashlen2 = 0;
+ if(index == j) {
+ /* this is the original */
+ continue;
+ }
+ if(!zonemd_fetch_parameters(zonemd_rrset, j, &serial2,
+ &scheme2, &hashalgo2, &hash2, &hashlen2)) {
+ /* malformed, skip it */
+ continue;
+ }
+ if(scheme == scheme2 && hashalgo == hashalgo2) {
+ /* duplicate scheme, hash */
+ verbose(VERB_ALGO, "zonemd duplicate for scheme %d "
+ "and hash %d", scheme, hashalgo);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Check ZONEMDs if present for the auth zone. Depending on config
+ * it can warn or fail on that. Checks the hash of the ZONEMD.
+ * @param z: auth zone to check for.
+ * caller must hold lock on zone.
+ * @param env: module env for temp buffers.
+ * @param reason: returned on failure.
+ * @return false on failure, true if hash checks out.
+ */
+static int auth_zone_zonemd_check_hash(struct auth_zone* z,
+ struct module_env* env, char** reason)
+{
+ /* loop over ZONEMDs and see which one is valid. if not print
+ * failure (depending on config) */
+ struct auth_data* apex;
+ struct auth_rrset* zonemd_rrset;
+ size_t i;
+ struct regional* region = NULL;
+ struct sldns_buffer* buf = NULL;
+ uint32_t soa_serial = 0;
+ region = env->scratch;
+ regional_free_all(region);
+ buf = env->scratch_buffer;
+ if(!auth_zone_get_serial(z, &soa_serial)) {
+ *reason = "zone has no SOA serial";
+ return 0;
+ }
+
+ apex = az_find_name(z, z->name, z->namelen);
+ if(!apex) {
+ *reason = "zone has no apex";
+ return 0;
+ }
+ zonemd_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_ZONEMD);
+ if(!zonemd_rrset || zonemd_rrset->data->count==0) {
+ *reason = "zone has no ZONEMD";
+ return 0; /* no RRset or no RRs in rrset */
+ }
+
+ /* we have a ZONEMD, check if it is correct */
+ for(i=0; i<zonemd_rrset->data->count; i++) {
+ uint32_t serial = 0;
+ int scheme = 0, hashalgo = 0;
+ uint8_t* hash = NULL;
+ size_t hashlen = 0;
+ if(!zonemd_fetch_parameters(zonemd_rrset, i, &serial, &scheme,
+ &hashalgo, &hash, &hashlen)) {
+ /* malformed RR */
+ *reason = "ZONEMD rdata malformed";
+ continue;
+ }
+ /* check for duplicates */
+ if(zonemd_is_duplicate_scheme_hash(zonemd_rrset, i, scheme,
+ hashalgo)) {
+ /* duplicate hash of the same scheme,hash
+ * is not allowed. */
+ *reason = "ZONEMD RRSet contains more than one RR "
+ "with the same scheme and hash algorithm";
+ continue;
+ }
+ regional_free_all(region);
+ if(serial != soa_serial) {
+ *reason = "ZONEMD serial is wrong";
+ continue;
+ }
+ if(auth_zone_generate_zonemd_check(z, scheme, hashalgo,
+ hash, hashlen, region, buf, reason)) {
+ /* success */
+ if(verbosity >= VERB_ALGO) {
+ char zstr[255+1];
+ dname_str(z->name, zstr);
+ verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr);
+ }
+ return 1;
+ }
+ /* try next one */
+ }
+ /* fail, we may have reason */
+ if(!*reason)
+ *reason = "no ZONEMD records found";
+ if(verbosity >= VERB_ALGO) {
+ char zstr[255+1];
+ dname_str(z->name, zstr);
+ verbose(VERB_ALGO, "auth-zone %s ZONEMD failed: %s", zstr, *reason);
+ }
+ return 0;
+}
+
/** find serial number of zone or false if none */
int
auth_zone_get_serial(struct auth_zone* z, uint32_t* serial)
}
/** Find auth_zone SOA and populate the values in xfr(soa values). */
-static int
+int
xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
{
struct auth_data* apex;
z->for_downstream = c->for_downstream;
z->for_upstream = c->for_upstream;
z->fallback_enabled = c->fallback_enabled;
+ z->zonemd_check = c->zonemd_check;
+ z->zonemd_reject_absence = c->zonemd_reject_absence;
if(c->isrpz && !z->rpz){
if(!(z->rpz = rpz_create(c))){
fatal_exit("Could not setup RPZ zones");
}
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
- int setup, int* is_rpz)
+ int setup, int* is_rpz, struct module_env* env,
+ struct module_stack* mods)
{
struct config_auth* p;
az_setall_deleted(az);
}
}
az_delete_deleted_zones(az);
- if(!auth_zones_read_zones(az, cfg))
+ if(!auth_zones_read_zones(az, cfg, env, mods))
return 0;
if(setup) {
if(!auth_zones_setup_zones(az))
lock_rw_unlock(&z->lock);
return;
}
+#ifdef UB_ON_WINDOWS
+ (void)unlink(zfilename); /* windows does not replace file with rename() */
+#endif
if(rename(tmpfile, zfilename) < 0) {
log_err("could not rename(%s, %s): %s", tmpfile, zfilename,
strerror(errno));
lock_rw_unlock(&z->lock);
}
+/** reacquire locks and structures. Starts with no locks, ends
+ * with xfr and z locks, if fail, no z lock */
+static int xfr_process_reacquire_locks(struct auth_xfer* xfr,
+ struct module_env* env, struct auth_zone** z)
+{
+ /* release xfr lock, then, while holding az->lock grab both
+ * z->lock and xfr->lock */
+ lock_rw_rdlock(&env->auth_zones->lock);
+ *z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen,
+ xfr->dclass);
+ if(!*z) {
+ lock_rw_unlock(&env->auth_zones->lock);
+ lock_basic_lock(&xfr->lock);
+ *z = NULL;
+ return 0;
+ }
+ lock_rw_wrlock(&(*z)->lock);
+ lock_basic_lock(&xfr->lock);
+ lock_rw_unlock(&env->auth_zones->lock);
+ return 1;
+}
+
/** process chunk list and update zone in memory,
* return false if it did not work */
static int
struct auth_zone* z;
/* obtain locks and structures */
- /* release xfr lock, then, while holding az->lock grab both
- * z->lock and xfr->lock */
lock_basic_unlock(&xfr->lock);
- lock_rw_rdlock(&env->auth_zones->lock);
- z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen,
- xfr->dclass);
- if(!z) {
- lock_rw_unlock(&env->auth_zones->lock);
+ if(!xfr_process_reacquire_locks(xfr, env, &z)) {
/* the zone is gone, ignore xfr results */
- lock_basic_lock(&xfr->lock);
return 0;
}
- lock_rw_wrlock(&z->lock);
- lock_basic_lock(&xfr->lock);
- lock_rw_unlock(&env->auth_zones->lock);
+ /* holding xfr and z locks */
/* apply data */
if(xfr->task_transfer->master->http) {
" (or malformed RR)", xfr->task_transfer->master->host);
return 0;
}
+
+ /* release xfr lock while verifying zonemd because it may have
+ * to spawn lookups in the state machines */
+ lock_basic_unlock(&xfr->lock);
+ /* holding z lock */
+ auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0);
+ if(z->zone_expired) {
+ char zname[256];
+ /* ZONEMD must have failed */
+ /* reacquire locks, so we hold xfr lock on exit of routine,
+ * and both xfr and z again after releasing xfr for potential
+ * state machine mesh callbacks */
+ lock_rw_unlock(&z->lock);
+ if(!xfr_process_reacquire_locks(xfr, env, &z))
+ return 0;
+ dname_str(xfr->name, zname);
+ verbose(VERB_ALGO, "xfr from %s: ZONEMD failed for %s, transfer is failed", xfr->task_transfer->master->host, zname);
+ xfr->zone_expired = 1;
+ lock_rw_unlock(&z->lock);
+ return 0;
+ }
+ /* reacquire locks, so we hold xfr lock on exit of routine,
+ * and both xfr and z again after releasing xfr for potential
+ * state machine mesh callbacks */
+ lock_rw_unlock(&z->lock);
+ if(!xfr_process_reacquire_locks(xfr, env, &z))
+ return 0;
+ /* holding xfr and z locks */
+
if(xfr->have_zone)
xfr->lease_time = *env->now;
xfr->task_transfer->cp = outnet_comm_point_for_http(
env->outnet, auth_xfer_transfer_http_callback, xfr,
&addr, addrlen, -1, master->ssl, master->host,
- master->file);
+ master->file, env->cfg);
if(!xfr->task_transfer->cp) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
/* perform AXFR/IXFR */
/* set the packet to be written */
/* create new ID */
- xfr->task_transfer->id = (uint16_t)(ub_random(env->rnd)&0xffff);
+ xfr->task_transfer->id = GET_RANDOM_ID(env->rnd);
xfr_create_ixfr_packet(xfr, env->scratch_buffer,
xfr->task_transfer->id, master);
/* create new ID for new probes, but not on timeout retries,
* this means we'll accept replies to previous retries to same ip */
if(timeout == AUTH_PROBE_TIMEOUT)
- xfr->task_probe->id = (uint16_t)(ub_random(env->rnd)&0xffff);
+ xfr->task_probe->id = GET_RANDOM_ID(env->rnd);
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
xfr->task_probe->id);
/* we need to remove the cp if we have a different ip4/ip6 type now */
if(with_http)
for(p = c->urls; p; p = p->next) {
m = auth_master_new(&list);
+ if(!m) return 0;
m->http = 1;
if(!parse_url(p->str, &m->host, &m->file, &m->port, &m->ssl))
return 0;
}
for(p = c->masters; p; p = p->next) {
m = auth_master_new(&list);
+ if(!m) return 0;
m->ixfr = 1; /* this flag is not configurable */
m->host = strdup(p->str);
if(!m->host) {
}
for(p = c->allow_notify; p; p = p->next) {
m = auth_master_new(&list);
+ if(!m) return 0;
m->allow_notify = 1;
m->host = strdup(p->str);
if(!m->host) {
return 1;
}
}
+
+int zonemd_hashalgo_supported(int hashalgo)
+{
+ if(hashalgo == ZONEMD_ALGO_SHA384) return 1;
+ if(hashalgo == ZONEMD_ALGO_SHA512) return 1;
+ return 0;
+}
+
+int zonemd_scheme_supported(int scheme)
+{
+ if(scheme == ZONEMD_SCHEME_SIMPLE) return 1;
+ return 0;
+}
+
+/** initialize hash for hashing with zonemd hash algo */
+static struct secalgo_hash* zonemd_digest_init(int hashalgo, char** reason)
+{
+ struct secalgo_hash *h;
+ if(hashalgo == ZONEMD_ALGO_SHA384) {
+ /* sha384 */
+ h = secalgo_hash_create_sha384();
+ if(!h)
+ *reason = "digest sha384 could not be created";
+ return h;
+ } else if(hashalgo == ZONEMD_ALGO_SHA512) {
+ /* sha512 */
+ h = secalgo_hash_create_sha512();
+ if(!h)
+ *reason = "digest sha512 could not be created";
+ return h;
+ }
+ /* unknown hash algo */
+ *reason = "unsupported algorithm";
+ return NULL;
+}
+
+/** update the hash for zonemd */
+static int zonemd_digest_update(int hashalgo, struct secalgo_hash* h,
+ uint8_t* data, size_t len, char** reason)
+{
+ if(hashalgo == ZONEMD_ALGO_SHA384) {
+ if(!secalgo_hash_update(h, data, len)) {
+ *reason = "digest sha384 failed";
+ return 0;
+ }
+ return 1;
+ } else if(hashalgo == ZONEMD_ALGO_SHA512) {
+ if(!secalgo_hash_update(h, data, len)) {
+ *reason = "digest sha512 failed";
+ return 0;
+ }
+ return 1;
+ }
+ /* unknown hash algo */
+ *reason = "unsupported algorithm";
+ return 0;
+}
+
+/** finish the hash for zonemd */
+static int zonemd_digest_finish(int hashalgo, struct secalgo_hash* h,
+ uint8_t* result, size_t hashlen, size_t* resultlen, char** reason)
+{
+ if(hashalgo == ZONEMD_ALGO_SHA384) {
+ if(hashlen < 384/8) {
+ *reason = "digest buffer too small for sha384";
+ return 0;
+ }
+ if(!secalgo_hash_final(h, result, hashlen, resultlen)) {
+ *reason = "digest sha384 finish failed";
+ return 0;
+ }
+ return 1;
+ } else if(hashalgo == ZONEMD_ALGO_SHA512) {
+ if(hashlen < 512/8) {
+ *reason = "digest buffer too small for sha512";
+ return 0;
+ }
+ if(!secalgo_hash_final(h, result, hashlen, resultlen)) {
+ *reason = "digest sha512 finish failed";
+ return 0;
+ }
+ return 1;
+ }
+ /* unknown algo */
+ *reason = "unsupported algorithm";
+ return 0;
+}
+
+/** add rrsets from node to the list */
+static size_t authdata_rrsets_to_list(struct auth_rrset** array,
+ size_t arraysize, struct auth_rrset* first)
+{
+ struct auth_rrset* rrset = first;
+ size_t num = 0;
+ while(rrset) {
+ if(num >= arraysize)
+ return num;
+ array[num] = rrset;
+ num++;
+ rrset = rrset->next;
+ }
+ return num;
+}
+
+/** compare rr list entries */
+static int rrlist_compare(const void* arg1, const void* arg2)
+{
+ struct auth_rrset* r1 = *(struct auth_rrset**)arg1;
+ struct auth_rrset* r2 = *(struct auth_rrset**)arg2;
+ uint16_t t1, t2;
+ if(r1 == NULL) t1 = LDNS_RR_TYPE_RRSIG;
+ else t1 = r1->type;
+ if(r2 == NULL) t2 = LDNS_RR_TYPE_RRSIG;
+ else t2 = r2->type;
+ if(t1 < t2)
+ return -1;
+ if(t1 > t2)
+ return 1;
+ return 0;
+}
+
+/** add type RRSIG to rr list if not one there already,
+ * this is to perform RRSIG collate processing at that point. */
+static void addrrsigtype_if_needed(struct auth_rrset** array,
+ size_t arraysize, size_t* rrnum, struct auth_data* node)
+{
+ if(az_domain_rrset(node, LDNS_RR_TYPE_RRSIG))
+ return; /* already one there */
+ if((*rrnum) >= arraysize)
+ return; /* array too small? */
+ array[*rrnum] = NULL; /* nothing there, but need entry in list */
+ (*rrnum)++;
+}
+
+/** collate the RRs in an RRset using the simple scheme */
+static int zonemd_simple_rrset(struct auth_zone* z, int hashalgo,
+ struct secalgo_hash* h, struct auth_data* node,
+ struct auth_rrset* rrset, struct regional* region,
+ struct sldns_buffer* buf, char** reason)
+{
+ /* canonicalize */
+ struct ub_packed_rrset_key key;
+ memset(&key, 0, sizeof(key));
+ key.entry.key = &key;
+ key.entry.data = rrset->data;
+ key.rk.dname = node->name;
+ key.rk.dname_len = node->namelen;
+ key.rk.type = htons(rrset->type);
+ key.rk.rrset_class = htons(z->dclass);
+ if(!rrset_canonicalize_to_buffer(region, buf, &key)) {
+ *reason = "out of memory";
+ return 0;
+ }
+ regional_free_all(region);
+
+ /* hash */
+ if(!zonemd_digest_update(hashalgo, h, sldns_buffer_begin(buf),
+ sldns_buffer_limit(buf), reason)) {
+ return 0;
+ }
+ return 1;
+}
+
+/** count number of RRSIGs in a domain name rrset list */
+static size_t zonemd_simple_count_rrsig(struct auth_rrset* rrset,
+ struct auth_rrset** rrlist, size_t rrnum,
+ struct auth_zone* z, struct auth_data* node)
+{
+ size_t i, count = 0;
+ if(rrset) {
+ size_t j;
+ for(j = 0; j<rrset->data->count; j++) {
+ if(rrsig_rdata_get_type_covered(rrset->data->
+ rr_data[j], rrset->data->rr_len[j]) ==
+ LDNS_RR_TYPE_ZONEMD &&
+ query_dname_compare(z->name, node->name)==0) {
+ /* omit RRSIGs over type ZONEMD at apex */
+ continue;
+ }
+ count++;
+ }
+ }
+ for(i=0; i<rrnum; i++) {
+ if(rrlist[i] && rrlist[i]->type == LDNS_RR_TYPE_ZONEMD &&
+ query_dname_compare(z->name, node->name)==0) {
+ /* omit RRSIGs over type ZONEMD at apex */
+ continue;
+ }
+ count += (rrlist[i]?rrlist[i]->data->rrsig_count:0);
+ }
+ return count;
+}
+
+/** allocate sparse rrset data for the number of entries in tepm region */
+static int zonemd_simple_rrsig_allocs(struct regional* region,
+ struct packed_rrset_data* data, size_t count)
+{
+ data->rr_len = regional_alloc(region, sizeof(*data->rr_len) * count);
+ if(!data->rr_len) {
+ return 0;
+ }
+ data->rr_ttl = regional_alloc(region, sizeof(*data->rr_ttl) * count);
+ if(!data->rr_ttl) {
+ return 0;
+ }
+ data->rr_data = regional_alloc(region, sizeof(*data->rr_data) * count);
+ if(!data->rr_data) {
+ return 0;
+ }
+ return 1;
+}
+
+/** add the RRSIGs from the rrs in the domain into the data */
+static void add_rrlist_rrsigs_into_data(struct packed_rrset_data* data,
+ size_t* done, struct auth_rrset** rrlist, size_t rrnum,
+ struct auth_zone* z, struct auth_data* node)
+{
+ size_t i;
+ for(i=0; i<rrnum; i++) {
+ size_t j;
+ if(!rrlist[i])
+ continue;
+ if(rrlist[i] && rrlist[i]->type == LDNS_RR_TYPE_ZONEMD &&
+ query_dname_compare(z->name, node->name)==0) {
+ /* omit RRSIGs over type ZONEMD at apex */
+ continue;
+ }
+ for(j = 0; j<rrlist[i]->data->rrsig_count; j++) {
+ data->rr_len[*done] = rrlist[i]->data->rr_len[rrlist[i]->data->count + j];
+ data->rr_ttl[*done] = rrlist[i]->data->rr_ttl[rrlist[i]->data->count + j];
+ /* reference the rdata in the rrset, no need to
+ * copy it, it is no longer needed at the end of
+ * the routine */
+ data->rr_data[*done] = rrlist[i]->data->rr_data[rrlist[i]->data->count + j];
+ (*done)++;
+ }
+ }
+}
+
+static void add_rrset_into_data(struct packed_rrset_data* data,
+ size_t* done, struct auth_rrset* rrset,
+ struct auth_zone* z, struct auth_data* node)
+{
+ if(rrset) {
+ size_t j;
+ for(j = 0; j<rrset->data->count; j++) {
+ if(rrsig_rdata_get_type_covered(rrset->data->
+ rr_data[j], rrset->data->rr_len[j]) ==
+ LDNS_RR_TYPE_ZONEMD &&
+ query_dname_compare(z->name, node->name)==0) {
+ /* omit RRSIGs over type ZONEMD at apex */
+ continue;
+ }
+ data->rr_len[*done] = rrset->data->rr_len[j];
+ data->rr_ttl[*done] = rrset->data->rr_ttl[j];
+ /* reference the rdata in the rrset, no need to
+ * copy it, it is no longer need at the end of
+ * the routine */
+ data->rr_data[*done] = rrset->data->rr_data[j];
+ (*done)++;
+ }
+ }
+}
+
+/** collate the RRSIGs using the simple scheme */
+static int zonemd_simple_rrsig(struct auth_zone* z, int hashalgo,
+ struct secalgo_hash* h, struct auth_data* node,
+ struct auth_rrset* rrset, struct auth_rrset** rrlist, size_t rrnum,
+ struct regional* region, struct sldns_buffer* buf, char** reason)
+{
+ /* the rrset pointer can be NULL, this means it is type RRSIG and
+ * there is no ordinary type RRSIG there. The RRSIGs are stored
+ * with the RRsets in their data.
+ *
+ * The RRset pointer can be nonNULL. This happens if there is
+ * no RR that is covered by the RRSIG for the domain. Then this
+ * RRSIG RR is stored in an rrset of type RRSIG. The other RRSIGs
+ * are stored in the rrset entries for the RRs in the rr list for
+ * the domain node. We need to collate the rrset's data, if any, and
+ * the rrlist's rrsigs */
+ /* if this is the apex, omit RRSIGs that cover type ZONEMD */
+ /* build rrsig rrset */
+ size_t done = 0;
+ struct ub_packed_rrset_key key;
+ struct packed_rrset_data data;
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ key.entry.key = &key;
+ key.entry.data = &data;
+ key.rk.dname = node->name;
+ key.rk.dname_len = node->namelen;
+ key.rk.type = htons(LDNS_RR_TYPE_RRSIG);
+ key.rk.rrset_class = htons(z->dclass);
+ data.count = zonemd_simple_count_rrsig(rrset, rrlist, rrnum, z, node);
+ if(!zonemd_simple_rrsig_allocs(region, &data, data.count)) {
+ *reason = "out of memory";
+ regional_free_all(region);
+ return 0;
+ }
+ /* all the RRSIGs stored in the other rrsets for this domain node */
+ add_rrlist_rrsigs_into_data(&data, &done, rrlist, rrnum, z, node);
+ /* plus the RRSIGs stored in an rrset of type RRSIG for this node */
+ add_rrset_into_data(&data, &done, rrset, z, node);
+
+ /* canonicalize */
+ if(!rrset_canonicalize_to_buffer(region, buf, &key)) {
+ *reason = "out of memory";
+ regional_free_all(region);
+ return 0;
+ }
+ regional_free_all(region);
+
+ /* hash */
+ if(!zonemd_digest_update(hashalgo, h, sldns_buffer_begin(buf),
+ sldns_buffer_limit(buf), reason)) {
+ return 0;
+ }
+ return 1;
+}
+
+/** collate a domain's rrsets using the simple scheme */
+static int zonemd_simple_domain(struct auth_zone* z, int hashalgo,
+ struct secalgo_hash* h, struct auth_data* node,
+ struct regional* region, struct sldns_buffer* buf, char** reason)
+{
+ const size_t rrlistsize = 65536;
+ struct auth_rrset* rrlist[rrlistsize];
+ size_t i, rrnum = 0;
+ /* see if the domain is out of scope, the zone origin,
+ * that would be omitted */
+ if(!dname_subdomain_c(node->name, z->name))
+ return 1; /* continue */
+ /* loop over the rrsets in ascending order. */
+ rrnum = authdata_rrsets_to_list(rrlist, rrlistsize, node->rrsets);
+ addrrsigtype_if_needed(rrlist, rrlistsize, &rrnum, node);
+ qsort(rrlist, rrnum, sizeof(*rrlist), rrlist_compare);
+ for(i=0; i<rrnum; i++) {
+ if(rrlist[i] && rrlist[i]->type == LDNS_RR_TYPE_ZONEMD &&
+ query_dname_compare(z->name, node->name) == 0) {
+ /* omit type ZONEMD at apex */
+ continue;
+ }
+ if(rrlist[i] == NULL || rrlist[i]->type ==
+ LDNS_RR_TYPE_RRSIG) {
+ if(!zonemd_simple_rrsig(z, hashalgo, h, node,
+ rrlist[i], rrlist, rrnum, region, buf, reason))
+ return 0;
+ } else if(!zonemd_simple_rrset(z, hashalgo, h, node,
+ rrlist[i], region, buf, reason)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/** collate the zone using the simple scheme */
+static int zonemd_simple_collate(struct auth_zone* z, int hashalgo,
+ struct secalgo_hash* h, struct regional* region,
+ struct sldns_buffer* buf, char** reason)
+{
+ /* our tree is sorted in canonical order, so we can just loop over
+ * the tree */
+ struct auth_data* n;
+ RBTREE_FOR(n, struct auth_data*, &z->data) {
+ if(!zonemd_simple_domain(z, hashalgo, h, n, region, buf,
+ reason))
+ return 0;
+ }
+ return 1;
+}
+
+int auth_zone_generate_zonemd_hash(struct auth_zone* z, int scheme,
+ int hashalgo, uint8_t* hash, size_t hashlen, size_t* resultlen,
+ struct regional* region, struct sldns_buffer* buf, char** reason)
+{
+ struct secalgo_hash* h = zonemd_digest_init(hashalgo, reason);
+ if(!h) {
+ if(!*reason)
+ *reason = "digest init fail";
+ return 0;
+ }
+ if(scheme == ZONEMD_SCHEME_SIMPLE) {
+ if(!zonemd_simple_collate(z, hashalgo, h, region, buf, reason)) {
+ if(!*reason) *reason = "scheme simple collate fail";
+ secalgo_hash_delete(h);
+ return 0;
+ }
+ }
+ if(!zonemd_digest_finish(hashalgo, h, hash, hashlen, resultlen,
+ reason)) {
+ secalgo_hash_delete(h);
+ *reason = "digest finish fail";
+ return 0;
+ }
+ secalgo_hash_delete(h);
+ return 1;
+}
+
+int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,
+ int hashalgo, uint8_t* hash, size_t hashlen, struct regional* region,
+ struct sldns_buffer* buf, char** reason)
+{
+ uint8_t gen[512];
+ size_t genlen = 0;
+ if(!zonemd_hashalgo_supported(hashalgo)) {
+ *reason = "unsupported algorithm";
+ return 0;
+ }
+ if(!zonemd_scheme_supported(scheme)) {
+ *reason = "unsupported scheme";
+ return 0;
+ }
+ if(hashlen < 12) {
+ /* the ZONEMD draft requires digests to fail if too small */
+ *reason = "digest length too small, less than 12";
+ return 0;
+ }
+ /* generate digest */
+ if(!auth_zone_generate_zonemd_hash(z, scheme, hashalgo, gen,
+ sizeof(gen), &genlen, region, buf, reason)) {
+ /* reason filled in by zonemd hash routine */
+ return 0;
+ }
+ /* check digest length */
+ if(hashlen != genlen) {
+ *reason = "incorrect digest length";
+ if(verbosity >= VERB_ALGO) {
+ verbose(VERB_ALGO, "zonemd scheme=%d hashalgo=%d",
+ scheme, hashalgo);
+ log_hex("ZONEMD should be ", gen, genlen);
+ log_hex("ZONEMD to check is", hash, hashlen);
+ }
+ return 0;
+ }
+ /* check digest */
+ if(memcmp(hash, gen, genlen) != 0) {
+ *reason = "incorrect digest";
+ if(verbosity >= VERB_ALGO) {
+ verbose(VERB_ALGO, "zonemd scheme=%d hashalgo=%d",
+ scheme, hashalgo);
+ log_hex("ZONEMD should be ", gen, genlen);
+ log_hex("ZONEMD to check is", hash, hashlen);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+/** log auth zone message with zone name in front. */
+static void auth_zone_log(uint8_t* name, enum verbosity_value level,
+ const char* format, ...) ATTR_FORMAT(printf, 3, 4);
+static void auth_zone_log(uint8_t* name, enum verbosity_value level,
+ const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ if(verbosity >= level) {
+ char str[255+1];
+ char msg[MAXSYSLOGMSGLEN];
+ dname_str(name, str);
+ vsnprintf(msg, sizeof(msg), format, args);
+ verbose(level, "auth zone %s %s", str, msg);
+ }
+ va_end(args);
+}
+
+/** ZONEMD, dnssec verify the rrset with the dnskey */
+static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
+ struct module_env* env, struct module_stack* mods,
+ struct ub_packed_rrset_key* dnskey, struct auth_data* node,
+ struct auth_rrset* rrset, char** why_bogus)
+{
+ struct ub_packed_rrset_key pk;
+ enum sec_status sec;
+ struct val_env* ve;
+ int m;
+ m = modstack_find(mods, "validator");
+ if(m == -1) {
+ auth_zone_log(z->name, VERB_ALGO, "zonemd dnssec verify: have "
+ "DNSKEY chain of trust, but no validator module");
+ return 0;
+ }
+ ve = (struct val_env*)env->modinfo[m];
+
+ memset(&pk, 0, sizeof(pk));
+ pk.entry.key = &pk;
+ pk.entry.data = rrset->data;
+ pk.rk.dname = node->name;
+ pk.rk.dname_len = node->namelen;
+ pk.rk.type = htons(rrset->type);
+ pk.rk.rrset_class = htons(z->dclass);
+ if(verbosity >= VERB_ALGO) {
+ char typestr[32];
+ typestr[0]=0;
+ sldns_wire2str_type_buf(rrset->type, typestr, sizeof(typestr));
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd: verify %s RRset with DNSKEY", typestr);
+ }
+ sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, NULL, why_bogus,
+ LDNS_SECTION_ANSWER, NULL);
+ if(sec == sec_status_secure) {
+ return 1;
+ }
+ if(why_bogus)
+ auth_zone_log(z->name, VERB_ALGO, "DNSSEC verify was bogus: %s", *why_bogus);
+ return 0;
+}
+
+/** check for nsec3, the RR with params equal, if bitmap has the type */
+static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
+ size_t iter, uint8_t* salt, size_t saltlen, uint16_t rrtype)
+{
+ int i, count = (int)nsec3->data->count;
+ struct ub_packed_rrset_key pk;
+ memset(&pk, 0, sizeof(pk));
+ pk.entry.data = nsec3->data;
+ for(i=0; i<count; i++) {
+ int rralgo;
+ size_t rriter, rrsaltlen;
+ uint8_t* rrsalt;
+ if(!nsec3_get_params(&pk, i, &rralgo, &rriter, &rrsalt,
+ &rrsaltlen))
+ continue; /* no parameters, malformed */
+ if(rralgo != algo || rriter != iter || rrsaltlen != saltlen)
+ continue; /* different parameters */
+ if(saltlen != 0) {
+ if(rrsalt == NULL || salt == NULL)
+ continue;
+ if(memcmp(rrsalt, salt, saltlen) != 0)
+ continue; /* different salt parameters */
+ }
+ if(nsec3_has_type(&pk, i, rrtype))
+ return 1;
+ }
+ return 0;
+}
+
+/** Verify the absence of ZONEMD with DNSSEC by checking NSEC, NSEC3 type flag.
+ * return false on failure, reason contains description of failure. */
+static int zonemd_check_dnssec_absence(struct auth_zone* z,
+ struct module_env* env, struct module_stack* mods,
+ struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
+ char** reason, char** why_bogus)
+{
+ struct auth_rrset* nsec = NULL;
+ if(!apex) {
+ *reason = "zone has no apex domain but ZONEMD missing";
+ return 0;
+ }
+ nsec = az_domain_rrset(apex, LDNS_RR_TYPE_NSEC);
+ if(nsec) {
+ struct ub_packed_rrset_key pk;
+ /* dnssec verify the NSEC */
+ if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
+ nsec, why_bogus)) {
+ *reason = "DNSSEC verify failed for NSEC RRset";
+ return 0;
+ }
+ /* check type bitmap */
+ memset(&pk, 0, sizeof(pk));
+ pk.entry.data = nsec->data;
+ if(nsec_has_type(&pk, LDNS_RR_TYPE_ZONEMD)) {
+ *reason = "DNSSEC NSEC bitmap says type ZONEMD exists";
+ return 0;
+ }
+ auth_zone_log(z->name, VERB_ALGO, "zonemd DNSSEC NSEC verification of absence of ZONEMD secure");
+ } else {
+ /* NSEC3 perhaps ? */
+ int algo;
+ size_t iter, saltlen;
+ uint8_t* salt;
+ struct auth_rrset* nsec3param = az_domain_rrset(apex,
+ LDNS_RR_TYPE_NSEC3PARAM);
+ struct auth_data* match;
+ struct auth_rrset* nsec3;
+ if(!nsec3param) {
+ *reason = "zone has no NSEC information but ZONEMD missing";
+ return 0;
+ }
+ if(!az_nsec3_param(z, &algo, &iter, &salt, &saltlen)) {
+ *reason = "zone has no NSEC information but ZONEMD missing";
+ return 0;
+ }
+ /* find the NSEC3 record */
+ match = az_nsec3_find_exact(z, z->name, z->namelen, algo,
+ iter, salt, saltlen);
+ if(!match) {
+ *reason = "zone has no NSEC3 domain for the apex but ZONEMD missing";
+ return 0;
+ }
+ nsec3 = az_domain_rrset(match, LDNS_RR_TYPE_NSEC3);
+ if(!nsec3) {
+ *reason = "zone has no NSEC3 RRset for the apex but ZONEMD missing";
+ return 0;
+ }
+ /* dnssec verify the NSEC3 */
+ if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
+ nsec3, why_bogus)) {
+ *reason = "DNSSEC verify failed for NSEC3 RRset";
+ return 0;
+ }
+ /* check type bitmap */
+ if(nsec3_of_param_has_type(nsec3, algo, iter, salt, saltlen,
+ LDNS_RR_TYPE_ZONEMD)) {
+ *reason = "DNSSEC NSEC3 bitmap says type ZONEMD exists";
+ return 0;
+ }
+ auth_zone_log(z->name, VERB_ALGO, "zonemd DNSSEC NSEC3 verification of absence of ZONEMD secure");
+ }
+
+ return 1;
+}
+
+/** Verify the SOA and ZONEMD DNSSEC signatures.
+ * return false on failure, reason contains description of failure. */
+static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
+ struct module_env* env, struct module_stack* mods,
+ struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
+ struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus)
+{
+ struct auth_rrset* soa;
+ if(!apex) {
+ *reason = "zone has no apex domain";
+ return 0;
+ }
+ soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
+ if(!soa) {
+ *reason = "zone has no SOA RRset";
+ return 0;
+ }
+ if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
+ why_bogus)) {
+ *reason = "DNSSEC verify failed for SOA RRset";
+ return 0;
+ }
+ if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
+ zonemd_rrset, why_bogus)) {
+ *reason = "DNSSEC verify failed for ZONEMD RRset";
+ return 0;
+ }
+ auth_zone_log(z->name, VERB_ALGO, "zonemd DNSSEC verification of SOA and ZONEMD RRsets secure");
+ return 1;
+}
+
+/**
+ * Fail the ZONEMD verification.
+ * @param z: auth zone that fails.
+ * @param env: environment with config, to ignore failure or not.
+ * @param reason: failure string description.
+ * @param why_bogus: failure string for DNSSEC verification failure.
+ * @param result: strdup result in here if not NULL.
+ */
+static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env,
+ char* reason, char* why_bogus, char** result)
+{
+ char zstr[255+1];
+ /* if fail: log reason, and depending on config also take action
+ * and drop the zone, eg. it is gone from memory, set zone_expired */
+ dname_str(z->name, zstr);
+ if(!reason) reason = "verification failed";
+ if(result) {
+ if(why_bogus) {
+ char res[1024];
+ snprintf(res, sizeof(res), "%s: %s", reason,
+ why_bogus);
+ *result = strdup(res);
+ } else {
+ *result = strdup(reason);
+ }
+ if(!*result) log_err("out of memory");
+ } else {
+ log_warn("auth zone %s: ZONEMD verification failed: %s", zstr, reason);
+ }
+
+ if(env->cfg->zonemd_permissive_mode) {
+ verbose(VERB_ALGO, "zonemd-permissive-mode enabled, "
+ "not blocking zone %s", zstr);
+ return;
+ }
+
+ /* expired means the zone gives servfail and is not used by
+ * lookup if fallback_enabled*/
+ z->zone_expired = 1;
+}
+
+/**
+ * Verify the zonemd with DNSSEC and hash check, with given key.
+ * @param z: auth zone.
+ * @param env: environment with config and temp buffers.
+ * @param mods: module stack with validator env for verification.
+ * @param dnskey: dnskey that we can use, or NULL. If nonnull, the key
+ * has been verified and is the start of the chain of trust.
+ * @param is_insecure: if true, the dnskey is not used, the zone is insecure.
+ * And dnssec is not used. It is DNSSEC secure insecure or not under
+ * a trust anchor.
+ * @param result: if not NULL result reason copied here.
+ */
+static void
+auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
+ struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
+ int is_insecure, char** result)
+{
+ char* reason = NULL, *why_bogus = NULL;
+ struct auth_data* apex = NULL;
+ struct auth_rrset* zonemd_rrset = NULL;
+ int zonemd_absent = 0, zonemd_absence_dnssecok = 0;
+
+ /* see if ZONEMD is present or absent. */
+ apex = az_find_name(z, z->name, z->namelen);
+ if(!apex) {
+ zonemd_absent = 1;
+ } else {
+ zonemd_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_ZONEMD);
+ if(!zonemd_rrset || zonemd_rrset->data->count==0) {
+ zonemd_absent = 1;
+ zonemd_rrset = NULL;
+ }
+ }
+
+ /* if no DNSSEC, done. */
+ /* if no ZONEMD, and DNSSEC, use DNSKEY to verify NSEC or NSEC3 for
+ * zone apex. Check ZONEMD bit is turned off or else fail */
+ /* if ZONEMD, and DNSSEC, check DNSSEC signature on SOA and ZONEMD,
+ * or else fail */
+ if(!dnskey && !is_insecure) {
+ auth_zone_zonemd_fail(z, env, "DNSKEY missing", NULL, result);
+ return;
+ } else if(!zonemd_rrset && dnskey && !is_insecure) {
+ /* fetch, DNSSEC verify, and check NSEC/NSEC3 */
+ if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
+ &reason, &why_bogus)) {
+ auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
+ return;
+ }
+ zonemd_absence_dnssecok = 1;
+ } else if(zonemd_rrset && dnskey && !is_insecure) {
+ /* check DNSSEC verify of SOA and ZONEMD */
+ if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
+ zonemd_rrset, &reason, &why_bogus)) {
+ auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
+ return;
+ }
+ }
+
+ if(zonemd_absent && z->zonemd_reject_absence) {
+ auth_zone_zonemd_fail(z, env, "ZONEMD absent and that is not allowed by config", NULL, result);
+ return;
+ }
+ if(zonemd_absent && zonemd_absence_dnssecok) {
+ auth_zone_log(z->name, VERB_ALGO, "DNSSEC verified nonexistence of ZONEMD");
+ if(result) {
+ *result = strdup("DNSSEC verified nonexistence of ZONEMD");
+ if(!*result) log_err("out of memory");
+ }
+ return;
+ }
+ if(zonemd_absent) {
+ auth_zone_log(z->name, VERB_ALGO, "no ZONEMD present");
+ if(result) {
+ *result = strdup("no ZONEMD present");
+ if(!*result) log_err("out of memory");
+ }
+ return;
+ }
+
+ /* check ZONEMD checksum and report or else fail. */
+ if(!auth_zone_zonemd_check_hash(z, env, &reason)) {
+ auth_zone_zonemd_fail(z, env, reason, NULL, result);
+ return;
+ }
+
+ /* success! log the success */
+ auth_zone_log(z->name, VERB_ALGO, "ZONEMD verification successful");
+ if(result) {
+ *result = strdup("ZONEMD verification successful");
+ if(!*result) log_err("out of memory");
+ }
+}
+
+/**
+ * verify the zone DNSKEY rrset from the trust anchor
+ * This is possible because the anchor is for the zone itself, and can
+ * thus apply straight to the zone DNSKEY set.
+ * @param z: the auth zone.
+ * @param env: environment with time and temp buffers.
+ * @param mods: module stack for validator environment for dnssec validation.
+ * @param anchor: trust anchor to use
+ * @param is_insecure: returned, true if the zone is securely insecure.
+ * @param why_bogus: if the routine fails, returns the failure reason.
+ * @param keystorage: where to store the ub_packed_rrset_key that is created
+ * on success. A pointer to it is returned on success.
+ * @return the dnskey RRset, reference to zone data and keystorage, or
+ * NULL on failure.
+ */
+static struct ub_packed_rrset_key*
+zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
+ struct module_stack* mods, struct trust_anchor* anchor,
+ int* is_insecure, char** why_bogus,
+ struct ub_packed_rrset_key* keystorage)
+{
+ struct auth_data* apex;
+ struct auth_rrset* dnskey_rrset;
+ enum sec_status sec;
+ struct val_env* ve;
+ int m;
+
+ apex = az_find_name(z, z->name, z->namelen);
+ if(!apex) {
+ *why_bogus = "have trust anchor, but zone has no apex domain for DNSKEY";
+ return 0;
+ }
+ dnskey_rrset = az_domain_rrset(apex, LDNS_RR_TYPE_DNSKEY);
+ if(!dnskey_rrset || dnskey_rrset->data->count==0) {
+ *why_bogus = "have trust anchor, but zone has no DNSKEY";
+ return 0;
+ }
+
+ m = modstack_find(mods, "validator");
+ if(m == -1) {
+ *why_bogus = "have trust anchor, but no validator module";
+ return 0;
+ }
+ ve = (struct val_env*)env->modinfo[m];
+
+ memset(keystorage, 0, sizeof(*keystorage));
+ keystorage->entry.key = keystorage;
+ keystorage->entry.data = dnskey_rrset->data;
+ keystorage->rk.dname = apex->name;
+ keystorage->rk.dname_len = apex->namelen;
+ keystorage->rk.type = htons(LDNS_RR_TYPE_DNSKEY);
+ keystorage->rk.rrset_class = htons(z->dclass);
+ auth_zone_log(z->name, VERB_QUERY,
+ "zonemd: verify DNSKEY RRset with trust anchor");
+ sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
+ anchor->dnskey_rrset, NULL, why_bogus, NULL);
+ regional_free_all(env->scratch);
+ if(sec == sec_status_secure) {
+ /* success */
+ *is_insecure = 0;
+ return keystorage;
+ } else if(sec == sec_status_insecure) {
+ /* insecure */
+ *is_insecure = 1;
+ } else {
+ /* bogus */
+ *is_insecure = 0;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd: verify DNSKEY RRset with trust anchor failed: %s", *why_bogus);
+ }
+ return NULL;
+}
+
+/** callback for ZONEMD lookup of DNSKEY */
+void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
+ enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
+{
+ struct auth_zone* z = (struct auth_zone*)arg;
+ struct module_env* env;
+ char* reason = NULL;
+ struct ub_packed_rrset_key* dnskey = NULL;
+ int is_insecure = 0;
+
+ lock_rw_wrlock(&z->lock);
+ env = z->zonemd_callback_env;
+ /* release the env variable so another worker can pick up the
+ * ZONEMD verification task if it wants to */
+ z->zonemd_callback_env = NULL;
+ if(!env || env->outnet->want_to_quit || z->zone_deleted) {
+ lock_rw_unlock(&z->lock);
+ return; /* stop on quit */
+ }
+
+ /* process result */
+ if(sec == sec_status_bogus) {
+ reason = why_bogus;
+ if(!reason)
+ reason = "lookup of DNSKEY was bogus";
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was bogus: %s", reason);
+ } else if(rcode == LDNS_RCODE_NOERROR) {
+ uint16_t wanted_qtype = LDNS_RR_TYPE_DNSKEY;
+ struct regional* temp = env->scratch;
+ struct query_info rq;
+ struct reply_info* rep;
+ memset(&rq, 0, sizeof(rq));
+ rep = parse_reply_in_temp_region(buf, temp, &rq);
+ if(rep && rq.qtype == wanted_qtype &&
+ query_dname_compare(z->name, rq.qname) == 0 &&
+ FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR) {
+ /* parsed successfully */
+ struct ub_packed_rrset_key* answer =
+ reply_find_answer_rrset(&rq, rep);
+ if(answer && sec == sec_status_secure) {
+ dnskey = answer;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was secure");
+ } else if(sec == sec_status_secure && !answer) {
+ is_insecure = 1;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY has no content, but is secure, treat as insecure");
+ } else if(sec == sec_status_insecure) {
+ is_insecure = 1;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was insecure");
+ } else if(sec == sec_status_indeterminate) {
+ is_insecure = 1;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was indeterminate, treat as insecure");
+ } else {
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY has nodata");
+ reason = "lookup of DNSKEY has nodata";
+ }
+ } else if(rep && rq.qtype == wanted_qtype &&
+ query_dname_compare(z->name, rq.qname) == 0 &&
+ FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN &&
+ sec == sec_status_secure) {
+ /* secure nxdomain, so the zone is like some RPZ zone
+ * that does not exist in the wider internet, with
+ * a secure nxdomain answer outside of it. So we
+ * treat the zonemd zone without a dnssec chain of
+ * trust, as insecure. */
+ is_insecure = 1;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was secure NXDOMAIN, treat as insecure");
+ } else if(rep && rq.qtype == wanted_qtype &&
+ query_dname_compare(z->name, rq.qname) == 0 &&
+ FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN &&
+ sec == sec_status_insecure) {
+ is_insecure = 1;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was insecure NXDOMAIN, treat as insecure");
+ } else if(rep && rq.qtype == wanted_qtype &&
+ query_dname_compare(z->name, rq.qname) == 0 &&
+ FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN &&
+ sec == sec_status_indeterminate) {
+ is_insecure = 1;
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY was indeterminate NXDOMAIN, treat as insecure");
+ } else {
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY has no answer");
+ reason = "lookup of DNSKEY has no answer";
+ }
+ } else {
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd lookup of DNSKEY failed");
+ reason = "lookup of DNSKEY failed";
+ }
+
+ if(reason) {
+ auth_zone_zonemd_fail(z, env, reason, NULL, NULL);
+ lock_rw_unlock(&z->lock);
+ return;
+ }
+
+ auth_zone_verify_zonemd_with_key(z, env, &env->mesh->mods, dnskey,
+ is_insecure, NULL);
+ regional_free_all(env->scratch);
+ lock_rw_unlock(&z->lock);
+}
+
+/** lookup DNSKEY for ZONEMD verification */
+static int
+zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
+{
+ struct query_info qinfo;
+ uint16_t qflags = BIT_RD;
+ struct edns_data edns;
+ sldns_buffer* buf = env->scratch_buffer;
+
+ if(z->zonemd_callback_env) {
+ /* another worker is already working on the callback
+ * for the DNSKEY lookup for ZONEMD verification.
+ * We do not also have to do ZONEMD verification, let that
+ * worker do it */
+ auth_zone_log(z->name, VERB_ALGO,
+ "zonemd needs lookup of DNSKEY and that already worked on by another worker");
+ return 1;
+ }
+
+ /* use mesh_new_callback to lookup the DNSKEY,
+ * and then wait for them to be looked up (in cache, or query) */
+ qinfo.qname_len = z->namelen;
+ qinfo.qname = z->name;
+ qinfo.qclass = z->dclass;
+ qinfo.qtype = LDNS_RR_TYPE_DNSKEY;
+ qinfo.local_alias = NULL;
+ if(verbosity >= VERB_ALGO) {
+ char buf1[512];
+ char buf2[LDNS_MAX_DOMAINLEN+1];
+ dname_str(z->name, buf2);
+ snprintf(buf1, sizeof(buf1), "auth zone %s: lookup DNSKEY "
+ "for zonemd verification", buf2);
+ log_query_info(VERB_ALGO, buf1, &qinfo);
+ }
+ edns.edns_present = 1;
+ edns.ext_rcode = 0;
+ edns.edns_version = 0;
+ edns.bits = EDNS_DO;
+ edns.opt_list = NULL;
+ if(sldns_buffer_capacity(buf) < 65535)
+ edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
+ else edns.udp_size = 65535;
+
+ /* store the worker-specific module env for the callback.
+ * We can then reference this when the callback executes */
+ z->zonemd_callback_env = env;
+ /* the callback can be called straight away */
+ lock_rw_unlock(&z->lock);
+ if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
+ &auth_zonemd_dnskey_lookup_callback, z)) {
+ lock_rw_wrlock(&z->lock);
+ log_err("out of memory lookup up dnskey for zonemd");
+ return 0;
+ }
+ lock_rw_wrlock(&z->lock);
+ return 1;
+}
+
+void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
+ struct module_stack* mods, char** result, int offline, int only_online)
+{
+ char* reason = NULL, *why_bogus = NULL;
+ struct trust_anchor* anchor = NULL;
+ struct ub_packed_rrset_key* dnskey = NULL;
+ struct ub_packed_rrset_key keystorage;
+ int is_insecure = 0;
+ /* verify the ZONEMD if present.
+ * If not present check if absence is allowed by DNSSEC */
+ if(!z->zonemd_check)
+ return;
+
+ /* if zone is under a trustanchor */
+ /* is it equal to trustanchor - get dnskey's verified */
+ /* else, find chain of trust by fetching DNSKEYs lookup for zone */
+ /* result if that, if insecure, means no DNSSEC for the ZONEMD,
+ * otherwise we have the zone DNSKEY for the DNSSEC verification. */
+ if(env->anchors)
+ anchor = anchors_lookup(env->anchors, z->name, z->namelen,
+ z->dclass);
+ if(anchor && anchor->numDS == 0 && anchor->numDNSKEY == 0) {
+ /* domain-insecure trust anchor for unsigned zones */
+ lock_basic_unlock(&anchor->lock);
+ if(only_online)
+ return;
+ dnskey = NULL;
+ is_insecure = 1;
+ } else if(anchor && query_dname_compare(z->name, anchor->name) == 0) {
+ if(only_online) {
+ lock_basic_unlock(&anchor->lock);
+ return;
+ }
+ /* equal to trustanchor, no need for online lookups */
+ dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor,
+ &is_insecure, &why_bogus, &keystorage);
+ lock_basic_unlock(&anchor->lock);
+ if(!dnskey && !reason && !is_insecure) {
+ reason = "verify DNSKEY RRset with trust anchor failed";
+ }
+ } else if(anchor) {
+ lock_basic_unlock(&anchor->lock);
+ /* perform online lookups */
+ if(offline)
+ return;
+ /* setup online lookups, and wait for them */
+ if(zonemd_lookup_dnskey(z, env)) {
+ /* wait for the lookup */
+ return;
+ }
+ reason = "could not lookup DNSKEY for chain of trust";
+ } else {
+ /* the zone is not under a trust anchor */
+ if(only_online)
+ return;
+ dnskey = NULL;
+ is_insecure = 1;
+ }
+
+ if(reason) {
+ auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
+ return;
+ }
+
+ auth_zone_verify_zonemd_with_key(z, env, mods, dnskey, is_insecure,
+ result);
+ regional_free_all(env->scratch);
+}
+
+void auth_zones_pickup_zonemd_verify(struct auth_zones* az,
+ struct module_env* env)
+{
+ struct auth_zone key;
+ uint8_t savezname[255+1];
+ size_t savezname_len;
+ struct auth_zone* z;
+ key.node.key = &key;
+ lock_rw_rdlock(&az->lock);
+ RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
+ lock_rw_wrlock(&z->lock);
+ if(!z->zonemd_check) {
+ lock_rw_unlock(&z->lock);
+ continue;
+ }
+ key.dclass = z->dclass;
+ key.namelabs = z->namelabs;
+ if(z->namelen > sizeof(savezname)) {
+ lock_rw_unlock(&z->lock);
+ log_err("auth_zones_pickup_zonemd_verify: zone name too long");
+ continue;
+ }
+ savezname_len = z->namelen;
+ memmove(savezname, z->name, z->namelen);
+ lock_rw_unlock(&az->lock);
+ auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 1);
+ lock_rw_unlock(&z->lock);
+ lock_rw_rdlock(&az->lock);
+ /* find the zone we had before, it is not deleted,
+ * because we have a flag for that that is processed at
+ * apply_cfg time */
+ key.namelen = savezname_len;
+ key.name = savezname;
+ z = (struct auth_zone*)rbtree_search(&az->ztree, &key);
+ if(!z)
+ break;
+ }
+ lock_rw_unlock(&az->lock);
+}
/** for upstream: this zone answers queries that unbound intends to
* send upstream. */
int for_upstream;
+ /** check ZONEMD records */
+ int zonemd_check;
+ /** reject absence of ZONEMD records */
+ int zonemd_reject_absence;
/** RPZ zones */
struct rpz* rpz;
+ /** store the env (worker thread specific) for the zonemd callbacks
+ * from the mesh with the results of the lookup, if nonNULL, some
+ * worker has already picked up the zonemd verification task and
+ * this worker does not have to do it as well. */
+ struct module_env* zonemd_callback_env;
/** zone has been deleted */
int zone_deleted;
/** deletelist pointer, unused normally except during delete */
* @param cfg: config to apply.
* @param setup: if true, also sets up values in the auth zones structure
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
+ * @param env: environment for offline verification.
+ * @param mods: modules in environment.
* @return false on failure.
*/
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
- int setup, int* is_rpz);
+ int setup, int* is_rpz, struct module_env* env,
+ struct module_stack* mods);
/** initial pick up of worker timeouts, ties events to worker event loop
* @param az: auth zones structure
/** find serial number of zone or false if none (no SOA record) */
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
+/** Find auth_zone SOA and populate the values in xfr(soa values). */
+int xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr);
+
/** compare auth_zones for sorted rbtree */
int auth_zone_cmp(const void* z1, const void* z2);
*/
int compare_serial(uint32_t a, uint32_t b);
+/**
+ * Generate ZONEMD digest for the auth zone.
+ * @param z: the auth zone to digest.
+ * omits zonemd at apex and its RRSIG from the digest.
+ * @param scheme: the collation scheme to use. Numbers as defined for ZONEMD.
+ * @param hashalgo: the hash algo, from the registry defined for ZONEMD type.
+ * @param hash: the result buffer.
+ * @param buflen: size of the result buffer, must be large enough. or the
+ * routine fails.
+ * @param resultlen: size of the hash in the result buffer of the result.
+ * @param region: temp region for allocs during canonicalisation.
+ * @param buf: temp buffer during canonicalisation.
+ * @param reason: failure reason, returns a string, NULL on success.
+ * @return false on failure.
+ */
+int auth_zone_generate_zonemd_hash(struct auth_zone* z, int scheme,
+ int hashalgo, uint8_t* hash, size_t buflen, size_t* resultlen,
+ struct regional* region, struct sldns_buffer* buf, char** reason);
+
+/** ZONEMD scheme definitions */
+#define ZONEMD_SCHEME_SIMPLE 1
+
+/** ZONEMD hash algorithm definition for SHA384 */
+#define ZONEMD_ALGO_SHA384 1
+/** ZONEMD hash algorithm definition for SHA512 */
+#define ZONEMD_ALGO_SHA512 2
+
+/** returns true if a zonemd hash algo is supported */
+int zonemd_hashalgo_supported(int hashalgo);
+/** returns true if a zonemd scheme is supported */
+int zonemd_scheme_supported(int scheme);
+
+/**
+ * Check ZONEMD digest for the auth zone.
+ * @param z: auth zone to digest.
+ * @param scheme: zonemd scheme.
+ * @param hashalgo: zonemd hash algorithm.
+ * @param hash: the hash to check.
+ * @param hashlen: length of hash buffer.
+ * @param region: temp region for allocs during canonicalisation.
+ * @param buf: temp buffer during canonicalisation.
+ * @param reason: string returned with failure reason.
+ * @return false on failure.
+ */
+int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,
+ int hashalgo, uint8_t* hash, size_t hashlen, struct regional* region,
+ struct sldns_buffer* buf, char** reason);
+
+/**
+ * Perform ZONEMD checks and verification for the auth zone.
+ * This includes DNSSEC verification if applicable.
+ * @param z: auth zone to check. Caller holds lock. wrlock.
+ * @param env: with temp region, buffer and config.
+ * @param mods: module stack for validator env.
+ * @param result: if not NULL, result string strdupped in here.
+ * @param offline: if true, there is no spawned lookup when online is needed.
+ * Those zones are skipped for ZONEMD checking.
+ * @param only_online: if true, only for ZONEMD that need online lookup
+ * of DNSKEY chain of trust are processed.
+ */
+void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
+ struct module_stack* mods, char** result, int offline,
+ int only_online);
+
+/** mesh callback for zonemd on lookup of dnskey */
+void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode,
+ struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
+ int was_ratelimited);
+
+/**
+ * Check the ZONEMD records that need online DNSSEC chain lookups,
+ * for them spawn the lookup process to get it checked out.
+ * Attaches the lookup process to the worker event base and mesh state.
+ * @param az: auth zones, every zones is checked.
+ * @param env: env of the worker where the task is attached.
+ */
+void auth_zones_pickup_zonemd_verify(struct auth_zones* az,
+ struct module_env* env);
+
#endif /* SERVICES_AUTHZONE_H */
dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
uint16_t flags, struct regional* region, struct regional* scratch,
- int no_partial)
+ int no_partial, uint8_t* dpname, size_t dpnamelen)
{
struct lruhash_entry* e;
struct query_info k;
* the same. We search upwards for NXDOMAINs. */
if(env->cfg->harden_below_nxdomain) {
while(!dname_is_root(k.qname)) {
+ if(dpname && dpnamelen
+ && !dname_subdomain_c(k.qname, dpname))
+ break; /* no synth nxdomain above the stub */
dname_remove_label(&k.qname, &k.qname_len);
h = query_info_hash(&k, flags);
e = slabhash_lookup(env->msg_cache, h, &k, 0);
* @param scratch: where to allocate temporary data.
* @param no_partial: if true, only complete messages and not a partial
* one (with only the start of the CNAME chain and not the rest).
+ * @param dpname: if not NULL, do not return NXDOMAIN above this name.
+ * @param dpnamelen: length of dpname.
* @return new response message (alloced in region, rrsets do not have IDs).
* or NULL on error or if not found in cache.
* TTLs are made relative to the current time.
struct dns_msg* dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
uint16_t flags, struct regional* region, struct regional* scratch,
- int no_partial);
+ int no_partial, uint8_t* dpname, size_t dpnamelen);
/**
* find and add A and AAAA records for missing nameservers in delegpt
sizeof(struct infra_cache));
size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
sizeof(struct infra_data)+INFRA_BYTES_NAME);
+ if(!infra) {
+ return NULL;
+ }
infra->hosts = slabhash_create(cfg->infra_cache_slabs,
INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc,
&infra_delkeyfunc, &infra_deldatafunc, NULL);
}
}
+void
+verbose_print_unbound_socket(struct unbound_socket* ub_sock)
+{
+ if(verbosity >= VERB_ALGO) {
+ log_info("listing of unbound_socket structure:");
+ verbose_print_addr(ub_sock->addr);
+ log_info("s is: %d, fam is: %s", ub_sock->s, ub_sock->fam == AF_INET?"AF_INET":"AF_INET6");
+ }
+}
+
#ifdef HAVE_SYSTEMD
static int
systemd_get_activated(int family, int socktype, int listen,
if(err != NULL)
log_warn("error setting IP DiffServ codepoint %d on UDP socket: %s", dscp, err);
if(family == AF_INET6) {
+# if defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
+ int omit6_set = 0;
+ int action;
+# endif
# if defined(IPV6_V6ONLY)
if(v6only) {
int val=(v6only==2)?0:1;
return -1;
}
# endif /* IPv6 MTU */
+# if defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
+# if defined(IP_PMTUDISC_OMIT)
+ action = IP_PMTUDISC_OMIT;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &action, (socklen_t)sizeof(action)) < 0) {
+
+ if (errno != EINVAL) {
+ log_err("setsockopt(..., IPV6_MTU_DISCOVER, IP_PMTUDISC_OMIT...) failed: %s",
+ strerror(errno));
+ sock_close(s);
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+ }
+ }
+ else
+ {
+ omit6_set = 1;
+ }
+# endif
+ if (omit6_set == 0) {
+ action = IP_PMTUDISC_DONT;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &action, (socklen_t)sizeof(action)) < 0) {
+ log_err("setsockopt(..., IPV6_MTU_DISCOVER, IP_PMTUDISC_DONT...) failed: %s",
+ strerror(errno));
+ sock_close(s);
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+ }
+ }
+# endif /* IPV6_MTU_DISCOVER */
} else if(family == AF_INET) {
# if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
/* linux 3.15 has IP_PMTUDISC_OMIT, Hannes Frederic Sowa made it so that
make_sock(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
- int use_systemd, int dscp)
+ int use_systemd, int dscp, struct unbound_socket* ub_sock)
{
struct addrinfo *res = NULL;
int r, s, inuse, noproto;
*noip6 = 1;
}
}
- freeaddrinfo(res);
+
+ ub_sock->addr = res;
+ ub_sock->s = s;
+ ub_sock->fam = hints->ai_family;
+
return s;
}
make_sock_port(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
- int use_systemd, int dscp)
+ int use_systemd, int dscp, struct unbound_socket* ub_sock)
{
char* s = strchr(ifname, '@');
if(s) {
p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6, rcv,
snd, reuseport, transparent, tcp_mss, nodelay, freebind,
- use_systemd, dscp);
+ use_systemd, dscp, ub_sock);
}
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd,
- dscp);
+ dscp, ub_sock);
}
/**
* @param list: list head. changed.
* @param s: fd.
* @param ftype: if fd is UDP.
+ * @param ub_sock: socket with address.
* @return false on failure. list in unchanged then.
*/
static int
-port_insert(struct listen_port** list, int s, enum listen_type ftype)
+port_insert(struct listen_port** list, int s, enum listen_type ftype, struct unbound_socket* ub_sock)
{
struct listen_port* item = (struct listen_port*)malloc(
sizeof(struct listen_port));
item->next = *list;
item->fd = s;
item->ftype = ftype;
+ item->socket = ub_sock;
*list = item;
return 1;
}
return 0;
}
# else
- log_err("no IPV6_RECVPKTINFO and no IPV6_PKTINFO option, please "
+ log_err("no IPV6_RECVPKTINFO and IPV6_PKTINFO options, please "
"disable interface-automatic or do-ip6 in config");
return 0;
# endif /* defined IPV6_RECVPKTINFO */
return 0;
}
-/** see if interface is https, its port number == the https port number */
-static int
-if_is_https(const char* ifname, const char* port, int https_port)
-{
- char* p = strchr(ifname, '@');
- if(!p && atoi(port) == https_port)
- return 1;
- if(p && atoi(p+1) == https_port)
- return 1;
- return 0;
-}
-
/**
* Helper for ports_open. Creates one interface (or NULL for default).
* @param ifname: The interface ip address.
int s, noip6=0;
int is_https = if_is_https(ifname, port, https_port);
int nodelay = is_https && http2_nodelay;
+ struct unbound_socket* ub_sock;
#ifdef USE_DNSCRYPT
int is_dnscrypt = ((strchr(ifname, '@') &&
atoi(strchr(ifname, '@')+1) == dnscrypt_port) ||
if(!do_udp && !do_tcp)
return 0;
+
if(do_auto) {
+ ub_sock = calloc(1, sizeof(struct unbound_socket));
+ if(!ub_sock)
+ return 0;
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent,
- tcp_mss, nodelay, freebind, use_systemd, dscp)) == -1) {
+ tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) {
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
/* getting source addr packet info is highly non-portable */
if(!set_recvpktinfo(s, hints->ai_family)) {
sock_close(s);
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
return 0;
}
if(!port_insert(list, s,
- is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil)) {
+ is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil, ub_sock)) {
sock_close(s);
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
return 0;
}
} else if(do_udp) {
+ ub_sock = calloc(1, sizeof(struct unbound_socket));
+ if(!ub_sock)
+ return 0;
/* regular udp socket */
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent,
- tcp_mss, nodelay, freebind, use_systemd, dscp)) == -1) {
+ tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) {
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
return 0;
}
if(!port_insert(list, s,
- is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp)) {
+ is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp, ub_sock)) {
sock_close(s);
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
return 0;
}
}
int is_ssl = if_is_ssl(ifname, port, ssl_port,
tls_additional_port);
enum listen_type port_type;
+ ub_sock = calloc(1, sizeof(struct unbound_socket));
+ if(!ub_sock)
+ return 0;
if(is_ssl)
port_type = listen_type_ssl;
else if(is_https)
port_type = listen_type_tcp;
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
&noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay,
- freebind, use_systemd, dscp)) == -1) {
+ freebind, use_systemd, dscp, ub_sock)) == -1) {
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
if(noip6) {
/*log_warn("IPv6 protocol not available");*/
return 1;
}
if(is_ssl)
verbose(VERB_ALGO, "setup TCP for SSL service");
- if(!port_insert(list, s, port_type)) {
+ if(!port_insert(list, s, port_type, ub_sock)) {
sock_close(s);
+ freeaddrinfo(ub_sock->addr);
+ free(ub_sock);
return 0;
}
}
if(ports->ftype == listen_type_udp ||
ports->ftype == listen_type_udp_dnscrypt)
cp = comm_point_create_udp(base, ports->fd,
- front->udp_buff, cb, cb_arg);
+ front->udp_buff, cb, cb_arg, ports->socket);
else if(ports->ftype == listen_type_tcp ||
ports->ftype == listen_type_tcp_dnscrypt)
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, tcp_idle_timeout,
harden_large_queries, 0, NULL,
tcp_conn_limit, bufsize, front->udp_buff,
- ports->ftype, cb, cb_arg);
+ ports->ftype, cb, cb_arg, ports->socket);
else if(ports->ftype == listen_type_ssl ||
ports->ftype == listen_type_http) {
cp = comm_point_create_tcp(base, ports->fd,
harden_large_queries,
http_max_streams, http_endpoint,
tcp_conn_limit, bufsize, front->udp_buff,
- ports->ftype, cb, cb_arg);
+ ports->ftype, cb, cb_arg, ports->socket);
if(http_notls && ports->ftype == listen_type_http)
cp->ssl = NULL;
else
} else if(ports->ftype == listen_type_udpancil ||
ports->ftype == listen_type_udpancil_dnscrypt)
cp = comm_point_create_udp_ancil(base, ports->fd,
- front->udp_buff, cb, cb_arg);
+ front->udp_buff, cb, cb_arg, ports->socket);
if(!cp) {
log_err("can't create commpoint");
listen_delete(front);
}
#endif /* HAVE_GETIFADDRS */
-int resolve_interface_names(struct config_file* cfg, char*** resif,
- int* num_resif)
+int resolve_interface_names(char** ifs, int num_ifs,
+ struct config_strlist* list, char*** resif, int* num_resif)
{
#ifdef HAVE_GETIFADDRS
- int i;
struct ifaddrs *addrs = NULL;
- if(cfg->num_ifs == 0) {
+ if(num_ifs == 0 && list == NULL) {
*resif = NULL;
*num_resif = 0;
return 1;
freeifaddrs(addrs);
return 0;
}
- for(i=0; i<cfg->num_ifs; i++) {
- if(!resolve_ifa_name(addrs, cfg->ifs[i], resif, num_resif)) {
- freeifaddrs(addrs);
- config_del_strarray(*resif, *num_resif);
- *resif = NULL;
- *num_resif = 0;
- return 0;
+ if(ifs) {
+ int i;
+ for(i=0; i<num_ifs; i++) {
+ if(!resolve_ifa_name(addrs, ifs[i], resif, num_resif)) {
+ freeifaddrs(addrs);
+ config_del_strarray(*resif, *num_resif);
+ *resif = NULL;
+ *num_resif = 0;
+ return 0;
+ }
}
}
+ if(list) {
+ struct config_strlist* p;
+ for(p = list; p; p = p->next) {
+ if(!resolve_ifa_name(addrs, p->str, resif, num_resif)) {
+ freeifaddrs(addrs);
+ config_del_strarray(*resif, *num_resif);
+ *resif = NULL;
+ *num_resif = 0;
+ return 0;
+ }
+}
+ }
freeifaddrs(addrs);
return 1;
#else
- int i;
- if(cfg->num_ifs == 0) {
+ struct config_strlist* p;
+ if(num_ifs == 0 && list == NULL) {
*resif = NULL;
*num_resif = 0;
return 1;
}
- *num_resif = cfg->num_ifs;
+ *num_resif = num_ifs;
+ for(p = list; p; p = p->next) {
+ (*num_resif)++;
+ }
*resif = calloc(*num_resif, sizeof(**resif));
if(!*resif) {
log_err("out of memory");
return 0;
}
- for(i=0; i<*num_resif; i++) {
- (*resif)[i] = strdup(cfg->ifs[i]);
- if(!((*resif)[i])) {
- log_err("out of memory");
- config_del_strarray(*resif, *num_resif);
- *resif = NULL;
- *num_resif = 0;
- return 0;
+ if(ifs) {
+ int i;
+ for(i=0; i<num_ifs; i++) {
+ (*resif)[i] = strdup(ifs[i]);
+ if(!((*resif)[i])) {
+ log_err("out of memory");
+ config_del_strarray(*resif, *num_resif);
+ *resif = NULL;
+ *num_resif = 0;
+ return 0;
+ }
+ }
+ }
+ if(list) {
+ int idx = num_ifs;
+ for(p = list; p; p = p->next) {
+ (*resif)[idx] = strdup(p->str);
+ if(!((*resif)[idx])) {
+ log_err("out of memory");
+ config_del_strarray(*resif, *num_resif);
+ *resif = NULL;
+ *num_resif = 0;
+ return 0;
+ }
+ idx++;
}
}
return 1;
}
}
}
+
return list;
}
if(list->fd != -1) {
sock_close(list->fd);
}
+ /* rc_ports don't have ub_socket */
+ if(list->socket) {
+ freeaddrinfo(list->socket->addr);
+ free(list->socket);
+ }
free(list);
list = nx;
}
"buffer already assigned to stream");
return -1;
}
+
+ /* the c->buffer might be used by mesh_send_reply and no be cleard
+ * need to be cleared before use */
+ sldns_buffer_clear(h2_session->c->buffer);
if(sldns_buffer_remaining(h2_session->c->buffer) <
sldns_buffer_remaining(h2_stream->qbuffer)) {
/* qbuffer will be free'd in frame close cb */
return 0;
}
- if(!(b64len = sldns_b64url_pton(
- (char const *)start, length,
- sldns_buffer_current(h2_stream->qbuffer),
- expectb64len)) || b64len < 0) {
- lock_basic_lock(&http2_query_buffer_count_lock);
- http2_query_buffer_count -= expectb64len;
- lock_basic_unlock(&http2_query_buffer_count_lock);
- sldns_buffer_free(h2_stream->qbuffer);
- h2_stream->qbuffer = NULL;
- /* return without error, method can be an
- * unknown POST */
- return 1;
+ if(sldns_b64_contains_nonurl((char const*)start, length)) {
+ char buf[65536+4];
+ verbose(VERB_ALGO, "HTTP2 stream contains wrong b64 encoding");
+ /* copy to the scratch buffer temporarily to terminate the
+ * string with a zero */
+ if(length+1 > sizeof(buf)) {
+ /* too long */
+ lock_basic_lock(&http2_query_buffer_count_lock);
+ http2_query_buffer_count -= expectb64len;
+ lock_basic_unlock(&http2_query_buffer_count_lock);
+ sldns_buffer_free(h2_stream->qbuffer);
+ h2_stream->qbuffer = NULL;
+ return 1;
+ }
+ memmove(buf, start, length);
+ buf[length] = 0;
+ if(!(b64len = sldns_b64_pton(buf, sldns_buffer_current(
+ h2_stream->qbuffer), expectb64len)) || b64len < 0) {
+ lock_basic_lock(&http2_query_buffer_count_lock);
+ http2_query_buffer_count -= expectb64len;
+ lock_basic_unlock(&http2_query_buffer_count_lock);
+ sldns_buffer_free(h2_stream->qbuffer);
+ h2_stream->qbuffer = NULL;
+ return 1;
+ }
+ } else {
+ if(!(b64len = sldns_b64url_pton(
+ (char const *)start, length,
+ sldns_buffer_current(h2_stream->qbuffer),
+ expectb64len)) || b64len < 0) {
+ lock_basic_lock(&http2_query_buffer_count_lock);
+ http2_query_buffer_count -= expectb64len;
+ lock_basic_unlock(&http2_query_buffer_count_lock);
+ sldns_buffer_free(h2_stream->qbuffer);
+ h2_stream->qbuffer = NULL;
+ /* return without error, method can be an
+ * unknown POST */
+ return 1;
+ }
}
sldns_buffer_skip(h2_stream->qbuffer, (size_t)b64len);
return 1;
listen_type_http
};
+/*
+ * socket properties (just like NSD nsd_socket structure definition)
+ */
+struct unbound_socket {
+ /** socket-address structure */
+ struct addrinfo * addr;
+ /** socket descriptor returned by socket() syscall */
+ int s;
+ /** address family (AF_INET/IF_INET6) */
+ int fam;
+};
+
/**
* Single linked list to store shared ports that have been
* opened for use by all threads.
int fd;
/** type of file descriptor, udp or tcp */
enum listen_type ftype;
+ /** fill in unbpound_socket structure for every opened socket at Unbound startup */
+ struct unbound_socket* socket;
};
/**
*/
void listening_ports_free(struct listen_port* list);
+struct config_strlist;
/**
* Resolve interface names in config and store result IP addresses
- * @param cfg: config
+ * @param ifs: array of interfaces. The list of interface names, if not NULL.
+ * @param num_ifs: length of ifs array.
+ * @param list: if not NULL, this is used as the list of interface names.
* @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);
+int resolve_interface_names(char** ifs, int num_ifs,
+ struct config_strlist* list, char*** resif, int* num_resif);
/**
* Create commpoints with for this thread for the shared ports.
char* set_ip_dscp(int socket, int addrfamily, int ds);
+/** for debug and profiling purposes only
+ * @param ub_sock: the structure containing created socket info we want to print or log for
+ */
+void verbose_print_unbound_socket(struct unbound_socket* ub_sock);
+
#endif /* LISTEN_DNSPORT_H */
lz_enter_zones(struct local_zones* zones, struct config_file* cfg)
{
struct config_str2list* p;
+#ifndef THREADS_DISABLED
struct local_zone* z;
+#endif
for(p = cfg->local_zones; p; p = p->next) {
- if(!(z=lz_enter_zone(zones, p->str, p->str2,
+ if(!(
+#ifndef THREADS_DISABLED
+ z=
+#endif
+ lz_enter_zone(zones, p->str, p->str2,
LDNS_RR_CLASS_IN)))
return 0;
lock_rw_unlock(&z->lock);
}
if(have_name) {
uint8_t* n2;
+#ifndef THREADS_DISABLED
struct local_zone* z;
+#endif
/* allocate zone of smallest shared topdomain to contain em */
n2 = nm;
dname_remove_labels(&n2, &nmlen, nmlabs - match);
}
log_nametypeclass(VERB_ALGO, "implicit transparent local-zone",
n2, 0, dclass);
- if(!(z=lz_enter_zone_dname(zones, n2, nmlen, match,
+ if(!(
+#ifndef THREADS_DISABLED
+ z=
+#endif
+ lz_enter_zone_dname(zones, n2, nmlen, match,
local_zone_transparent, dclass))) {
return 0;
}
rbtree_type data;
/** if data contains zone apex SOA data, this is a ptr to it. */
struct ub_packed_rrset_key* soa;
- /** if data contains zone apex SOA data, this is a prt to an
+ /** if data contains zone apex SOA data, this is a ptr to an
* artificial negative SOA rrset (TTL is the minimum of the TTL and the
* SOA.MINIMUM). */
struct ub_packed_rrset_key* soa_negative;
{
#ifndef S_SPLINT_S
size_t leftover;
- if(d == 0) {
+ if(d <= 0) {
avg->tv_sec = 0;
avg->tv_usec = 0;
return;
avg->tv_usec = sum->tv_usec / d;
/* handle fraction from seconds divide */
leftover = sum->tv_sec - avg->tv_sec*d;
- avg->tv_usec += (leftover*1000000)/d;
+ if(leftover <= 0)
+ leftover = 0;
+ avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
+ if(avg->tv_sec < 0)
+ avg->tv_sec = 0;
+ if(avg->tv_usec < 0)
+ avg->tv_usec = 0;
#endif
}
mstate->s.serve_expired_data->get_cached_answer =
mstate->s.serve_expired_data->get_cached_answer?
mstate->s.serve_expired_data->get_cached_answer:
- mesh_serve_expired_lookup;
+ &mesh_serve_expired_lookup;
/* In case this timer already popped, start it again */
if(!mstate->s.serve_expired_data->timer) {
{
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* dep_m = NULL;
- if(!mesh_state_is_unique(qstate->mesh_info))
- dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
+ dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
return mesh_detect_cycle_found(qstate, dep_m);
}
while(1) {
fptr_ok(fptr_whitelist_serve_expired_lookup(
qstate->serve_expired_data->get_cached_answer));
- msg = qstate->serve_expired_data->get_cached_answer(qstate,
+ msg = (*qstate->serve_expired_data->get_cached_answer)(qstate,
lookup_qinfo);
if(!msg)
return;
return num;
}
-void
+void
modstack_init(struct module_stack* stack)
{
stack->num = 0;
stack->mod = NULL;
}
-int
+int
modstack_config(struct module_stack* stack, const char* module_conf)
{
- int i;
- verbose(VERB_QUERY, "module config: \"%s\"", module_conf);
- stack->num = count_modules(module_conf);
- if(stack->num == 0) {
- log_err("error: no modules specified");
- return 0;
- }
- if(stack->num > MAX_MODULE) {
- log_err("error: too many modules (%d max %d)",
- stack->num, MAX_MODULE);
- return 0;
- }
- stack->mod = (struct module_func_block**)calloc((size_t)
- stack->num, sizeof(struct module_func_block*));
- if(!stack->mod) {
- log_err("out of memory");
- return 0;
- }
- for(i=0; i<stack->num; i++) {
- stack->mod[i] = module_factory(&module_conf);
- if(!stack->mod[i]) {
+ int i;
+ verbose(VERB_QUERY, "module config: \"%s\"", module_conf);
+ stack->num = count_modules(module_conf);
+ if(stack->num == 0) {
+ log_err("error: no modules specified");
+ return 0;
+ }
+ if(stack->num > MAX_MODULE) {
+ log_err("error: too many modules (%d max %d)",
+ stack->num, MAX_MODULE);
+ return 0;
+ }
+ stack->mod = (struct module_func_block**)calloc((size_t)
+ stack->num, sizeof(struct module_func_block*));
+ if(!stack->mod) {
+ log_err("out of memory");
+ return 0;
+ }
+ for(i=0; i<stack->num; i++) {
+ stack->mod[i] = module_factory(&module_conf);
+ if(!stack->mod[i]) {
char md[256];
snprintf(md, sizeof(md), "%s", module_conf);
if(strchr(md, ' ')) *(strchr(md, ' ')) = 0;
if(strchr(md, '\t')) *(strchr(md, '\t')) = 0;
- log_err("Unknown value in module-config, module: '%s'."
+ log_err("Unknown value in module-config, module: '%s'."
" This module is not present (not compiled in),"
- " See the list of linked modules with unbound -h",
- md);
- return 0;
- }
- }
- return 1;
+ " See the list of linked modules with unbound -V", md);
+ return 0;
+ }
+ }
+ return 1;
}
/** The list of module names */
const char**
module_list_avail(void)
{
- /* these are the modules available */
- static const char* names[] = {
+ /* these are the modules available */
+ static const char* names[] = {
"dns64",
#ifdef WITH_PYTHONMODULE
"python",
"subnetcache",
#endif
#ifdef USE_IPSET
- "ipset",
+ "ipset",
#endif
"respip",
"validator",
static void waiting_list_remove(struct outside_network* outnet,
struct waiting_tcp* w);
-/** remove reused element from tree and lru list */
-static void reuse_tcp_remove_tree_list(struct outside_network* outnet,
+/** select a DNS ID for a TCP stream */
+static uint16_t tcp_select_id(struct outside_network* outnet,
struct reuse_tcp* reuse);
int
* Pick random outgoing-interface of that family, and bind it.
* port set to 0 so OS picks a port number for us.
* if it is the ANY address, do not bind.
+ * @param pend: pending tcp structure, for storing the local address choice.
* @param w: tcp structure with destination address.
* @param s: socket fd.
* @return false on error, socket closed.
*/
static int
-pick_outgoing_tcp(struct waiting_tcp* w, int s)
+pick_outgoing_tcp(struct pending_tcp* pend, struct waiting_tcp* w, int s)
{
struct port_if* pi = NULL;
int num;
+ pend->pi = NULL;
#ifdef INET6
if(addr_is_ip6(&w->addr, w->addrlen))
num = w->outnet->num_ip6;
#endif
pi = &w->outnet->ip4_ifs[ub_random_max(w->outnet->rnd, num)];
log_assert(pi);
+ pend->pi = pi;
if(addr_is_any(&pi->addr, pi->addrlen)) {
/* binding to the ANY interface is for listening sockets */
return 1;
((struct sockaddr_in6*)&pi->addr)->sin6_port = 0;
else ((struct sockaddr_in*)&pi->addr)->sin_port = 0;
if(bind(s, (struct sockaddr*)&pi->addr, pi->addrlen) != 0) {
- log_err("outgoing tcp: bind: %s", sock_strerror(errno));
+#ifndef USE_WINSOCK
+#ifdef EADDRNOTAVAIL
+ if(!(verbosity < 4 && errno == EADDRNOTAVAIL))
+#endif
+#else /* USE_WINSOCK */
+ if(!(verbosity < 4 && WSAGetLastError() == WSAEADDRNOTAVAIL))
+#endif
+ log_err("outgoing tcp: bind: %s", sock_strerror(errno));
sock_close(s);
return 0;
}
uint16_t port;
char addrbuf[128];
if(verbosity < v) return;
+ if(!reuse || !reuse->pending || !reuse->pending->c)
+ return;
addr_to_str(&reuse->addr, reuse->addrlen, addrbuf, sizeof(addrbuf));
port = ntohs(((struct sockaddr_in*)&reuse->addr)->sin_port);
verbose(v, "%s %s#%u fd %d", msg, addrbuf, (unsigned)port,
w->write_wait_next->write_wait_prev = NULL;
else reuse->write_wait_last = NULL;
w->write_wait_queued = 0;
+ w->write_wait_next = NULL;
+ w->write_wait_prev = NULL;
return w;
}
static void reuse_write_wait_remove(struct reuse_tcp* reuse,
struct waiting_tcp* w)
{
+ log_assert(w);
+ log_assert(w->write_wait_queued);
if(!w)
return;
if(!w->write_wait_queued)
if(w->write_wait_prev)
w->write_wait_prev->write_wait_next = w->write_wait_next;
else reuse->write_wait_first = w->write_wait_next;
+ log_assert(!w->write_wait_prev ||
+ w->write_wait_prev->write_wait_next != w->write_wait_prev);
if(w->write_wait_next)
w->write_wait_next->write_wait_prev = w->write_wait_prev;
else reuse->write_wait_last = w->write_wait_prev;
+ log_assert(!w->write_wait_next
+ || w->write_wait_next->write_wait_prev != w->write_wait_next);
w->write_wait_queued = 0;
+ w->write_wait_next = NULL;
+ w->write_wait_prev = NULL;
}
/** push the element after the last on the writewait list */
log_assert(!w->write_wait_queued);
if(reuse->write_wait_last) {
reuse->write_wait_last->write_wait_next = w;
+ log_assert(reuse->write_wait_last->write_wait_next !=
+ reuse->write_wait_last);
w->write_wait_prev = reuse->write_wait_last;
} else {
reuse->write_wait_first = w;
void
reuse_tree_by_id_insert(struct reuse_tcp* reuse, struct waiting_tcp* w)
{
+#ifdef UNBOUND_DEBUG
+ rbnode_type* added;
+#endif
log_assert(w->id_node.key == NULL);
w->id_node.key = w;
+#ifdef UNBOUND_DEBUG
+ added =
+#else
+ (void)
+#endif
rbtree_insert(&reuse->tree_by_id, &w->id_node);
+ log_assert(added); /* should have been added */
}
/** find element in tree by id */
}
/** insert into reuse tcp tree and LRU, false on failure (duplicate) */
-static int
+int
reuse_tcp_insert(struct outside_network* outnet, struct pending_tcp* pend_tcp)
{
log_reuse_tcp(VERB_CLIENT, "reuse_tcp_insert", &pend_tcp->reuse);
if(pend_tcp->reuse.item_on_lru_list) {
if(!pend_tcp->reuse.node.key)
- log_err("internal error: reuse_tcp_insert: on lru list without key");
+ log_err("internal error: reuse_tcp_insert: "
+ "in lru list without key");
return 1;
}
pend_tcp->reuse.node.key = &pend_tcp->reuse;
pend_tcp->reuse.pending = pend_tcp;
if(!rbtree_insert(&outnet->tcp_reuse, &pend_tcp->reuse.node)) {
- /* this is a duplicate connection, close this one */
- verbose(VERB_CLIENT, "reuse_tcp_insert: duplicate connection");
- pend_tcp->reuse.node.key = NULL;
- return 0;
+ /* We are not in the LRU list but we are already in the
+ * tcp_reuse tree, strange.
+ * Continue to add ourselves to the LRU list. */
+ log_err("internal error: reuse_tcp_insert: in lru list but "
+ "not in the tree");
}
/* insert into LRU, first is newest */
pend_tcp->reuse.lru_prev = NULL;
if(outnet->tcp_reuse_first) {
pend_tcp->reuse.lru_next = outnet->tcp_reuse_first;
+ log_assert(pend_tcp->reuse.lru_next != &pend_tcp->reuse);
outnet->tcp_reuse_first->lru_prev = &pend_tcp->reuse;
+ log_assert(outnet->tcp_reuse_first->lru_prev !=
+ outnet->tcp_reuse_first);
} else {
pend_tcp->reuse.lru_next = NULL;
outnet->tcp_reuse_last = &pend_tcp->reuse;
}
outnet->tcp_reuse_first = &pend_tcp->reuse;
pend_tcp->reuse.item_on_lru_list = 1;
+ log_assert((!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+ (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
+ log_assert(outnet->tcp_reuse_first != outnet->tcp_reuse_first->lru_next &&
+ outnet->tcp_reuse_first != outnet->tcp_reuse_first->lru_prev);
+ log_assert(outnet->tcp_reuse_last != outnet->tcp_reuse_last->lru_next &&
+ outnet->tcp_reuse_last != outnet->tcp_reuse_last->lru_prev);
return 1;
}
while(result && result != RBTREE_NULL &&
reuse_cmp_addrportssl(result->key, &key_p.reuse) == 0) {
if(((struct reuse_tcp*)result)->tree_by_id.count <
- MAX_REUSE_TCP_QUERIES) {
+ outnet->max_reuse_tcp_queries) {
/* same address, port, ssl-yes-or-no, and has
* space for another query */
return (struct reuse_tcp*)result;
if(s == -1)
return 0;
- if(!pick_outgoing_tcp(w, s))
+ if(!pick_outgoing_tcp(pend, w, s))
return 0;
fd_set_nonblock(s);
/** Touch the lru of a reuse_tcp element, it is in use.
* This moves it to the front of the list, where it is not likely to
* be closed. Items at the back of the list are closed to make space. */
-static void
+void
reuse_tcp_lru_touch(struct outside_network* outnet, struct reuse_tcp* reuse)
{
if(!reuse->item_on_lru_list) {
log_err("internal error: we need to touch the lru_list but item not in list");
return; /* not on the list, no lru to modify */
}
+ log_assert(reuse->lru_prev ||
+ (!reuse->lru_prev && outnet->tcp_reuse_first == reuse));
if(!reuse->lru_prev)
return; /* already first in the list */
/* remove at current position */
/* since it is not first, there is a previous element */
reuse->lru_prev->lru_next = reuse->lru_next;
+ log_assert(reuse->lru_prev->lru_next != reuse->lru_prev);
if(reuse->lru_next)
reuse->lru_next->lru_prev = reuse->lru_prev;
else outnet->tcp_reuse_last = reuse->lru_prev;
+ log_assert(!reuse->lru_next || reuse->lru_next->lru_prev != reuse->lru_next);
+ log_assert(outnet->tcp_reuse_last != outnet->tcp_reuse_last->lru_next &&
+ outnet->tcp_reuse_last != outnet->tcp_reuse_last->lru_prev);
/* insert at the front */
reuse->lru_prev = NULL;
reuse->lru_next = outnet->tcp_reuse_first;
+ if(outnet->tcp_reuse_first) {
+ outnet->tcp_reuse_first->lru_prev = reuse;
+ }
+ log_assert(reuse->lru_next != reuse);
/* since it is not first, it is not the only element and
* lru_next is thus not NULL and thus reuse is now not the last in
* the list, so outnet->tcp_reuse_last does not need to be modified */
outnet->tcp_reuse_first = reuse;
+ log_assert(outnet->tcp_reuse_first != outnet->tcp_reuse_first->lru_next &&
+ outnet->tcp_reuse_first != outnet->tcp_reuse_first->lru_prev);
+ log_assert((!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+ (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
+}
+
+/** Snip the last reuse_tcp element off of the LRU list */
+struct reuse_tcp*
+reuse_tcp_lru_snip(struct outside_network* outnet)
+{
+ struct reuse_tcp* reuse = outnet->tcp_reuse_last;
+ if(!reuse) return NULL;
+ /* snip off of LRU */
+ log_assert(reuse->lru_next == NULL);
+ if(reuse->lru_prev) {
+ outnet->tcp_reuse_last = reuse->lru_prev;
+ reuse->lru_prev->lru_next = NULL;
+ } else {
+ outnet->tcp_reuse_last = NULL;
+ outnet->tcp_reuse_first = NULL;
+ }
+ log_assert((!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+ (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
+ reuse->item_on_lru_list = 0;
+ reuse->lru_next = NULL;
+ reuse->lru_prev = NULL;
+ return reuse;
}
/** call callback on waiting_tcp, if not NULL */
waiting_tcp_callback(struct waiting_tcp* w, struct comm_point* c, int error,
struct comm_reply* reply_info)
{
- if(w->cb) {
+ if(w && w->cb) {
fptr_ok(fptr_whitelist_pending_tcp(w->cb));
(void)(*w->cb)(c, w->cb_arg, error, reply_info);
}
}
+/** add waiting_tcp element to the outnet tcp waiting list */
+static void
+outnet_add_tcp_waiting(struct outside_network* outnet, struct waiting_tcp* w)
+{
+ struct timeval tv;
+ log_assert(!w->on_tcp_waiting_list);
+ if(w->on_tcp_waiting_list)
+ return;
+ w->next_waiting = NULL;
+ if(outnet->tcp_wait_last)
+ outnet->tcp_wait_last->next_waiting = w;
+ else outnet->tcp_wait_first = w;
+ outnet->tcp_wait_last = w;
+ w->on_tcp_waiting_list = 1;
+#ifndef S_SPLINT_S
+ tv.tv_sec = w->timeout/1000;
+ tv.tv_usec = (w->timeout%1000)*1000;
+#endif
+ comm_timer_set(w->timer, &tv);
+}
+
+/** add waiting_tcp element as first to the outnet tcp waiting list */
+static void
+outnet_add_tcp_waiting_first(struct outside_network* outnet,
+ struct waiting_tcp* w, int reset_timer)
+{
+ struct timeval tv;
+ log_assert(!w->on_tcp_waiting_list);
+ if(w->on_tcp_waiting_list)
+ return;
+ w->next_waiting = outnet->tcp_wait_first;
+ if(!outnet->tcp_wait_last)
+ outnet->tcp_wait_last = w;
+ outnet->tcp_wait_first = w;
+ w->on_tcp_waiting_list = 1;
+ if(reset_timer) {
+#ifndef S_SPLINT_S
+ tv.tv_sec = w->timeout/1000;
+ tv.tv_usec = (w->timeout%1000)*1000;
+#endif
+ comm_timer_set(w->timer, &tv);
+ }
+ log_assert(
+ (!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+ (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
+}
+
/** see if buffers can be used to service TCP queries */
static void
use_free_buffer(struct outside_network* outnet)
{
struct waiting_tcp* w;
- while(outnet->tcp_free && outnet->tcp_wait_first
- && !outnet->want_to_quit) {
+ while(outnet->tcp_wait_first && !outnet->want_to_quit) {
+#ifdef USE_DNSTAP
+ struct pending_tcp* pend_tcp = NULL;
+#endif
struct reuse_tcp* reuse = NULL;
w = outnet->tcp_wait_first;
+ log_assert(w->on_tcp_waiting_list);
outnet->tcp_wait_first = w->next_waiting;
if(outnet->tcp_wait_last == w)
outnet->tcp_wait_last = NULL;
+ log_assert(
+ (!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+ (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
w->on_tcp_waiting_list = 0;
reuse = reuse_tcp_find(outnet, &w->addr, w->addrlen,
w->ssl_upstream);
+ /* re-select an ID when moving to a new TCP buffer */
+ w->id = tcp_select_id(outnet, reuse);
+ LDNS_ID_SET(w->pkt, w->id);
if(reuse) {
log_reuse_tcp(VERB_CLIENT, "use free buffer for waiting tcp: "
"found reuse", reuse);
+#ifdef USE_DNSTAP
+ pend_tcp = reuse->pending;
+#endif
reuse_tcp_lru_touch(outnet, reuse);
comm_timer_disable(w->timer);
w->next_waiting = (void*)reuse->pending;
reuse->pending->c->fd, reuse->pending,
w);
}
- } else {
+ } else if(outnet->tcp_free) {
struct pending_tcp* pend = w->outnet->tcp_free;
rbtree_init(&pend->reuse.tree_by_id, reuse_id_cmp);
pend->reuse.pending = pend;
waiting_tcp_callback(w, NULL, NETEVENT_CLOSED,
NULL);
waiting_tcp_delete(w);
+#ifdef USE_DNSTAP
+ w = NULL;
+#endif
}
+#ifdef USE_DNSTAP
+ pend_tcp = pend;
+#endif
+ } else {
+ /* no reuse and no free buffer, put back at the start */
+ outnet_add_tcp_waiting_first(outnet, w, 0);
+ break;
+ }
+#ifdef USE_DNSTAP
+ if(outnet->dtenv && pend_tcp && w && w->sq &&
+ (outnet->dtenv->log_resolver_query_messages ||
+ outnet->dtenv->log_forwarder_query_messages)) {
+ sldns_buffer tmp;
+ sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len);
+ dt_msg_send_outside_query(outnet->dtenv, &w->sq->addr,
+ &pend_tcp->pi->addr, comm_tcp, w->sq->zone,
+ w->sq->zonelen, &tmp);
}
- }
-}
-
-/** add waiting_tcp element to the outnet tcp waiting list */
-static void
-outnet_add_tcp_waiting(struct outside_network* outnet, struct waiting_tcp* w)
-{
- struct timeval tv;
- if(w->on_tcp_waiting_list)
- return;
- w->next_waiting = NULL;
- if(outnet->tcp_wait_last)
- outnet->tcp_wait_last->next_waiting = w;
- else outnet->tcp_wait_first = w;
- outnet->tcp_wait_last = w;
- w->on_tcp_waiting_list = 1;
-#ifndef S_SPLINT_S
- tv.tv_sec = w->timeout/1000;
- tv.tv_usec = (w->timeout%1000)*1000;
#endif
- comm_timer_set(w->timer, &tv);
+ }
}
/** delete element from tree by id */
static void
reuse_tree_by_id_delete(struct reuse_tcp* reuse, struct waiting_tcp* w)
{
+#ifdef UNBOUND_DEBUG
+ rbnode_type* rem;
+#endif
log_assert(w->id_node.key != NULL);
+#ifdef UNBOUND_DEBUG
+ rem =
+#else
+ (void)
+#endif
rbtree_delete(&reuse->tree_by_id, w);
+ log_assert(rem); /* should have been there */
w->id_node.key = NULL;
}
}
/** remove reused element from tree and lru list */
-static void
+void
reuse_tcp_remove_tree_list(struct outside_network* outnet,
struct reuse_tcp* reuse)
{
verbose(VERB_CLIENT, "reuse_tcp_remove_tree_list");
if(reuse->node.key) {
/* delete it from reuse tree */
- (void)rbtree_delete(&outnet->tcp_reuse, reuse);
+ if(!rbtree_delete(&outnet->tcp_reuse, reuse)) {
+ /* should not be possible, it should be there */
+ char buf[256];
+ addr_to_str(&reuse->addr, reuse->addrlen, buf,
+ sizeof(buf));
+ log_err("reuse tcp delete: node not present, internal error, %s ssl %d lru %d", buf, reuse->is_ssl, reuse->item_on_lru_list);
+ }
reuse->node.key = NULL;
+ /* defend against loops on broken tree by zeroing the
+ * rbnode structure */
+ memset(&reuse->node, 0, sizeof(reuse->node));
}
/* delete from reuse list */
if(reuse->item_on_lru_list) {
* and thus have a pending pointer to the struct */
log_assert(reuse->lru_prev->pending);
reuse->lru_prev->lru_next = reuse->lru_next;
+ log_assert(reuse->lru_prev->lru_next != reuse->lru_prev);
} else {
log_assert(!reuse->lru_next || reuse->lru_next->pending);
outnet->tcp_reuse_first = reuse->lru_next;
+ log_assert(!outnet->tcp_reuse_first ||
+ (outnet->tcp_reuse_first !=
+ outnet->tcp_reuse_first->lru_next &&
+ outnet->tcp_reuse_first !=
+ outnet->tcp_reuse_first->lru_prev));
}
if(reuse->lru_next) {
/* assert that members of the lru list are waiting
* and thus have a pending pointer to the struct */
log_assert(reuse->lru_next->pending);
reuse->lru_next->lru_prev = reuse->lru_prev;
+ log_assert(reuse->lru_next->lru_prev != reuse->lru_next);
} else {
log_assert(!reuse->lru_prev || reuse->lru_prev->pending);
outnet->tcp_reuse_last = reuse->lru_prev;
- }
+ log_assert(!outnet->tcp_reuse_last ||
+ (outnet->tcp_reuse_last !=
+ outnet->tcp_reuse_last->lru_next &&
+ outnet->tcp_reuse_last !=
+ outnet->tcp_reuse_last->lru_prev));
+ }
+ log_assert((!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+ (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
reuse->item_on_lru_list = 0;
+ reuse->lru_next = NULL;
+ reuse->lru_prev = NULL;
}
+ reuse->pending = NULL;
}
/** helper function that deletes an element from the tree of readwait
struct pending_tcp* pend)
{
verbose(VERB_CLIENT, "decommission_pending_tcp");
- pend->next_free = outnet->tcp_free;
- outnet->tcp_free = pend;
+ /* A certain code path can lead here twice for the same pending_tcp
+ * creating a loop in the free pending_tcp list. */
+ if(outnet->tcp_free != pend) {
+ pend->next_free = outnet->tcp_free;
+ outnet->tcp_free = pend;
+ }
if(pend->reuse.node.key) {
/* needs unlink from the reuse tree to get deleted */
reuse_tcp_remove_tree_list(outnet, &pend->reuse);
/** set timeout on tcp fd and setup read event to catch incoming dns msgs */
static void
-reuse_tcp_setup_timeout(struct pending_tcp* pend_tcp)
+reuse_tcp_setup_timeout(struct pending_tcp* pend_tcp, int tcp_reuse_timeout)
{
log_reuse_tcp(VERB_CLIENT, "reuse_tcp_setup_timeout", &pend_tcp->reuse);
- comm_point_start_listening(pend_tcp->c, -1, REUSE_TIMEOUT);
+ comm_point_start_listening(pend_tcp->c, -1, tcp_reuse_timeout);
}
/** set timeout on tcp fd and setup read event to catch incoming dns msgs */
static void
-reuse_tcp_setup_read_and_timeout(struct pending_tcp* pend_tcp)
+reuse_tcp_setup_read_and_timeout(struct pending_tcp* pend_tcp, int tcp_reuse_timeout)
{
log_reuse_tcp(VERB_CLIENT, "reuse_tcp_setup_readtimeout", &pend_tcp->reuse);
sldns_buffer_clear(pend_tcp->c->buffer);
pend_tcp->c->tcp_is_reading = 1;
pend_tcp->c->tcp_byte_count = 0;
comm_point_stop_listening(pend_tcp->c);
- comm_point_start_listening(pend_tcp->c, -1, REUSE_TIMEOUT);
+ comm_point_start_listening(pend_tcp->c, -1, tcp_reuse_timeout);
}
int
struct pending_tcp* pend = (struct pending_tcp*)arg;
struct outside_network* outnet = pend->reuse.outnet;
struct waiting_tcp* w = NULL;
+ log_assert(pend->reuse.item_on_lru_list && pend->reuse.node.key);
verbose(VERB_ALGO, "outnettcp cb");
if(error == NETEVENT_TIMEOUT) {
if(pend->c->tcp_write_and_read) {
pend->reuse.cp_more_write_again = 0;
pend->c->tcp_is_reading = 1;
comm_point_stop_listening(pend->c);
- reuse_tcp_setup_timeout(pend);
+ reuse_tcp_setup_timeout(pend, outnet->tcp_reuse_timeout);
}
return 0;
} else if(error != NETEVENT_NOERROR) {
* and there could be more bytes to read on the input */
if(pend->reuse.tree_by_id.count != 0)
pend->reuse.cp_more_read_again = 1;
- reuse_tcp_setup_read_and_timeout(pend);
+ reuse_tcp_setup_read_and_timeout(pend, outnet->tcp_reuse_timeout);
return 0;
}
verbose(VERB_CLIENT, "outnet_tcp_cb reuse after cb: decommission it");
int numavailports, size_t unwanted_threshold, int tcp_mss,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv,
- int udp_connect)
+ int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
+ int tcp_auth_query_timeout)
{
struct outside_network* outnet = (struct outside_network*)
calloc(1, sizeof(struct outside_network));
comm_base_timept(base, &outnet->now_secs, &outnet->now_tv);
outnet->base = base;
outnet->num_tcp = num_tcp;
+ outnet->max_reuse_tcp_queries = max_reuse_tcp_queries;
+ outnet->tcp_reuse_timeout= tcp_reuse_timeout;
+ outnet->tcp_auth_query_timeout = tcp_auth_query_timeout;
outnet->num_tcp_outgoing = 0;
outnet->infra = infra;
outnet->rnd = rnd;
return NULL;
}
pc->cp = comm_point_create_udp(outnet->base, -1,
- outnet->udp_buff, outnet_udp_cb, outnet);
+ outnet->udp_buff, outnet_udp_cb, outnet, NULL);
if(!pc->cp) {
log_err("malloc failed");
free(pc);
size_t i;
for(i=0; i<outnet->num_tcp; i++)
if(outnet->tcp_conns[i]) {
- if(outnet->tcp_conns[i]->query &&
- !outnet->tcp_conns[i]->query->
- on_tcp_waiting_list) {
+ struct pending_tcp* pend;
+ pend = outnet->tcp_conns[i];
+ if(pend->reuse.item_on_lru_list) {
/* delete waiting_tcp elements that
* the tcp conn is working on */
- struct pending_tcp* pend =
- (struct pending_tcp*)outnet->
- tcp_conns[i]->query->
- next_waiting;
decommission_pending_tcp(outnet, pend);
}
comm_point_delete(outnet->tcp_conns[i]->c);
- waiting_tcp_delete(outnet->tcp_conns[i]->query);
free(outnet->tcp_conns[i]);
+ outnet->tcp_conns[i] = NULL;
}
free(outnet->tcp_conns);
+ outnet->tcp_conns = NULL;
}
if(outnet->tcp_wait_first) {
struct waiting_tcp* p = outnet->tcp_wait_first, *np;
sldns_buffer* packet)
{
int id_tries = 0;
- pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
+ pend->id = GET_RANDOM_ID(outnet->rnd);
LDNS_ID_SET(sldns_buffer_begin(packet), pend->id);
/* insert in tree */
pend->node.key = pend;
while(!rbtree_insert(outnet->pending, &pend->node)) {
/* change ID to avoid collision */
- pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
+ pend->id = GET_RANDOM_ID(outnet->rnd);
LDNS_ID_SET(sldns_buffer_begin(packet), pend->id);
id_tries++;
if(id_tries == MAX_ID_RETRY) {
# ifdef ENETDOWN
case ENETDOWN:
# endif
+ case EPERM:
if(verbosity >= VERB_ALGO)
return 1;
return 0;
comm_timer_set(pend->timer, &tv);
#ifdef USE_DNSTAP
+ /*
+ * sending src (local service)/dst (upstream) addresses over DNSTAP
+ * There are no chances to get the src (local service) addr if unbound
+ * is not configured with specific outgoing IP-addresses. So we will
+ * pass 0.0.0.0 (::) to argument for
+ * dt_msg_send_outside_query()/dt_msg_send_outside_response() calls.
+ */
if(outnet->dtenv &&
(outnet->dtenv->log_resolver_query_messages ||
- outnet->dtenv->log_forwarder_query_messages))
- dt_msg_send_outside_query(outnet->dtenv, &pend->addr, comm_udp,
- pend->sq->zone, pend->sq->zonelen, packet);
+ outnet->dtenv->log_forwarder_query_messages)) {
+ log_addr(VERB_ALGO, "from local addr", &pend->pc->pif->addr, pend->pc->pif->addrlen);
+ log_addr(VERB_ALGO, "request to upstream", &pend->addr, pend->addrlen);
+ dt_msg_send_outside_query(outnet->dtenv, &pend->addr, &pend->pc->pif->addr, comm_udp,
+ pend->sq->zone, pend->sq->zonelen, packet);
+ }
#endif
return 1;
}
static void
reuse_tcp_close_oldest(struct outside_network* outnet)
{
- struct pending_tcp* pend;
+ struct reuse_tcp* reuse;
verbose(VERB_CLIENT, "reuse_tcp_close_oldest");
- if(!outnet->tcp_reuse_last) return;
- pend = outnet->tcp_reuse_last->pending;
-
- /* snip off of LRU */
- log_assert(pend->reuse.lru_next == NULL);
- if(pend->reuse.lru_prev) {
- outnet->tcp_reuse_last = pend->reuse.lru_prev;
- pend->reuse.lru_prev->lru_next = NULL;
- } else {
- outnet->tcp_reuse_last = NULL;
- outnet->tcp_reuse_first = NULL;
- }
- pend->reuse.item_on_lru_list = 0;
-
+ reuse = reuse_tcp_lru_snip(outnet);
+ if(!reuse) return;
/* free up */
- reuse_cb_and_decommission(outnet, pend, NETEVENT_CLOSED);
+ reuse_cb_and_decommission(outnet, reuse->pending, NETEVENT_CLOSED);
+}
+
+static uint16_t
+tcp_select_id(struct outside_network* outnet, struct reuse_tcp* reuse)
+{
+ if(reuse)
+ return reuse_tcp_select_id(reuse, outnet);
+ return GET_RANDOM_ID(outnet->rnd);
}
/** find spare ID value for reuse tcp stream. That is random and also does
/* make really sure the tree is not empty */
if(reuse->tree_by_id.count == 0) {
- id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
+ id = GET_RANDOM_ID(outnet->rnd);
return id;
}
/* try to find random empty spots by picking them */
for(i = 0; i<try_random; i++) {
- id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
+ id = GET_RANDOM_ID(outnet->rnd);
if(!reuse_tcp_by_id_find(reuse, id)) {
return id;
}
reuse_tcp_lru_touch(sq->outnet, reuse);
}
+ log_assert(!reuse || (reuse && pend));
/* if !pend but we have reuse streams, close a reuse stream
* to be able to open a new one to this target, no use waiting
* to reuse a file descriptor while another query needs to use
if(!pend) {
reuse_tcp_close_oldest(sq->outnet);
pend = sq->outnet->tcp_free;
+ log_assert(!reuse || (pend == reuse->pending));
}
/* allocate space to store query */
w->pkt = (uint8_t*)w + sizeof(struct waiting_tcp);
w->pkt_len = sldns_buffer_limit(packet);
memmove(w->pkt, sldns_buffer_begin(packet), w->pkt_len);
- if(reuse)
- w->id = reuse_tcp_select_id(reuse, sq->outnet);
- else w->id = ((unsigned)ub_random(sq->outnet->rnd)>>8) & 0xffff;
+ w->id = tcp_select_id(sq->outnet, reuse);
LDNS_ID_SET(w->pkt, w->id);
memcpy(&w->addr, &sq->addr, sq->addrlen);
w->addrlen = sq->addrlen;
w->write_wait_next = NULL;
w->write_wait_queued = 0;
w->error_count = 0;
+#ifdef USE_DNSTAP
+ w->sq = NULL;
+#endif
if(pend) {
/* we have a buffer available right now */
if(reuse) {
+ log_assert(reuse == &pend->reuse);
/* reuse existing fd, write query and continue */
/* store query in tree by id */
verbose(VERB_CLIENT, "pending_tcp_query: reuse, store");
return NULL;
}
}
+#ifdef USE_DNSTAP
+ if(sq->outnet->dtenv &&
+ (sq->outnet->dtenv->log_resolver_query_messages ||
+ sq->outnet->dtenv->log_forwarder_query_messages)) {
+ /* use w->pkt, because it has the ID value */
+ sldns_buffer tmp;
+ sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len);
+ dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr,
+ &pend->pi->addr, comm_tcp, sq->zone,
+ sq->zonelen, &tmp);
+ }
+#endif
} else {
/* queue up */
/* waiting for a buffer on the outside network buffer wait
* list */
verbose(VERB_CLIENT, "pending_tcp_query: queue to wait");
- outnet_add_tcp_waiting(sq->outnet, w);
- }
#ifdef USE_DNSTAP
- if(sq->outnet->dtenv &&
- (sq->outnet->dtenv->log_resolver_query_messages ||
- sq->outnet->dtenv->log_forwarder_query_messages))
- dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr,
- comm_tcp, sq->zone, sq->zonelen, packet);
+ w->sq = sq;
#endif
+ outnet_add_tcp_waiting(sq->outnet, w);
+ }
return w;
}
prev = p;
p = p->next_waiting;
}
+ /* waiting_list_remove is currently called only with items that are
+ * already in the waiting list. */
+ log_assert(0);
}
/** reuse tcp stream, remove serviced query from stream,
if(!reuse_tcp_insert(sq->outnet, pend_tcp)) {
return 0;
}
- reuse_tcp_setup_timeout(pend_tcp);
+ reuse_tcp_setup_timeout(pend_tcp, sq->outnet->tcp_reuse_timeout);
return 1;
}
return 0;
{
struct serviced_query* sq = (struct serviced_query*)arg;
struct comm_reply r2;
+#ifdef USE_DNSTAP
+ struct waiting_tcp* w = (struct waiting_tcp*)sq->pending;
+ struct pending_tcp* pend_tcp = NULL;
+ struct port_if* pi = NULL;
+ if(!w->on_tcp_waiting_list && w->next_waiting) {
+ pend_tcp = (struct pending_tcp*)w->next_waiting;
+ pi = pend_tcp->pi;
+ }
+#endif
sq->pending = NULL; /* removed after this callback */
if(error != NETEVENT_NOERROR)
log_addr(VERB_QUERY, "tcp error for address",
infra_update_tcp_works(sq->outnet->infra, &sq->addr,
sq->addrlen, sq->zone, sq->zonelen);
#ifdef USE_DNSTAP
- if(error==NETEVENT_NOERROR && sq->outnet->dtenv &&
+ /*
+ * sending src (local service)/dst (upstream) addresses over DNSTAP
+ */
+ if(error==NETEVENT_NOERROR && pi && sq->outnet->dtenv &&
(sq->outnet->dtenv->log_resolver_response_messages ||
- sq->outnet->dtenv->log_forwarder_response_messages))
+ sq->outnet->dtenv->log_forwarder_response_messages)) {
+ log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
+ log_addr(VERB_ALGO, "to local addr", &pi->addr, pi->addrlen);
dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr,
- c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
- &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
+ &pi->addr, c->type, sq->zone, sq->zonelen, sq->qbuf,
+ sq->qbuflen, &sq->last_sent_time, sq->outnet->now_tv,
+ c->buffer);
+ }
#endif
if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS &&
(LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
sq->status==serviced_query_TCP_EDNS?"EDNS":"");
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
sq->last_sent_time = *sq->outnet->now_tv;
- sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT,
+ sq->pending = pending_tcp_query(sq, buff, sq->outnet->tcp_auth_query_timeout,
serviced_tcp_callback, sq);
if(!sq->pending) {
/* delete from tree so that a retry by above layer does not
sq->last_sent_time = *sq->outnet->now_tv;
if(sq->tcp_upstream || sq->ssl_upstream) {
timeout = rtt;
- if(rtt >= UNKNOWN_SERVER_NICENESS && rtt < TCP_AUTH_QUERY_TIMEOUT)
- timeout = TCP_AUTH_QUERY_TIMEOUT;
+ if(rtt >= UNKNOWN_SERVER_NICENESS && rtt < sq->outnet->tcp_auth_query_timeout)
+ timeout = sq->outnet->tcp_auth_query_timeout;
} else {
- timeout = TCP_AUTH_QUERY_TIMEOUT;
+ timeout = sq->outnet->tcp_auth_query_timeout;
}
sq->pending = pending_tcp_query(sq, buff, timeout,
serviced_tcp_callback, sq);
struct serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet;
struct timeval now = *sq->outnet->now_tv;
+#ifdef USE_DNSTAP
+ struct pending* p = (struct pending*)sq->pending;
+ struct port_if* pi = p->pc->pif;
+#endif
sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) {
return 0;
}
#ifdef USE_DNSTAP
+ /*
+ * sending src (local service)/dst (upstream) addresses over DNSTAP
+ */
if(error == NETEVENT_NOERROR && outnet->dtenv &&
(outnet->dtenv->log_resolver_response_messages ||
- outnet->dtenv->log_forwarder_response_messages))
- dt_msg_send_outside_response(outnet->dtenv, &sq->addr, c->type,
- sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
- &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
+ outnet->dtenv->log_forwarder_response_messages)) {
+ log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
+ log_addr(VERB_ALGO, "to local addr", &pi->addr, pi->addrlen);
+ dt_msg_send_outside_response(outnet->dtenv, &sq->addr, &pi->addr, c->type,
+ sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
+ &sq->last_sent_time, sq->outnet->now_tv, c->buffer);
+ }
#endif
if( (sq->status == serviced_query_UDP_EDNS
||sq->status == serviced_query_UDP_EDNS_FRAG)
return NULL;
}
cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
- cb, cb_arg);
+ cb, cb_arg, NULL);
if(!cp) {
log_err("malloc failure");
close(fd);
return cp;
}
+/** setup the User-Agent HTTP header based on http-user-agent configuration */
+static void
+setup_http_user_agent(sldns_buffer* buf, struct config_file* cfg)
+{
+ if(cfg->hide_http_user_agent) return;
+ if(cfg->http_user_agent==NULL || cfg->http_user_agent[0] == 0) {
+ sldns_buffer_printf(buf, "User-Agent: %s/%s\r\n", PACKAGE_NAME,
+ PACKAGE_VERSION);
+ } else {
+ sldns_buffer_printf(buf, "User-Agent: %s\r\n", cfg->http_user_agent);
+ }
+}
+
/** setup http request headers in buffer for sending query to destination */
static int
-setup_http_request(sldns_buffer* buf, char* host, char* path)
+setup_http_request(sldns_buffer* buf, char* host, char* path,
+ struct config_file* cfg)
{
sldns_buffer_clear(buf);
sldns_buffer_printf(buf, "GET /%s HTTP/1.1\r\n", path);
sldns_buffer_printf(buf, "Host: %s\r\n", host);
- sldns_buffer_printf(buf, "User-Agent: unbound/%s\r\n",
- PACKAGE_VERSION);
+ setup_http_user_agent(buf, cfg);
/* We do not really do multiple queries per connection,
* but this header setting is also not needed.
* sldns_buffer_printf(buf, "Connection: close\r\n") */
outnet_comm_point_for_http(struct outside_network* outnet,
comm_point_callback_type* cb, void* cb_arg,
struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout,
- int ssl, char* host, char* path)
+ int ssl, char* host, char* path, struct config_file* cfg)
{
/* cp calls cb with err=NETEVENT_DONE when transfer is done */
struct comm_point* cp;
comm_point_start_listening(cp, fd, timeout);
/* setup http request in cp->buffer */
- if(!setup_http_request(cp->buffer, host, path)) {
+ if(!setup_http_request(cp->buffer, host, path, cfg)) {
log_err("error setting up http request");
comm_point_delete(cp);
return NULL;
struct module_env;
struct module_qstate;
struct query_info;
+struct config_file;
/**
* Send queries to outside servers and wait for answers from servers.
size_t num_tcp;
/** number of tcp communication points in use. */
size_t num_tcp_outgoing;
+ /** max number of queries on a reuse connection */
+ size_t max_reuse_tcp_queries;
+ /** timeout for REUSE entries in milliseconds. */
+ int tcp_reuse_timeout;
+ /** timeout in milliseconds for TCP queries to auth servers. */
+ int tcp_auth_query_timeout;
/**
* tree of still-open and waiting tcp connections for reuse.
* can be closed and reopened to get a new tcp connection.
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.
*/
struct pending_tcp {
/** next in list of free tcp comm points, or NULL. */
struct pending_tcp* next_free;
+ /** port for of the outgoing interface that is used */
+ struct port_if* pi;
/** tcp comm point it was sent on (and reply must come back on). */
struct comm_point* c;
/** the query being serviced, NULL if the pending_tcp is unused. */
char* tls_auth_name;
/** the packet was involved in an error, to stop looping errors */
int error_count;
+#ifdef USE_DNSTAP
+ /** serviced query pointer for dnstap to get logging info, if nonNULL*/
+ struct serviced_query* sq;
+#endif
};
/**
* @param tls_use_sni: if SNI is used for TLS connections.
* @param dtenv: environment to send dnstap events with (if enabled).
* @param udp_connect: if the udp_connect option is enabled.
+ * @param max_reuse_tcp_queries: max number of queries on a reuse connection.
+ * @param tcp_reuse_timeout: timeout for REUSE entries in milliseconds.
+ * @param tcp_auth_query_timeout: timeout in milliseconds for TCP queries to auth servers.
* @return: the new structure (with no pending answers) or NULL on error.
*/
struct outside_network* outside_network_create(struct comm_base* base,
int numavailports, size_t unwanted_threshold, int tcp_mss,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
- int udp_connect);
+ int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
+ int tcp_auth_query_timeout);
/**
* Delete outside_network structure.
/** insert element in tree by id */
void reuse_tree_by_id_insert(struct reuse_tcp* reuse, struct waiting_tcp* w);
+/** insert element in tcp_reuse tree and LRU list */
+int reuse_tcp_insert(struct outside_network* outnet,
+ struct pending_tcp* pend_tcp);
+
+/** touch the LRU of the element */
+void reuse_tcp_lru_touch(struct outside_network* outnet,
+ struct reuse_tcp* reuse);
+
+/** remove element from tree and LRU list */
+void reuse_tcp_remove_tree_list(struct outside_network* outnet,
+ struct reuse_tcp* reuse);
+
+/** snip the last reuse_tcp element off of the LRU list if any */
+struct reuse_tcp* reuse_tcp_lru_snip(struct outside_network* outnet);
+
/** 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,
* 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);
/**
* Create udp commpoint suitable for sending packets to the destination.
* @param ssl: set to true for https.
* @param host: hostname to use for the destination. part of http request.
* @param path: pathname to lookup, eg. name of the file on the destination.
+ * @param cfg: running configuration for User-Agent setup.
* @return http_out commpoint, or NULL.
*/
struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
comm_point_callback_type* cb, void* cb_arg,
struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout,
- int ssl, char* host, char* path);
+ int ssl, char* host, char* path, struct config_file* cfg);
/** connect tcp connection to addr, 0 on failure */
int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
#ifdef HAVE_OPENSSL_BN_H
#include <openssl/bn.h>
#endif
-#ifdef HAVE_OPENSSL_RSA_H
-#include <openssl/rsa.h>
-#endif
-#ifdef HAVE_OPENSSL_DSA_H
-#include <openssl/dsa.h>
+#ifdef HAVE_OPENSSL_PARAM_BUILD_H
+# include <openssl/param_build.h>
+#else
+# ifdef HAVE_OPENSSL_RSA_H
+# include <openssl/rsa.h>
+# endif
+# ifdef HAVE_OPENSSL_DSA_H
+# include <openssl/dsa.h>
+# endif
#endif
#endif /* HAVE_SSL */
}
#endif /* USE_GOST */
-DSA *
-sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
+/* Retrieve params as BIGNUM from raw buffer */
+static int
+sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
+ BIGNUM** q, BIGNUM** g, BIGNUM** y)
{
uint8_t T;
uint16_t length;
uint16_t offset;
- DSA *dsa;
- BIGNUM *Q; BIGNUM *P;
- BIGNUM *G; BIGNUM *Y;
if(len == 0)
- return NULL;
+ return 0;
T = (uint8_t)key[0];
length = (64 + T * 8);
offset = 1;
if (T > 8) {
- return NULL;
+ return 0;
}
if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
- return NULL;
+ return 0;
- Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
+ *q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
offset += SHA_DIGEST_LENGTH;
- P = BN_bin2bn(key+offset, (int)length, NULL);
+ *p = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
- G = BN_bin2bn(key+offset, (int)length, NULL);
+ *g = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
- Y = BN_bin2bn(key+offset, (int)length, NULL);
+ *y = BN_bin2bn(key+offset, (int)length, NULL);
+
+ if(!*q || !*p || !*g || !*y) {
+ BN_free(*q);
+ BN_free(*p);
+ BN_free(*g);
+ BN_free(*y);
+ return 0;
+ }
+ return 1;
+}
+#ifndef HAVE_OSSL_PARAM_BLD_NEW
+DSA *
+sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
+{
+ DSA *dsa;
+ BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
+ if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
+ return NULL;
+ }
/* create the key and set its properties */
- if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
- BN_free(Q);
- BN_free(P);
- BN_free(G);
- BN_free(Y);
+ if(!(dsa = DSA_new())) {
return NULL;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
return dsa;
}
+#endif /* HAVE_OSSL_PARAM_BLD_NEW */
-RSA *
-sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
+EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
+{
+#ifdef HAVE_OSSL_PARAM_BLD_NEW
+ EVP_PKEY* evp_key = NULL;
+ EVP_PKEY_CTX* ctx;
+ BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
+ OSSL_PARAM_BLD* param_bld;
+ OSSL_PARAM* params = NULL;
+ if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
+ return NULL;
+ }
+
+ param_bld = OSSL_PARAM_BLD_new();
+ if(!param_bld) {
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(y);
+ return NULL;
+ }
+ if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
+ !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
+ !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
+ !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
+ OSSL_PARAM_BLD_free(param_bld);
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(y);
+ return NULL;
+ }
+ params = OSSL_PARAM_BLD_to_param(param_bld);
+ OSSL_PARAM_BLD_free(param_bld);
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
+ if(!ctx) {
+ OSSL_PARAM_free(params);
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(y);
+ return NULL;
+ }
+ if(EVP_PKEY_fromdata_init(ctx) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(y);
+ return NULL;
+ }
+ if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(y);
+ return NULL;
+ }
+
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(y);
+ return evp_key;
+#else
+ DSA* dsa;
+ EVP_PKEY* evp_key = EVP_PKEY_new();
+ if(!evp_key) {
+ return NULL;
+ }
+ dsa = sldns_key_buf2dsa_raw(key, len);
+ if(!dsa) {
+ EVP_PKEY_free(evp_key);
+ return NULL;
+ }
+ if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
+ DSA_free(dsa);
+ EVP_PKEY_free(evp_key);
+ return NULL;
+ }
+ return evp_key;
+#endif
+}
+
+/* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
+static int
+sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
+ BIGNUM** e)
{
uint16_t offset;
uint16_t exp;
uint16_t int16;
- RSA *rsa;
- BIGNUM *modulus;
- BIGNUM *exponent;
if (len == 0)
- return NULL;
+ return 0;
if (key[0] == 0) {
if(len < 3)
- return NULL;
+ return 0;
memmove(&int16, key+1, 2);
exp = ntohs(int16);
offset = 3;
/* key length at least one */
if(len < (size_t)offset + exp + 1)
- return NULL;
+ return 0;
/* Exponent */
- exponent = BN_new();
- if(!exponent) return NULL;
- (void) BN_bin2bn(key+offset, (int)exp, exponent);
+ *e = BN_new();
+ if(!*e) return 0;
+ (void) BN_bin2bn(key+offset, (int)exp, *e);
offset += exp;
/* Modulus */
- modulus = BN_new();
- if(!modulus) {
- BN_free(exponent);
- return NULL;
+ *n = BN_new();
+ if(!*n) {
+ BN_free(*e);
+ return 0;
}
/* length of the buffer must match the key length! */
- (void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
+ (void) BN_bin2bn(key+offset, (int)(len - offset), *n);
+ return 1;
+}
+#ifndef HAVE_OSSL_PARAM_BLD_NEW
+RSA *
+sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
+{
+ BIGNUM* modulus = NULL;
+ BIGNUM* exponent = NULL;
+ RSA *rsa;
+ if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
+ return NULL;
rsa = RSA_new();
if(!rsa) {
BN_free(exponent);
return rsa;
}
+#endif /* HAVE_OSSL_PARAM_BLD_NEW */
+
+EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
+{
+#ifdef HAVE_OSSL_PARAM_BLD_NEW
+ EVP_PKEY* evp_key = NULL;
+ EVP_PKEY_CTX* ctx;
+ BIGNUM *n=NULL, *e=NULL;
+ OSSL_PARAM_BLD* param_bld;
+ OSSL_PARAM* params = NULL;
+
+ if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) {
+ return NULL;
+ }
+
+ param_bld = OSSL_PARAM_BLD_new();
+ if(!param_bld) {
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+ if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
+ OSSL_PARAM_BLD_free(param_bld);
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+ if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
+ OSSL_PARAM_BLD_free(param_bld);
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+ params = OSSL_PARAM_BLD_to_param(param_bld);
+ OSSL_PARAM_BLD_free(param_bld);
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+ if(!ctx) {
+ OSSL_PARAM_free(params);
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+ if(EVP_PKEY_fromdata_init(ctx) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+ if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ BN_free(n);
+ BN_free(e);
+ return NULL;
+ }
+
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ BN_free(n);
+ BN_free(e);
+ return evp_key;
+#else
+ RSA* rsa;
+ EVP_PKEY *evp_key = EVP_PKEY_new();
+ if(!evp_key) {
+ return NULL;
+ }
+ rsa = sldns_key_buf2rsa_raw(key, len);
+ if(!rsa) {
+ EVP_PKEY_free(evp_key);
+ return NULL;
+ }
+ if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
+ RSA_free(rsa);
+ EVP_PKEY_free(evp_key);
+ return NULL;
+ }
+ return evp_key;
+#endif
+}
#ifdef USE_GOST
EVP_PKEY*
EVP_PKEY*
sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
{
+#ifdef HAVE_OSSL_PARAM_BLD_NEW
+ unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
+ EVP_PKEY *evp_key = NULL;
+ EVP_PKEY_CTX* ctx;
+ OSSL_PARAM_BLD* param_bld;
+ OSSL_PARAM* params = NULL;
+ char* group = NULL;
+
+ /* check length, which uncompressed must be 2 bignums */
+ if(algo == LDNS_ECDSAP256SHA256) {
+ if(keylen != 2*256/8) return NULL;
+ group = "prime256v1";
+ } else if(algo == LDNS_ECDSAP384SHA384) {
+ if(keylen != 2*384/8) return NULL;
+ group = "P-384";
+ } else {
+ return NULL;
+ }
+ if(keylen+1 > sizeof(buf)) { /* sanity check */
+ return NULL;
+ }
+ /* prepend the 0x04 for uncompressed format */
+ buf[0] = POINT_CONVERSION_UNCOMPRESSED;
+ memmove(buf+1, key, keylen);
+
+ param_bld = OSSL_PARAM_BLD_new();
+ if(!param_bld) {
+ return NULL;
+ }
+ if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
+ !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
+ OSSL_PARAM_BLD_free(param_bld);
+ return NULL;
+ }
+ params = OSSL_PARAM_BLD_to_param(param_bld);
+ OSSL_PARAM_BLD_free(param_bld);
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
+ if(!ctx) {
+ OSSL_PARAM_free(params);
+ return NULL;
+ }
+ if(EVP_PKEY_fromdata_init(ctx) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ return NULL;
+ }
+ if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ return NULL;
+ }
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ return evp_key;
+#else
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
const unsigned char* pp = buf;
EVP_PKEY *evp_key;
return NULL;
}
return evp_key;
+#endif /* HAVE_OSSL_PARAM_BLD_NEW */
}
#endif /* USE_ECDSA */
/** Release the engine reference held for the GOST engine. */
void sldns_key_EVP_unload_gost(void);
+#ifndef HAVE_OSSL_PARAM_BLD_NEW
/**
* Like sldns_key_buf2dsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
* \return a DSA * structure with the key material
*/
DSA *sldns_key_buf2dsa_raw(unsigned char* key, size_t len);
+#endif
+
+/**
+ * Converts a holding buffer with DSA key material to EVP PKEY in openssl.
+ * \param[in] key the uncompressed wireformat of the key.
+ * \param[in] len length of key data
+ * \return the key or NULL on error.
+ */
+EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len);
/**
* Converts a holding buffer with key material to EVP PKEY in openssl.
*/
EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
+#ifndef HAVE_OSSL_PARAM_BLD_NEW
/**
* Like sldns_key_buf2rsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
* \return a RSA * structure with the key material
*/
RSA *sldns_key_buf2rsa_raw(unsigned char* key, size_t len);
+#endif
+
+/**
+ * Converts a holding buffer with RSA key material to EVP PKEY in openssl.
+ * \param[in] key the uncompressed wireformat of the key.
+ * \param[in] len length of key data
+ * \return the key or NULL on error.
+ */
+EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len);
/**
* Converts a holding buffer with key material to EVP PKEY in openssl.
if (c != '\0' && c != '\n') {
*t++ = c;
}
+ if (c == '\n' && line_nr) {
+ *line_nr = *line_nr + 1;
+ }
if (c == '\\' && prev_c == '\\')
prev_c = 0;
else prev_c = c;
* the position to the first character that is not in *s.
* \param[in] *buffer buffer to use
* \param[in] *s characters to skip
- * \return void
*/
void sldns_bskipcs(struct sldns_buffer *buffer, const char *s);
* the position to the first character that is not in *s.
* \param[in] *fp file to use
* \param[in] *s characters to skip
- * \return void
*/
void sldns_fskipcs(FILE *fp, const char *s);
* \param[in] *fp file to use
* \param[in] *s characters to skip
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return void
*/
void sldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);
}
return sldns_b64_pton_base(src, srcsize, target, targsize, 1);
}
+
+int sldns_b64_contains_nonurl(char const *src, size_t srcsize)
+{
+ const char* s = src;
+ while(*s && srcsize) {
+ char d = *s++;
+ srcsize--;
+ /* the '+' and the '/' and padding '=' is not allowed in b64
+ * url encoding */
+ if(d == '+' || d == '/' || d == '=') {
+ return 1;
+ }
+ }
+ return 0;
+}
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);
+int sldns_b64_contains_nonurl(char const *src, size_t srcsize);
/**
* calculates the size needed to store the result of b32_ntop
static const sldns_rdf_type type_csync_wireformat[] = {
LDNS_RDF_TYPE_INT32, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC
};
+static const sldns_rdf_type type_zonemd_wireformat[] = {
+ LDNS_RDF_TYPE_INT32, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
+};
+static const sldns_rdf_type type_svcb_wireformat[] = {
+ LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
+};
/* nsec3 is some vars, followed by same type of data of nsec */
static const sldns_rdf_type type_nsec3_wireformat[] = {
/* LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC*/
{LDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 62 */
{LDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{(enum sldns_enum_rr_type)0, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{(enum sldns_enum_rr_type)0, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{(enum sldns_enum_rr_type)0, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+ /* 63 */
+ {LDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+ /* 64 */
+ {LDNS_RR_TYPE_SVCB, "SVCB", 2, 2, type_svcb_wireformat, LDNS_RDF_TYPE_SVCPARAM, LDNS_RR_NO_COMPRESS, 0 },
+ /* 65 */
+ {LDNS_RR_TYPE_HTTPS, "HTTPS", 2, 2, type_svcb_wireformat, LDNS_RDF_TYPE_SVCPARAM, LDNS_RR_NO_COMPRESS, 0 },
{(enum sldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{(enum sldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{(enum sldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
LDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */
LDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
LDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
+ LDNS_RR_TYPE_ZONEMD = 63, /* draft-ietf-dnsop-dns-zone-digest-12 */
+ LDNS_RR_TYPE_SVCB = 64, /* draft-ietf-dnsop-svcb-https-04 */
+ LDNS_RR_TYPE_HTTPS = 65, /* draft-ietf-dnsop-svcb-https-04 */
LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
/** TSIG extended 16bit error value */
LDNS_RDF_TYPE_TSIGERROR,
+ /* draft-ietf-dnsop-svcb-https-05:
+ * each SvcParam consisting of a SvcParamKey=SvcParamValue pair or
+ * a standalone SvcParamKey */
+ LDNS_RDF_TYPE_SVCPARAM,
+
/* Aliases */
- LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC
+ LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC,
};
typedef enum sldns_enum_rdf_type sldns_rdf_type;
* the position is set to 0.
*
* \param[in] buffer the buffer to flip
- * \return void
*/
INLINE void sldns_buffer_flip(sldns_buffer *buffer)
{
/**
* frees the buffer.
* \param[in] *buffer the buffer to be freed
- * \return void
*/
void sldns_buffer_free(sldns_buffer *buffer);
#define RET_ERR(e, off) ((int)((e)|((off)<<LDNS_WIREPARSE_SHIFT)))
/** Move parse error but keep its ID */
#define RET_ERR_SHIFT(e, move) RET_ERR(LDNS_WIREPARSE_ERROR(e), LDNS_WIREPARSE_OFFSET(e)+(move));
-#define LDNS_IP6ADDRLEN (128/8)
/*
* No special care is taken, all dots are translated into
return 1;
}
+static int sldns_str2wire_svcparam_key_cmp(const void *a, const void *b)
+{
+ return sldns_read_uint16(*(uint8_t**) a)
+ - sldns_read_uint16(*(uint8_t**) b);
+}
+
+/**
+ * Add constraints to the SVCB RRs which involve the whole set
+ */
+static int sldns_str2wire_check_svcbparams(uint8_t* rdata, uint16_t rdata_len)
+{
+ size_t nparams = 0, i;
+ uint8_t new_rdata[LDNS_MAX_RDFLEN];
+ uint8_t* new_rdata_ptr = new_rdata;
+ uint8_t* svcparams[MAX_NUMBER_OF_SVCPARAMS];
+ uint8_t* rdata_ptr = rdata;
+ uint16_t rdata_remaining = rdata_len;
+
+ /* find the SvcParams */
+ while (rdata_remaining) {
+ uint16_t svcbparam_len;
+
+ svcparams[nparams] = rdata_ptr;
+ if (rdata_remaining < 4)
+ return LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA;
+ svcbparam_len = sldns_read_uint16(rdata_ptr + 2);
+ rdata_remaining -= 4;
+ rdata_ptr += 4;
+
+ if (rdata_remaining < svcbparam_len)
+ return LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA;
+ rdata_remaining -= svcbparam_len;
+ rdata_ptr += svcbparam_len;
+
+ nparams += 1;
+ if (nparams >= MAX_NUMBER_OF_SVCPARAMS)
+ return LDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS;
+ }
+
+ /* In draft-ietf-dnsop-svcb-https-06 Section 7:
+ *
+ * In wire format, the keys are represented by their numeric
+ * values in network byte order, concatenated in ascending order.
+ */
+ qsort((void *)svcparams
+ ,nparams
+ ,sizeof(uint8_t*)
+ ,sldns_str2wire_svcparam_key_cmp);
+
+
+ /* The code below revolves around sematic errors in the SVCParam set.
+ * So long as we do not distinguish between running Unbound as a primary
+ * or as a secondary, we default to secondary behavior and we ignore the
+ * sematic errors. */
+
+#ifdef SVCB_SEMANTIC_ERRORS
+ {
+ uint8_t* mandatory = NULL;
+ /* In draft-ietf-dnsop-svcb-https-06 Section 7:
+ *
+ * Keys (...) MUST NOT appear more than once.
+ *
+ * If they key has already been seen, we have a duplicate
+ */
+ for(i=0; i < nparams; i++) {
+ uint16_t key = sldns_read_uint16(svcparams[i]);
+ if(i + 1 < nparams && key == sldns_read_uint16(svcparams[i+1]))
+ return LDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS;
+ if(key == SVCB_KEY_MANDATORY)
+ mandatory = svcparams[i];
+ }
+
+ /* 4. verify that all the SvcParamKeys in mandatory are present */
+ if(mandatory) {
+ /* Divide by sizeof(uint16_t)*/
+ uint16_t mandatory_nkeys = sldns_read_uint16(mandatory + 2) / sizeof(uint16_t);
+
+ /* Guaranteed by sldns_str2wire_svcparam_key_value */
+ assert(mandatory_nkeys > 0);
+
+ for(i=0; i < mandatory_nkeys; i++) {
+ uint16_t mandatory_key = sldns_read_uint16(
+ mandatory
+ + 2 * sizeof(uint16_t)
+ + i * sizeof(uint16_t));
+ uint8_t found = 0;
+ size_t j;
+
+ for(j=0; j < nparams; j++) {
+ if(mandatory_key == sldns_read_uint16(svcparams[j])) {
+ found = 1;
+ break;
+ }
+ }
+
+ if(!found)
+ return LDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM;
+ }
+ }
+ }
+#endif
+ /* Write rdata in correct order */
+ for (i = 0; i < nparams; i++) {
+ uint16_t svcparam_len = sldns_read_uint16(svcparams[i] + 2)
+ + 2 * sizeof(uint16_t);
+
+ if ((unsigned)(new_rdata_ptr - new_rdata) + svcparam_len > sizeof(new_rdata))
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+
+ memcpy(new_rdata_ptr, svcparams[i], svcparam_len);
+ new_rdata_ptr += svcparam_len;
+ }
+ memcpy(rdata, new_rdata, rdata_len);
+ return LDNS_WIREPARSE_ERR_OK;
+}
+
/** parse rdata from string into rr buffer(-remainder after dname). */
static int
rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
/* write rdata length */
sldns_write_uint16(rr+dname_len+8, (uint16_t)(rr_cur_len-dname_len-10));
*rr_len = rr_cur_len;
+ /* SVCB/HTTPS handling */
+ if (rr_type == LDNS_RR_TYPE_SVCB || rr_type == LDNS_RR_TYPE_HTTPS) {
+ size_t rdata_len = rr_cur_len - dname_len - 10;
+ uint8_t *rdata = rr+dname_len + 10;
+
+ /* skip 1st rdata field SvcPriority (uint16_t) */
+ if (rdata_len < sizeof(uint16_t))
+ return LDNS_WIREPARSE_ERR_OK;
+
+ rdata_len -= sizeof(uint16_t);
+ rdata += sizeof(uint16_t);
+
+ /* skip 2nd rdata field dname */
+ while (rdata_len && *rdata != 0) {
+ uint8_t label_len;
+
+ if (*rdata & 0xC0)
+ return LDNS_WIREPARSE_ERR_OK;
+
+ label_len = *rdata + 1;
+ if (rdata_len < label_len)
+ return LDNS_WIREPARSE_ERR_OK;
+
+ rdata_len -= label_len;
+ rdata += label_len;
+ }
+ /* The root label is one more character, so smaller
+ * than 1 + 1 means no Svcparam Keys */
+ if (rdata_len < 2 || *rdata != 0)
+ return LDNS_WIREPARSE_ERR_OK;
+
+ rdata_len -= 1;
+ rdata += 1;
+ return sldns_str2wire_check_svcbparams(rdata, rdata_len);
+
+ }
return LDNS_WIREPARSE_ERR_OK;
}
memmove(parse_state->prev_rr, rr, *dname_len);
parse_state->prev_rr_len = (*dname_len);
}
+ if(r == LDNS_WIREPARSE_ERR_OK && parse_state) {
+ parse_state->default_ttl = sldns_wirerr_get_ttl(
+ rr, *len, *dname_len);
+ }
return r;
}
return LDNS_WIREPARSE_ERR_OK;
}
+static int
+sldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
+{
+ char buf[64];
+ char *endptr;
+ unsigned long int key_value;
+
+ if (key_len >= 4 && key_len <= 8 && !strncmp(key, "key", 3)) {
+ memcpy(buf, key + 3, key_len - 3);
+ buf[key_len - 3] = 0;
+ key_value = strtoul(buf, &endptr, 10);
+
+ if (endptr > buf /* digits seen */
+ && *endptr == 0 /* no non-digit chars after digits */
+ && key_value <= 65535) /* no overflow */
+ return key_value;
+
+ } else switch (key_len) {
+ case sizeof("mandatory")-1:
+ if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
+ return SVCB_KEY_MANDATORY;
+ if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
+ return SVCB_KEY_ECH; /* allow "echconfig as well as "ech" */
+ break;
+
+ case sizeof("alpn")-1:
+ if (!strncmp(key, "alpn", sizeof("alpn")-1))
+ return SVCB_KEY_ALPN;
+ if (!strncmp(key, "port", sizeof("port")-1))
+ return SVCB_KEY_PORT;
+ break;
+
+ case sizeof("no-default-alpn")-1:
+ if (!strncmp( key , "no-default-alpn"
+ , sizeof("no-default-alpn")-1))
+ return SVCB_KEY_NO_DEFAULT_ALPN;
+ break;
+
+ case sizeof("ipv4hint")-1:
+ if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
+ return SVCB_KEY_IPV4HINT;
+ if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
+ return SVCB_KEY_IPV6HINT;
+ break;
+
+ case sizeof("ech")-1:
+ if (!strncmp(key, "ech", sizeof("ech")-1))
+ return SVCB_KEY_ECH;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Although the returned value might be used by the caller,
+ * the parser has erred, so the zone will not be loaded.
+ */
+ return -1;
+}
+
+static int
+sldns_str2wire_svcparam_port(const char* val, uint8_t* rd, size_t* rd_len)
+{
+ unsigned long int port;
+ char *endptr;
+
+ if (*rd_len < 6)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+
+ port = strtoul(val, &endptr, 10);
+
+ if (endptr > val /* digits seen */
+ && *endptr == 0 /* no non-digit chars after digits */
+ && port <= 65535) { /* no overflow */
+
+ sldns_write_uint16(rd, SVCB_KEY_PORT);
+ sldns_write_uint16(rd + 2, sizeof(uint16_t));
+ sldns_write_uint16(rd + 4, port);
+ *rd_len = 6;
+
+ return LDNS_WIREPARSE_ERR_OK;
+ }
+
+ return LDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX;
+}
+
+static int
+sldns_str2wire_svcbparam_ipv4hint(const char* val, uint8_t* rd, size_t* rd_len)
+{
+ size_t count;
+ char ip_str[INET_ADDRSTRLEN+1];
+ char *next_ip_str;
+ size_t i;
+
+ for (i = 0, count = 1; val[i]; i++) {
+ if (val[i] == ',')
+ count += 1;
+ if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
+ return LDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES;
+ }
+ }
+
+ if (*rd_len < (LDNS_IP4ADDRLEN * count) + 4)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+
+ /* count is number of comma's in val + 1; so the actual number of IPv4
+ * addresses in val
+ */
+ sldns_write_uint16(rd, SVCB_KEY_IPV4HINT);
+ sldns_write_uint16(rd + 2, LDNS_IP4ADDRLEN * count);
+ *rd_len = 4;
+
+ while (count) {
+ if (!(next_ip_str = strchr(val, ','))) {
+ if (inet_pton(AF_INET, val, rd + *rd_len) != 1)
+ break;
+ *rd_len += LDNS_IP4ADDRLEN;
+
+ assert(count == 1);
+
+ } else if (next_ip_str - val >= (int)sizeof(ip_str))
+ break;
+
+ else {
+ memcpy(ip_str, val, next_ip_str - val);
+ ip_str[next_ip_str - val] = 0;
+ if (inet_pton(AF_INET, ip_str, rd + *rd_len) != 1) {
+ break;
+ }
+ *rd_len += LDNS_IP4ADDRLEN;
+
+ val = next_ip_str + 1;
+ }
+ count--;
+ }
+ if (count) /* verify that we parsed all values */
+ return LDNS_WIREPARSE_ERR_SYNTAX_IP4;
+
+ return LDNS_WIREPARSE_ERR_OK;
+}
+
+static int
+sldns_str2wire_svcbparam_ipv6hint(const char* val, uint8_t* rd, size_t* rd_len)
+{
+ size_t count;
+ char ip_str[INET6_ADDRSTRLEN+1];
+ char *next_ip_str;
+ size_t i;
+
+ for (i = 0, count = 1; val[i]; i++) {
+ if (val[i] == ',')
+ count += 1;
+ if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
+ return LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES;
+ }
+ }
+
+ if (*rd_len < (LDNS_IP6ADDRLEN * count) + 4)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+
+ /* count is number of comma's in val + 1; so the actual number of IPv6
+ * addresses in val
+ */
+ sldns_write_uint16(rd, SVCB_KEY_IPV6HINT);
+ sldns_write_uint16(rd + 2, LDNS_IP6ADDRLEN * count);
+ *rd_len = 4;
+
+ while (count) {
+ if (!(next_ip_str = strchr(val, ','))) {
+ if (inet_pton(AF_INET6, val, rd + *rd_len) != 1)
+ break;
+ *rd_len += LDNS_IP6ADDRLEN;
+
+ assert(count == 1);
+
+ } else if (next_ip_str - val >= (int)sizeof(ip_str))
+ break;
+
+ else {
+ memcpy(ip_str, val, next_ip_str - val);
+ ip_str[next_ip_str - val] = 0;
+ if (inet_pton(AF_INET6, ip_str, rd + *rd_len) != 1) {
+ break;
+ }
+ *rd_len += LDNS_IP6ADDRLEN;
+
+ val = next_ip_str + 1;
+ }
+ count--;
+ }
+ if (count) /* verify that we parsed all values */
+ return LDNS_WIREPARSE_ERR_SYNTAX_IP6;
+
+ return LDNS_WIREPARSE_ERR_OK;
+}
+
+/* compare function used for sorting uint16_t's */
+static int
+sldns_network_uint16_cmp(const void *a, const void *b)
+{
+ return ((int)sldns_read_uint16(a)) - ((int)sldns_read_uint16(b));
+}
+
+static int
+sldns_str2wire_svcbparam_mandatory(const char* val, uint8_t* rd, size_t* rd_len)
+{
+ size_t i, count, val_len;
+ char* next_key;
+
+ val_len = strlen(val);
+
+ for (i = 0, count = 1; val[i]; i++) {
+ if (val[i] == ',')
+ count += 1;
+ if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
+ return LDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS;
+ }
+ }
+ if (sizeof(uint16_t) * (count + 2) > *rd_len)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+
+ sldns_write_uint16(rd, SVCB_KEY_MANDATORY);
+ sldns_write_uint16(rd + 2, sizeof(uint16_t) * count);
+ *rd_len = 4;
+
+ while (1) {
+ int svcparamkey;
+
+ if (!(next_key = strchr(val, ','))) {
+ svcparamkey = sldns_str2wire_svcparam_key_lookup(val, val_len);
+
+ if (svcparamkey < 0) {
+ return LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
+ }
+
+ sldns_write_uint16(rd + *rd_len, svcparamkey);
+ *rd_len += 2;
+ break;
+ } else {
+ svcparamkey = sldns_str2wire_svcparam_key_lookup(val, next_key - val);
+
+ if (svcparamkey < 0) {
+ return LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
+ }
+
+ sldns_write_uint16(rd + *rd_len,
+ svcparamkey);
+ *rd_len += 2;
+ }
+
+ val_len -= next_key - val + 1;
+ val = next_key + 1; /* skip the comma */
+ }
+
+ /* In draft-ietf-dnsop-svcb-https-06 Section 7:
+ *
+ * "In wire format, the keys are represented by their numeric
+ * values in network byte order, concatenated in ascending order."
+ */
+ qsort((void *)(rd + 4), count, sizeof(uint16_t), sldns_network_uint16_cmp);
+
+ /* The code below revolves around sematic errors in the SVCParam set.
+ * So long as we do not distinguish between running Unbound as a primary
+ * or as a secondary, we default to secondary behavior and we ignore the
+ * semantic errors. */
+#ifdef SVCB_SEMANTIC_ERRORS
+ /* In draft-ietf-dnsop-svcb-https-06 Section 8
+ * automatically mandatory MUST NOT appear in its own value-list
+ */
+ if (sldns_read_uint16(rd + 4) == SVCB_KEY_MANDATORY)
+ return LDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY;
+
+ /* Guarantee key uniqueness. After the sort we only need to
+ * compare neighbouring keys */
+ if (count > 1) {
+ for (i = 0; i < count - 1; i++) {
+ uint8_t* current_pos = (rd + 4 + (sizeof(uint16_t) * i));
+ uint16_t key = sldns_read_uint16(current_pos);
+
+ if (key == sldns_read_uint16(current_pos + 2)) {
+ return LDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY;
+ }
+ }
+ }
+#endif
+ return LDNS_WIREPARSE_ERR_OK;
+}
+
+static int
+sldns_str2wire_svcbparam_ech_value(const char* val, uint8_t* rd, size_t* rd_len)
+{
+ uint8_t buffer[LDNS_MAX_RDFLEN];
+ int wire_len;
+
+ /* single 0 represents empty buffer */
+ if(strcmp(val, "0") == 0) {
+ if (*rd_len < 4)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+ sldns_write_uint16(rd, SVCB_KEY_ECH);
+ sldns_write_uint16(rd + 2, 0);
+
+ return LDNS_WIREPARSE_ERR_OK;
+ }
+
+ wire_len = sldns_b64_pton(val, buffer, LDNS_MAX_RDFLEN);
+
+ if (wire_len <= 0) {
+ return LDNS_WIREPARSE_ERR_SYNTAX_B64;
+ } else if ((unsigned)wire_len + 4 > *rd_len) {
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+ } else {
+ sldns_write_uint16(rd, SVCB_KEY_ECH);
+ sldns_write_uint16(rd + 2, wire_len);
+ memcpy(rd + 4, buffer, wire_len);
+ *rd_len = 4 + wire_len;
+
+ return LDNS_WIREPARSE_ERR_OK;
+ }
+}
+
+static const char*
+sldns_str2wire_svcbparam_parse_next_unescaped_comma(const char *val)
+{
+ while (*val) {
+ /* Only return when the comma is not escaped*/
+ if (*val == '\\'){
+ ++val;
+ if (!*val)
+ break;
+ } else if (*val == ',')
+ return val;
+
+ val++;
+ }
+ return NULL;
+}
+
+/* The source is already properly unescaped, this double unescaping is purely to allow for
+ * comma's in comma seperated alpn lists.
+ *
+ * In draft-ietf-dnsop-svcb-https-06 Section 7:
+ * To enable simpler parsing, this SvcParamValue MUST NOT contain escape sequences.
+ */
+static size_t
+sldns_str2wire_svcbparam_parse_copy_unescaped(uint8_t *dst,
+ const char *src, size_t len)
+{
+ uint8_t *orig_dst = dst;
+
+ while (len) {
+ if (*src == '\\') {
+ src++;
+ len--;
+ if (!len)
+ break;
+ }
+ *dst++ = *src++;
+ len--;
+ }
+ return (size_t)(dst - orig_dst);
+}
+
+static int
+sldns_str2wire_svcbparam_alpn_value(const char* val,
+ uint8_t* rd, size_t* rd_len)
+{
+ uint8_t unescaped_dst[LDNS_MAX_RDFLEN];
+ uint8_t *dst = unescaped_dst;
+ const char *next_str;
+ size_t str_len;
+ size_t dst_len;
+ size_t val_len;
+
+ val_len = strlen(val);
+
+ if (val_len > sizeof(unescaped_dst)) {
+ return LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE;
+ }
+ while (val_len) {
+ size_t key_len;
+
+ str_len = (next_str = sldns_str2wire_svcbparam_parse_next_unescaped_comma(val))
+ ? (size_t)(next_str - val) : val_len;
+
+ if (str_len > 255) {
+ return LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE;
+ }
+
+ key_len = sldns_str2wire_svcbparam_parse_copy_unescaped(dst + 1, val, str_len);
+ *dst++ = key_len;
+ dst += key_len;
+
+ if (!next_str)
+ break;
+
+ /* skip the comma in the next iteration */
+ val_len -= next_str - val + 1;
+ val = next_str + 1;
+ }
+ dst_len = dst - unescaped_dst;
+ if (*rd_len < 4 + dst_len)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+ sldns_write_uint16(rd, SVCB_KEY_ALPN);
+ sldns_write_uint16(rd + 2, dst_len);
+ memcpy(rd + 4, unescaped_dst, dst_len);
+ *rd_len = 4 + dst_len;
+
+ return LDNS_WIREPARSE_ERR_OK;
+}
+
+static int
+sldns_str2wire_svcparam_value(const char *key, size_t key_len,
+ const char *val, uint8_t* rd, size_t* rd_len)
+{
+ size_t str_len;
+ int svcparamkey = sldns_str2wire_svcparam_key_lookup(key, key_len);
+
+ if (svcparamkey < 0) {
+ return LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
+ }
+
+ /* key without value */
+ if (val == NULL) {
+ switch (svcparamkey) {
+#ifdef SVCB_SEMANTIC_ERRORS
+ case SVCB_KEY_MANDATORY:
+ case SVCB_KEY_ALPN:
+ case SVCB_KEY_PORT:
+ case SVCB_KEY_IPV4HINT:
+ case SVCB_KEY_IPV6HINT:
+ return LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM;
+#endif
+ default:
+ if (*rd_len < 4)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+ sldns_write_uint16(rd, svcparamkey);
+ sldns_write_uint16(rd + 2, 0);
+ *rd_len = 4;
+
+ return LDNS_WIREPARSE_ERR_OK;
+ }
+ }
+
+ /* value is non-empty */
+ switch (svcparamkey) {
+ case SVCB_KEY_PORT:
+ return sldns_str2wire_svcparam_port(val, rd, rd_len);
+ case SVCB_KEY_IPV4HINT:
+ return sldns_str2wire_svcbparam_ipv4hint(val, rd, rd_len);
+ case SVCB_KEY_IPV6HINT:
+ return sldns_str2wire_svcbparam_ipv6hint(val, rd, rd_len);
+ case SVCB_KEY_MANDATORY:
+ return sldns_str2wire_svcbparam_mandatory(val, rd, rd_len);
+#ifdef SVCB_SEMANTIC_ERRORS
+ case SVCB_KEY_NO_DEFAULT_ALPN:
+ return LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE;
+#endif
+ case SVCB_KEY_ECH:
+ return sldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
+ case SVCB_KEY_ALPN:
+ return sldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
+ default:
+ str_len = strlen(val);
+ if (*rd_len < 4 + str_len)
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+ sldns_write_uint16(rd, svcparamkey);
+ sldns_write_uint16(rd + 2, str_len);
+ memcpy(rd + 4, val, str_len);
+ *rd_len = 4 + str_len;
+
+ return LDNS_WIREPARSE_ERR_OK;
+ }
+
+ return LDNS_WIREPARSE_ERR_GENERAL;
+}
+
+int sldns_str2wire_svcparam_buf(const char* str, uint8_t* rd, size_t* rd_len)
+{
+ const char* eq_pos;
+ char unescaped_val[LDNS_MAX_RDFLEN];
+ char* val_out = unescaped_val;
+ const char* val_in;
+
+ eq_pos = strchr(str, '=');
+
+ /* case: key=value */
+ if (eq_pos != NULL && eq_pos[1]) {
+ val_in = eq_pos + 1;
+
+ /* unescape characters and "" blocks */
+ if (*val_in == '"') {
+ val_in++;
+ while (*val_in != '"'
+ && (unsigned)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
+ && sldns_parse_char( (uint8_t*) val_out, &val_in)) {
+ val_out++;
+ }
+ } else {
+ while ((unsigned)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
+ && sldns_parse_char( (uint8_t*) val_out, &val_in)) {
+ val_out++;
+ }
+ }
+ *val_out = 0;
+
+ return sldns_str2wire_svcparam_value(str, eq_pos - str,
+ unescaped_val[0] ? unescaped_val : NULL, rd, rd_len);
+ }
+ /* case: key= */
+ else if (eq_pos != NULL && !(eq_pos[1])) {
+ return sldns_str2wire_svcparam_value(str, eq_pos - str, NULL, rd, rd_len);
+ }
+ /* case: key */
+ else {
+ return sldns_str2wire_svcparam_value(str, strlen(str), NULL, rd, rd_len);
+ }
+}
+
int sldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
sldns_rdf_type rdftype)
{
return sldns_str2wire_hip_buf(str, rd, len);
case LDNS_RDF_TYPE_INT16_DATA:
return sldns_str2wire_int16_data_buf(str, rd, len);
+ case LDNS_RDF_TYPE_SVCPARAM:
+ return sldns_str2wire_svcparam_buf(str, rd, len);
case LDNS_RDF_TYPE_UNKNOWN:
case LDNS_RDF_TYPE_SERVICE:
return LDNS_WIREPARSE_ERR_NOT_IMPL;
loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
{
uint32_t meters = 0, cm = 0, val;
+ char* cm_endstr;
while (isblank((unsigned char)*my_str)) {
my_str++;
}
meters = (uint32_t)strtol(my_str, &my_str, 10);
if (*my_str == '.') {
my_str++;
- cm = (uint32_t)strtol(my_str, &my_str, 10);
+ cm = (uint32_t)strtol(my_str, &cm_endstr, 10);
+ if(cm_endstr == my_str + 1)
+ cm *= 10;
+ my_str = cm_endstr;
}
if (meters >= 1) {
*e = 2;
#endif
struct sldns_struct_lookup_table;
+#define LDNS_IP4ADDRLEN (32/8)
+#define LDNS_IP6ADDRLEN (128/8)
+
/** buffer to read an RR, cannot be larger than 64K because of packet size */
#define LDNS_RR_BUF_SIZE 65535 /* bytes */
#define LDNS_DEFAULT_TTL 3600
+/* SVCB keys currently defined in draft-ietf-dnsop-svcb-https */
+#define SVCB_KEY_MANDATORY 0
+#define SVCB_KEY_ALPN 1
+#define SVCB_KEY_NO_DEFAULT_ALPN 2
+#define SVCB_KEY_PORT 3
+#define SVCB_KEY_IPV4HINT 4
+#define SVCB_KEY_ECH 5
+#define SVCB_KEY_IPV6HINT 6
+#define SVCPARAMKEY_COUNT 7
+
+#define MAX_NUMBER_OF_SVCPARAMS 64
+
+#define SVCB_MAX_COMMA_SEPARATED_VALUES 1000
+
/*
* To convert class and type to string see
* sldns_get_rr_class_by_name(str)
#define LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW 370
#define LDNS_WIREPARSE_ERR_INCLUDE 371
#define LDNS_WIREPARSE_ERR_PARENTHESIS 372
+#define LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY 373
+#define LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM 374
+#define LDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS 375
+#define LDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS 376
+#define LDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS 377
+#define LDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM 378
+#define LDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY 379
+#define LDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY 380
+#define LDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX 381
+#define LDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES 382
+#define LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES 383
+#define LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE 384
+#define LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE 385
+#define LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 386
/**
* Get reference to a constant string for the (parse) error.
{ LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer overflow" },
{ LDNS_WIREPARSE_ERR_INCLUDE, "$INCLUDE directive was seen in the zone" },
{ LDNS_WIREPARSE_ERR_PARENTHESIS, "Parse error, parenthesis mismatch" },
+ { LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY, "Unknown SvcParamKey"},
+ { LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM, "SvcParam is missing a SvcParamValue"},
+ { LDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS, "Duplicate SVCB key found"},
+ { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS, "Too many keys in mandatory" },
+ { LDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS,
+ "Too many SvcParams. Unbound only allows 63 entries" },
+ { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM,
+ "Mandatory SvcParamKey is missing"},
+ { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY,
+ "Keys in SvcParam mandatory MUST be unique" },
+ { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY,
+ "mandatory MUST not be included as mandatory parameter" },
+ { LDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX,
+ "Could not parse port SvcParamValue" },
+ { LDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES,
+ "Too many IPv4 addresses in ipv4hint" },
+ { LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES,
+ "Too many IPv6 addresses in ipv6hint" },
+ { LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE,
+ "Alpn strings need to be smaller than 255 chars"},
+ { LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE,
+ "No-default-alpn should not have a value" },
+ { LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA,
+ "General SVCParam error" },
{ 0, NULL }
};
sldns_lookup_table* sldns_wireparse_errors = sldns_wireparse_errors_data;
};
sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
+/* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */
+const char *svcparamkey_strs[] = {
+ "mandatory", "alpn", "no-default-alpn", "port",
+ "ipv4hint", "ech", "ipv6hint"
+};
+
char* sldns_wire2str_pkt(uint8_t* data, size_t len)
{
size_t slen = (size_t)sldns_wire2str_pkt_buf(data, len, NULL, 0);
return sldns_str_print(s, slen, "%u", (unsigned)ttl);
}
+static int
+sldns_print_svcparamkey(char** s, size_t* slen, uint16_t svcparamkey)
+{
+ if (svcparamkey < SVCPARAMKEY_COUNT) {
+ return sldns_str_print(s, slen, "%s", svcparamkey_strs[svcparamkey]);
+ }
+ else {
+ return sldns_str_print(s, slen, "key%d", (int)svcparamkey);
+ }
+}
+
+static int sldns_wire2str_svcparam_port2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ int w = 0;
+
+ if (data_len != 2)
+ return -1; /* wireformat error, a short is 2 bytes */
+ w = sldns_str_print(s, slen, "=%d", (int)sldns_read_uint16(data));
+
+ return w;
+}
+
+static int sldns_wire2str_svcparam_ipv4hint2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ char ip_str[INET_ADDRSTRLEN + 1];
+
+ int w = 0;
+
+ assert(data_len > 0);
+
+ if ((data_len % LDNS_IP4ADDRLEN) == 0) {
+ if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
+ return -1; /* wireformat error, incorrect size or inet family */
+
+ w += sldns_str_print(s, slen, "=%s", ip_str);
+ data += LDNS_IP4ADDRLEN;
+
+ while ((data_len -= LDNS_IP4ADDRLEN) > 0) {
+ if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
+ return -1; /* wireformat error, incorrect size or inet family */
+
+ w += sldns_str_print(s, slen, ",%s", ip_str);
+ data += LDNS_IP4ADDRLEN;
+ }
+ } else
+ return -1;
+
+ return w;
+}
+
+static int sldns_wire2str_svcparam_ipv6hint2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ char ip_str[INET6_ADDRSTRLEN + 1];
+
+ int w = 0;
+
+ assert(data_len > 0);
+
+ if ((data_len % LDNS_IP6ADDRLEN) == 0) {
+ if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
+ return -1; /* wireformat error, incorrect size or inet family */
+
+ w += sldns_str_print(s, slen, "=%s", ip_str);
+ data += LDNS_IP6ADDRLEN;
+
+ while ((data_len -= LDNS_IP6ADDRLEN) > 0) {
+ if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
+ return -1; /* wireformat error, incorrect size or inet family */
+
+ w += sldns_str_print(s, slen, ",%s", ip_str);
+ data += LDNS_IP6ADDRLEN;
+ }
+ } else
+ return -1;
+
+ return w;
+}
+
+static int sldns_wire2str_svcparam_mandatory2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ int w = 0;
+
+ assert(data_len > 0);
+
+ if (data_len % sizeof(uint16_t))
+ return -1; // wireformat error, data_len must be multiple of shorts
+ w += sldns_str_print(s, slen, "=");
+ w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data));
+ data += 2;
+
+ while ((data_len -= sizeof(uint16_t))) {
+ w += sldns_str_print(s, slen, ",");
+ w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data));
+ data += 2;
+ }
+
+ return w;
+}
+
+static int sldns_wire2str_svcparam_alpn2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ uint8_t *dp = (void *)data;
+ int w = 0;
+
+ assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */
+
+ w += sldns_str_print(s, slen, "=\"");
+ while (data_len) {
+ /* alpn is list of length byte (str_len) followed by a string of that size */
+ uint8_t i, str_len = *dp++;
+
+ if (str_len > --data_len)
+ return -1;
+
+ for (i = 0; i < str_len; i++) {
+ if (dp[i] == '"' || dp[i] == '\\')
+ w += sldns_str_print(s, slen, "\\\\\\%c", dp[i]);
+
+ else if (dp[i] == ',')
+ w += sldns_str_print(s, slen, "\\\\%c", dp[i]);
+
+ else if (!isprint(dp[i]))
+ w += sldns_str_print(s, slen, "\\%03u", (unsigned) dp[i]);
+
+ else
+ w += sldns_str_print(s, slen, "%c", dp[i]);
+ }
+ dp += str_len;
+ if ((data_len -= str_len))
+ w += sldns_str_print(s, slen, "%s", ",");
+ }
+ w += sldns_str_print(s, slen, "\"");
+
+ return w;
+}
+
+static int sldns_wire2str_svcparam_ech2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ int size;
+ int w = 0;
+
+ assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */
+
+ w += sldns_str_print(s, slen, "=\"");
+
+ if ((size = sldns_b64_ntop(data, data_len, *s, *slen)) < 0)
+ return -1;
+
+ (*s) += size;
+ (*slen) -= size;
+
+ w += sldns_str_print(s, slen, "\"");
+
+ return w + size;
+}
+
+int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
+{
+ uint8_t ch;
+ uint16_t svcparamkey, data_len;
+ int written_chars = 0;
+ int r, i;
+
+ /* verify that we have enough data to read svcparamkey and data_len */
+ if(*dlen < 4)
+ return -1;
+
+ svcparamkey = sldns_read_uint16(*d);
+ data_len = sldns_read_uint16(*d+2);
+ *d += 4;
+ *dlen -= 4;
+
+ /* verify that we have data_len data */
+ if (data_len > *dlen)
+ return -1;
+
+ written_chars += sldns_print_svcparamkey(s, slen, svcparamkey);
+ if (!data_len) {
+
+ /* Some SvcParams MUST have values */
+ switch (svcparamkey) {
+ case SVCB_KEY_ALPN:
+ case SVCB_KEY_PORT:
+ case SVCB_KEY_IPV4HINT:
+ case SVCB_KEY_IPV6HINT:
+ case SVCB_KEY_MANDATORY:
+ return -1;
+ default:
+ return written_chars;
+ }
+ }
+
+ switch (svcparamkey) {
+ case SVCB_KEY_PORT:
+ r = sldns_wire2str_svcparam_port2str(s, slen, data_len, *d);
+ break;
+ case SVCB_KEY_IPV4HINT:
+ r = sldns_wire2str_svcparam_ipv4hint2str(s, slen, data_len, *d);
+ break;
+ case SVCB_KEY_IPV6HINT:
+ r = sldns_wire2str_svcparam_ipv6hint2str(s, slen, data_len, *d);
+ break;
+ case SVCB_KEY_MANDATORY:
+ r = sldns_wire2str_svcparam_mandatory2str(s, slen, data_len, *d);
+ break;
+ case SVCB_KEY_NO_DEFAULT_ALPN:
+ return -1; /* wireformat error, should not have a value */
+ case SVCB_KEY_ALPN:
+ r = sldns_wire2str_svcparam_alpn2str(s, slen, data_len, *d);
+ break;
+ case SVCB_KEY_ECH:
+ r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
+ break;
+ default:
+ r = sldns_str_print(s, slen, "=\"");
+
+ for (i = 0; i < data_len; i++) {
+ ch = (*d)[i];
+
+ if (ch == '"' || ch == '\\')
+ r += sldns_str_print(s, slen, "\\%c", ch);
+
+ else if (!isprint(ch))
+ r += sldns_str_print(s, slen, "\\%03u", (unsigned) ch);
+
+ else
+ r += sldns_str_print(s, slen, "%c", ch);
+
+ }
+ r += sldns_str_print(s, slen, "\"");
+ break;
+ }
+ if (r <= 0)
+ return -1; /* wireformat error */
+
+ written_chars += r;
+ *d += data_len;
+ *dlen -= data_len;
+ return written_chars;
+}
+
int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop)
{
return sldns_wire2str_tag_scan(d, dlen, s, slen);
case LDNS_RDF_TYPE_LONG_STR:
return sldns_wire2str_long_str_scan(d, dlen, s, slen);
+ case LDNS_RDF_TYPE_SVCPARAM:
+ return sldns_wire2str_svcparam_scan(d, dlen, s, slen);
case LDNS_RDF_TYPE_TSIGERROR:
return sldns_wire2str_tsigerror_scan(d, dlen, s, slen);
}
int sldns_wire2str_dname_buf(uint8_t* dname, size_t dname_len, char* str,
size_t len);
+/**
+ * Convert wire SVCB to a string with user buffer.
+ * @param d: the SVCB data in uncompressed wireformat.
+ * @param dlen: length of the SVCB data.
+ * @param s: the string to write to.
+ * @param slen: length of string.
+ * @return the number of characters for this element, excluding zerobyte.
+ * Is larger or equal than str_len if output was truncated.
+ */
+int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s,
+ size_t* slen);
+
/**
* Scan wireformat rdf field to string, with user buffers.
* It shifts the arguments to move along (see sldns_wire2str_pkt_scan).
/*
- * checkconf/unbound-checkconf.c - config file checker for unbound.conf file.
+ * smallapp/unbound-checkconf.c - config file checker for unbound.conf file.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
{
int is_rpz = 0;
struct auth_zones* az = auth_zones_create();
- if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz)) {
+ if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL)) {
fatal_exit("Could not setup authority zones");
}
auth_zones_delete(az);
/*
- * checkconf/unbound-control.c - remote control utility for unbound.
+ * smallapp/unbound-control.c - remote control utility for unbound.
*
* Copyright (c) 2008, NLnet Labs. All rights reserved.
*
#include "sldns/wire2str.h"
#include "sldns/pkthdr.h"
#include "services/rpz.h"
+#include "services/listen_dnsport.h"
#ifdef HAVE_SYS_IPC_H
#include "sys/ipc.h"
{
#ifndef S_SPLINT_S
size_t leftover;
- if(d == 0) {
+ if(d <= 0) {
avg->tv_sec = 0;
avg->tv_usec = 0;
return;
avg->tv_usec = sum->tv_usec / d;
/* handle fraction from seconds divide */
leftover = sum->tv_sec - avg->tv_sec*d;
- avg->tv_usec += (leftover*1000000)/d;
+ if(leftover <= 0)
+ leftover = 0;
+ avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
+ if(avg->tv_sec < 0)
+ avg->tv_sec = 0;
+ if(avg->tv_usec < 0)
+ avg->tv_usec = 0;
#endif
}
{
unsigned long err;
err = ERR_peek_error();
- if (ERR_GET_LIB(err) == ERR_LIB_SYS &&
- (ERR_GET_FUNC(err) == SYS_F_FOPEN ||
- ERR_GET_FUNC(err) == SYS_F_FREAD) ) {
+ if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
fprintf(stderr, "error: %s\n%s: %s\n",
s, path, ERR_reason_error_string(err));
exit(1);
socklen_t addrlen;
int addrfamily = 0, proto = IPPROTO_TCP;
int fd, useport = 1;
+ char** rcif = NULL;
+ int num_rcif = 0;
/* use svr or the first config entry */
if(!svr) {
if(cfg->control_ifs.first) {
- svr = cfg->control_ifs.first->str;
+ struct sockaddr_storage addr2;
+ socklen_t addrlen2;
+ if(extstrtoaddr(cfg->control_ifs.first->str, &addr2,
+ &addrlen2)) {
+ svr = cfg->control_ifs.first->str;
+ } else {
+ if(!resolve_interface_names(NULL, 0,
+ cfg->control_ifs.first, &rcif,
+ &num_rcif)) {
+ fatal_exit("could not resolve interface names");
+ }
+ if(rcif == NULL || num_rcif == 0) {
+ fatal_exit("no control interfaces");
+ }
+ svr = rcif[0];
+ }
} else if(cfg->do_ip4) {
svr = "127.0.0.1";
} else {
break;
}
fd_set_block(fd);
+ config_del_strarray(rcif, num_rcif);
return fd;
}
/*
- * checkconf/unbound-host.c - replacement for host that supports validation.
+ * smallapp/unbound-host.c - replacement for host that supports validation.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
/*
- * checkconf/worker_cb.c - fake callback routines to make fptr_wlist work
+ * smallapp/worker_cb.c - fake callback routines to make fptr_wlist work
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
return 0;
}
-int worker_handle_reply(struct comm_point* ATTR_UNUSED(c),
- void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
- struct comm_reply* ATTR_UNUSED(reply_info))
-{
- log_assert(0);
- return 0;
-}
-
int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
return 0;
}
-int libworker_handle_reply(struct comm_point* ATTR_UNUSED(c),
- void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
- struct comm_reply* ATTR_UNUSED(reply_info))
-{
- log_assert(0);
- return 0;
-}
-
int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
cfg->do_ip6 = 1;
cfg->do_udp = 1;
cfg->do_tcp = 1;
+ cfg->tcp_reuse_timeout = 60 * 1000; /* 60s in milisecs */
+ cfg->max_reuse_tcp_queries = 200;
cfg->tcp_upstream = 0;
cfg->udp_upstream_without_downstream = 0;
cfg->tcp_mss = 0;
cfg->outgoing_tcp_mss = 0;
cfg->tcp_idle_timeout = 30 * 1000; /* 30s in millisecs */
+ cfg->tcp_auth_query_timeout = 3 * 1000; /* 3s in millisecs */
cfg->do_tcp_keepalive = 0;
cfg->tcp_keepalive_timeout = 120 * 1000; /* 120s in millisecs */
cfg->ssl_service_key = NULL;
cfg->hide_identity = 0;
cfg->hide_version = 0;
cfg->hide_trustanchor = 0;
+ cfg->hide_http_user_agent = 0;
cfg->identity = NULL;
cfg->version = NULL;
+ cfg->http_user_agent = NULL;
cfg->nsid_cfg_str = NULL;
cfg->nsid = NULL;
cfg->nsid_len = 0;
cfg->val_date_override = 0;
cfg->val_sig_skew_min = 3600; /* at least daylight savings trouble */
cfg->val_sig_skew_max = 86400; /* at most timezone settings trouble */
+ cfg->val_max_restart = 5;
cfg->val_clean_additional = 1;
cfg->val_log_level = 0;
cfg->val_log_squelch = 0;
cfg->serve_expired_reply_ttl = 30;
cfg->serve_expired_client_timeout = 0;
cfg->serve_original_ttl = 0;
+ cfg->zonemd_permissive_mode = 0;
cfg->add_holddown = 30*24*3600;
cfg->del_holddown = 30*24*3600;
cfg->keep_missing = 366*24*3600; /* one year plus a little leeway */
if(!(cfg->module_conf = strdup("validator iterator"))) goto error_exit;
#endif
if(!(cfg->val_nsec3_key_iterations =
- strdup("1024 150 2048 500 4096 2500"))) goto error_exit;
+ strdup("1024 150 2048 150 4096 150"))) goto error_exit;
#if defined(DNSTAP_SOCKET_PATH)
if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH)))
goto error_exit;
udp_upstream_without_downstream)
else S_NUMBER_NONZERO("tcp-mss:", tcp_mss)
else S_NUMBER_NONZERO("outgoing-tcp-mss:", outgoing_tcp_mss)
+ else S_NUMBER_NONZERO("tcp-auth-query-timeout:", tcp_auth_query_timeout)
else S_NUMBER_NONZERO("tcp-idle-timeout:", tcp_idle_timeout)
+ else S_NUMBER_NONZERO("max-reuse-tcp-queries:", max_reuse_tcp_queries)
+ else S_NUMBER_NONZERO("tcp-reuse-timeout:", tcp_reuse_timeout)
else S_YNO("edns-tcp-keepalive:", do_tcp_keepalive)
else S_NUMBER_NONZERO("edns-tcp-keepalive-timeout:", tcp_keepalive_timeout)
else S_YNO("ssl-upstream:", ssl_upstream)
else S_YNO("hide-identity:", hide_identity)
else S_YNO("hide-version:", hide_version)
else S_YNO("hide-trustanchor:", hide_trustanchor)
+ else S_YNO("hide-http-user-agent:", hide_http_user_agent)
else S_STR("identity:", identity)
else S_STR("version:", version)
+ else S_STR("http-user-agent:", http_user_agent)
else if(strcmp(opt, "nsid:") == 0) {
free(cfg->nsid_cfg_str);
if (!(cfg->nsid_cfg_str = strdup(val)))
else S_NUMBER_OR_ZERO("serve-expired-client-timeout:", serve_expired_client_timeout)
else S_YNO("serve-original-ttl:", serve_original_ttl)
else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations)
+ else S_YNO("zonemd-permissive-mode:", zonemd_permissive_mode)
else S_UNSIGNED_OR_ZERO("add-holddown:", add_holddown)
else S_UNSIGNED_OR_ZERO("del-holddown:", del_holddown)
else S_UNSIGNED_OR_ZERO("keep-missing:", keep_missing)
#endif
else if(strcmp(opt, "define-tag:") ==0) {
return config_add_tag(cfg, val);
- /* val_sig_skew_min and max are copied into val_env during init,
- * so this does not update val_env with set_option */
+ /* val_sig_skew_min, max and val_max_restart are copied into val_env
+ * during init so this does not update val_env with set_option */
} else if(strcmp(opt, "val-sig-skew-min:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->val_sig_skew_min = (int32_t)atoi(val); }
else if(strcmp(opt, "val-sig-skew-max:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->val_sig_skew_max = (int32_t)atoi(val); }
+ else if(strcmp(opt, "val-max-restart:") == 0)
+ { IS_NUMBER_OR_ZERO; cfg->val_max_restart = (int32_t)atoi(val); }
else if (strcmp(opt, "outgoing-interface:") == 0) {
char* d = strdup(val);
char** oi =
else O_YNO(opt, "udp-upstream-without-downstream", udp_upstream_without_downstream)
else O_DEC(opt, "tcp-mss", tcp_mss)
else O_DEC(opt, "outgoing-tcp-mss", outgoing_tcp_mss)
+ else O_DEC(opt, "tcp-auth-query-timeout", tcp_auth_query_timeout)
else O_DEC(opt, "tcp-idle-timeout", tcp_idle_timeout)
+ else O_DEC(opt, "max-reuse-tcp-queries", max_reuse_tcp_queries)
+ else O_DEC(opt, "tcp-reuse-timeout", tcp_reuse_timeout)
else O_YNO(opt, "edns-tcp-keepalive", do_tcp_keepalive)
else O_DEC(opt, "edns-tcp-keepalive-timeout", tcp_keepalive_timeout)
else O_YNO(opt, "ssl-upstream", ssl_upstream)
else O_YNO(opt, "hide-identity", hide_identity)
else O_YNO(opt, "hide-version", hide_version)
else O_YNO(opt, "hide-trustanchor", hide_trustanchor)
+ else O_YNO(opt, "hide-http-user-agent", hide_http_user_agent)
else O_STR(opt, "identity", identity)
else O_STR(opt, "version", version)
+ else O_STR(opt, "http-user-agent", http_user_agent)
else O_STR(opt, "nsid", nsid_cfg_str)
else O_STR(opt, "target-fetch-policy", target_fetch_policy)
else O_YNO(opt, "harden-short-bufsize", harden_short_bufsize)
else O_DEC(opt, "serve-expired-client-timeout", serve_expired_client_timeout)
else O_YNO(opt, "serve-original-ttl", serve_original_ttl)
else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations)
+ else O_YNO(opt, "zonemd-permissive-mode", zonemd_permissive_mode)
else O_UNS(opt, "add-holddown", add_holddown)
else O_UNS(opt, "del-holddown", del_holddown)
else O_UNS(opt, "keep-missing", keep_missing)
else O_DEC(opt, "fast-server-permil", fast_server_permil)
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
+ else O_DEC(opt, "val-max-restart", val_max_restart)
else O_YNO(opt, "qname-minimisation", qname_minimisation)
else O_YNO(opt, "qname-minimisation-strict", qname_minimisation_strict)
else O_IFC(opt, "define-tag", num_tags, tagname)
#endif
free(cfg->identity);
free(cfg->version);
+ free(cfg->http_user_agent);
free(cfg->nsid_cfg_str);
free(cfg->nsid);
free(cfg->module_conf);
return num;
}
+void cfg_apply_local_port_policy(struct config_file* cfg, int num) {
+(void)cfg;
+(void)num;
+#ifdef USE_LINUX_IP_LOCAL_PORT_RANGE
+ {
+ int i = 0;
+ FILE* range_fd;
+ if ((range_fd = fopen(LINUX_IP_LOCAL_PORT_RANGE_PATH, "r")) != NULL) {
+ int min_port = 0;
+ int max_port = num - 1;
+ if (fscanf(range_fd, "%d %d", &min_port, &max_port) == 2) {
+ for(i=0; i<min_port; i++) {
+ cfg->outgoing_avail_ports[i] = 0;
+ }
+ for(i=max_port+1; i<num; i++) {
+ cfg->outgoing_avail_ports[i] = 0;
+ }
+ } else {
+ log_err("unexpected port range in %s",
+ LINUX_IP_LOCAL_PORT_RANGE_PATH);
+ }
+ fclose(range_fd);
+ } else {
+ log_err("failed to read from file: %s (%s)",
+ LINUX_IP_LOCAL_PORT_RANGE_PATH,
+ strerror(errno));
+ }
+ }
+#endif
+}
+
/** print error with file and line number */
static void ub_c_error_va_list(const char *fmt, va_list args)
{
return (cfg->control_ifs.first->str[0] != '/');
}
+/** see if interface is https, its port number == the https port number */
+int
+if_is_https(const char* ifname, const char* port, int https_port)
+{
+ char* p = strchr(ifname, '@');
+ if(!p && atoi(port) == https_port)
+ return 1;
+ if(p && atoi(p+1) == https_port)
+ return 1;
+ return 0;
+}
+
+/** see if config contains https turned on */
+int cfg_has_https(struct config_file* cfg)
+{
+ int i;
+ char portbuf[32];
+ snprintf(portbuf, sizeof(portbuf), "%d", cfg->port);
+ for(i = 0; i<cfg->num_ifs; i++) {
+ if(if_is_https(cfg->ifs[i], portbuf, cfg->https_port))
+ return 1;
+ }
+ return 0;
+}
int do_udp;
/** do tcp query support. */
int do_tcp;
+ /** max number of queries on a reuse connection. */
+ size_t max_reuse_tcp_queries;
+ /** timeout for REUSE entries in milliseconds. */
+ int tcp_reuse_timeout;
+ /** timeout in milliseconds for TCP queries to auth servers. */
+ int tcp_auth_query_timeout;
/** tcp upstream queries (no UDP upstream queries) */
int tcp_upstream;
/** udp upstream enabled when no UDP downstream is enabled (do_udp no)*/
int hide_version;
/** do not report trustanchor (trustanchor.unbound) */
int hide_trustanchor;
+ /** do not report the User-Agent HTTP header */
+ int hide_http_user_agent;
/** identity, hostname is returned if "". */
char* identity;
/** version, package version returned if "". */
char* version;
+ /** User-Agent for HTTP header */
+ char* http_user_agent;
/** nsid */
char *nsid_cfg_str;
uint8_t *nsid;
int32_t val_sig_skew_min;
/** the maximum for signature clock skew */
int32_t val_sig_skew_max;
+ /** max number of query restarts, number of IPs to probe */
+ int32_t val_max_restart;
/** this value sets the number of seconds before revalidating bogus */
int bogus_ttl;
/** should validator clean additional section for secure msgs */
int serve_original_ttl;
/** nsec3 maximum iterations per key size, string */
char* val_nsec3_key_iterations;
+ /** if zonemd failures are permitted, only logged */
+ int zonemd_permissive_mode;
/** autotrust add holddown time, in seconds */
unsigned int add_holddown;
/** autotrust del holddown time, in seconds */
/** Always reply with this CNAME target if the cname override action is
* used */
char* rpz_cname;
+ /** Check ZONEMD records for this zone */
+ int zonemd_check;
+ /** Reject absence of ZONEMD records, zone must have one */
+ int zonemd_reject_absence;
};
/**
*/
int cfg_condense_ports(struct config_file* cfg, int** avail);
+/**
+ * Apply system specific port range policy.
+ * @param cfg: config file.
+ * @param num: size of the array (65536).
+ */
+void cfg_apply_local_port_policy(struct config_file* cfg, int num);
+
/**
* Scan ports available
* @param avail: the array from cfg.
/** debug option for unit tests. */
extern int fake_dsa, fake_sha1;
+/** see if interface is https, its port number == the https port number */
+int if_is_https(const char* ifname, const char* port, int https_port);
+
+/**
+ * Return true if the config contains settings that enable https.
+ * @param cfg: config information.
+ * @return true if https ports are used for server.
+ */
+int cfg_has_https(struct config_file* cfg);
+
+#ifdef USE_LINUX_IP_LOCAL_PORT_RANGE
+#define LINUX_IP_LOCAL_PORT_RANGE_PATH "/proc/sys/net/ipv4/ip_local_port_range"
+#endif
+
#endif /* UTIL_CONFIG_FILE_H */
tcp-mss{COLON} { YDVAR(1, VAR_TCP_MSS) }
outgoing-tcp-mss{COLON} { YDVAR(1, VAR_OUTGOING_TCP_MSS) }
tcp-idle-timeout{COLON} { YDVAR(1, VAR_TCP_IDLE_TIMEOUT) }
+max-reuse-tcp-queries{COLON} { YDVAR(1, VAR_MAX_REUSE_TCP_QUERIES) }
+tcp-reuse-timeout{COLON} { YDVAR(1, VAR_TCP_REUSE_TIMEOUT) }
+tcp-auth-query-timeout{COLON} { YDVAR(1, VAR_TCP_AUTH_QUERY_TIMEOUT) }
edns-tcp-keepalive{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE) }
edns-tcp-keepalive-timeout{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE_TIMEOUT) }
ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
hide-identity{COLON} { YDVAR(1, VAR_HIDE_IDENTITY) }
hide-version{COLON} { YDVAR(1, VAR_HIDE_VERSION) }
hide-trustanchor{COLON} { YDVAR(1, VAR_HIDE_TRUSTANCHOR) }
+hide-http-user-agent{COLON} { YDVAR(1, VAR_HIDE_HTTP_USER_AGENT) }
identity{COLON} { YDVAR(1, VAR_IDENTITY) }
version{COLON} { YDVAR(1, VAR_VERSION) }
+http-user-agent{COLON} { YDVAR(1, VAR_HTTP_USER_AGENT) }
module-config{COLON} { YDVAR(1, VAR_MODULE_CONF) }
dlv-anchor{COLON} { YDVAR(1, VAR_DLV_ANCHOR) }
dlv-anchor-file{COLON} { YDVAR(1, VAR_DLV_ANCHOR_FILE) }
val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) }
val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) }
val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }
+val-max-restart{COLON} { YDVAR(1, VAR_VAL_MAX_RESTART) }
val-bogus-ttl{COLON} { YDVAR(1, VAR_BOGUS_TTL) }
val-clean-additional{COLON} { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) }
val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) }
neg-cache-size{COLON} { YDVAR(1, VAR_NEG_CACHE_SIZE) }
val-nsec3-keysize-iterations{COLON} {
YDVAR(1, VAR_VAL_NSEC3_KEYSIZE_ITERATIONS) }
+zonemd-permissive-mode{COLON} { YDVAR(1, VAR_ZONEMD_PERMISSIVE_MODE) }
+zonemd-check{COLON} { YDVAR(1, VAR_ZONEMD_CHECK) }
+zonemd-reject-absence{COLON} { YDVAR(1, VAR_ZONEMD_REJECT_ABSENCE) }
add-holddown{COLON} { YDVAR(1, VAR_ADD_HOLDDOWN) }
del-holddown{COLON} { YDVAR(1, VAR_DEL_HOLDDOWN) }
keep-missing{COLON} { YDVAR(1, VAR_KEEP_MISSING) }
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
-%token VAR_CONTROL_USE_CERT
+%token VAR_CONTROL_USE_CERT VAR_TCP_REUSE_TIMEOUT VAR_MAX_REUSE_TCP_QUERIES
%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
-%token VAR_VAL_SIG_SKEW_MAX VAR_CACHE_MIN_TTL VAR_VAL_LOG_LEVEL
-%token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN
-%token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
-%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN
-%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES VAR_LOG_LOCAL_ACTIONS
-%token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
-%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
+%token VAR_VAL_SIG_SKEW_MAX VAR_VAL_MAX_RESTART VAR_CACHE_MIN_TTL
+%token VAR_VAL_LOG_LEVEL VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING
+%token VAR_ADD_HOLDDOWN VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE
+%token VAR_PREFETCH VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT
+%token VAR_HARDEN_BELOW_NXDOMAIN VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES
+%token VAR_LOG_REPLIES VAR_LOG_LOCAL_ACTIONS VAR_TCP_UPSTREAM
+%token VAR_SSL_UPSTREAM VAR_TCP_AUTH_QUERY_TIMEOUT VAR_SSL_SERVICE_KEY
+%token VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE
%token VAR_HTTPS_PORT VAR_HTTP_ENDPOINT VAR_HTTP_MAX_STREAMS
%token VAR_HTTP_QUERY_BUFFER_SIZE VAR_HTTP_RESPONSE_BUFFER_SIZE
%token VAR_SERVE_EXPIRED_TTL_RESET VAR_SERVE_EXPIRED_REPLY_TTL
%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_SERVE_ORIGINAL_TTL VAR_FAKE_DSA
%token VAR_FAKE_SHA1 VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR
+%token VAR_HIDE_HTTP_USER_AGENT VAR_HTTP_USER_AGENT
%token VAR_TRUST_ANCHOR_SIGNALING VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD
%token VAR_SHM_ENABLE VAR_SHM_KEY VAR_ROOT_KEY_SENTINEL
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
+%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_harden_short_bufsize | server_harden_large_queries |
server_do_not_query_address | server_hide_identity |
server_hide_version | server_identity | server_version |
+ server_hide_http_user_agent | server_http_user_agent |
server_harden_glue | server_module_conf | server_trust_anchor_file |
server_trust_anchor | server_val_override_date | server_bogus_ttl |
server_val_clean_additional | server_val_permissive_mode |
server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min |
- server_val_sig_skew_max | server_cache_min_ttl | server_val_log_level |
- server_auto_trust_anchor_file | server_add_holddown |
+ server_val_sig_skew_max | server_val_max_restart |
+ server_cache_min_ttl | server_val_log_level |
+ server_auto_trust_anchor_file | server_add_holddown |
server_del_holddown | server_keep_missing | server_so_rcvbuf |
server_edns_buffer_size | server_prefetch | server_prefetch_key |
server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
server_stream_wait_size | server_tls_ciphers |
server_tls_ciphersuites | server_tls_session_ticket_keys |
server_tls_use_sni | server_edns_client_string |
- server_edns_client_string_opcode | server_nsid
+ server_edns_client_string_opcode | server_nsid |
+ server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
+ server_tcp_reuse_timeout | server_tcp_auth_query_timeout
+
;
stubstart: VAR_STUB_ZONE
{
s->for_downstream = 1;
s->for_upstream = 1;
s->fallback_enabled = 0;
+ s->zonemd_check = 0;
+ s->zonemd_reject_absence = 0;
s->isrpz = 0;
} else
yyerror("out of memory");
| ;
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
- auth_allow_notify
+ auth_allow_notify | auth_zonemd_check | auth_zonemd_reject_absence
;
rpz_tag: VAR_TAGS STRING_ARG
free($2);
}
;
+server_max_reuse_tcp_queries: VAR_MAX_REUSE_TCP_QUERIES STRING_ARG
+ {
+ OUTYY(("P(server_max_reuse_tcp_queries:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else if (atoi($2) < 1)
+ cfg_parser->cfg->max_reuse_tcp_queries = 0;
+ else cfg_parser->cfg->max_reuse_tcp_queries = atoi($2);
+ free($2);
+ }
+ ;
+server_tcp_reuse_timeout: VAR_TCP_REUSE_TIMEOUT STRING_ARG
+ {
+ OUTYY(("P(server_tcp_reuse_timeout:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else if (atoi($2) < 1)
+ cfg_parser->cfg->tcp_reuse_timeout = 0;
+ else cfg_parser->cfg->tcp_reuse_timeout = atoi($2);
+ free($2);
+ }
+ ;
+server_tcp_auth_query_timeout: VAR_TCP_AUTH_QUERY_TIMEOUT STRING_ARG
+ {
+ OUTYY(("P(server_tcp_auth_query_timeout:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else if (atoi($2) < 1)
+ cfg_parser->cfg->tcp_auth_query_timeout = 0;
+ else cfg_parser->cfg->tcp_auth_query_timeout = atoi($2);
+ free($2);
+ }
+ ;
server_tcp_keepalive: VAR_EDNS_TCP_KEEPALIVE STRING_ARG
{
OUTYY(("P(server_tcp_keepalive:%s)\n", $2));
free($2);
}
;
+server_hide_http_user_agent: VAR_HIDE_HTTP_USER_AGENT STRING_ARG
+ {
+ OUTYY(("P(server_hide_user_agent:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->hide_http_user_agent = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_identity: VAR_IDENTITY STRING_ARG
{
OUTYY(("P(server_identity:%s)\n", $2));
cfg_parser->cfg->version = $2;
}
;
+server_http_user_agent: VAR_HTTP_USER_AGENT STRING_ARG
+ {
+ OUTYY(("P(server_http_user_agent:%s)\n", $2));
+ free(cfg_parser->cfg->http_user_agent);
+ cfg_parser->cfg->http_user_agent = $2;
+ }
+ ;
server_nsid: VAR_NSID STRING_ARG
{
OUTYY(("P(server_nsid:%s)\n", $2));
free($2);
}
;
+server_val_max_restart: VAR_VAL_MAX_RESTART STRING_ARG
+ {
+ OUTYY(("P(server_val_max_restart:%s)\n", $2));
+ if(*$2 == '\0' || strcmp($2, "0") == 0) {
+ cfg_parser->cfg->val_max_restart = 0;
+ } else {
+ cfg_parser->cfg->val_max_restart = atoi($2);
+ if(!cfg_parser->cfg->val_max_restart)
+ yyerror("number expected");
+ }
+ free($2);
+ }
+ ;
server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG
{
OUTYY(("P(server_cache_max_ttl:%s)\n", $2));
cfg_parser->cfg->val_nsec3_key_iterations = $2;
}
;
+server_zonemd_permissive_mode: VAR_ZONEMD_PERMISSIVE_MODE STRING_ARG
+ {
+ OUTYY(("P(server_zonemd_permissive_mode:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->zonemd_permissive_mode = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG
{
OUTYY(("P(server_add_holddown:%s)\n", $2));
yyerror("out of memory");
}
;
+auth_zonemd_check: VAR_ZONEMD_CHECK STRING_ARG
+ {
+ OUTYY(("P(zonemd-check:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->auths->zonemd_check =
+ (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
+auth_zonemd_reject_absence: VAR_ZONEMD_REJECT_ABSENCE STRING_ARG
+ {
+ OUTYY(("P(zonemd-reject-absence:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->auths->zonemd_reject_absence =
+ (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG
{
OUTYY(("P(for-downstream:%s)\n", $2));
&& strcmp($3, "always_transparent")!=0
&& strcmp($3, "always_refuse")!=0
&& strcmp($3, "always_nxdomain")!=0
+ && strcmp($3, "always_nodata")!=0
+ && strcmp($3, "always_deny")!=0
+ && strcmp($3, "always_null")!=0
&& strcmp($3, "noview")!=0
- && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) {
+ && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
+ && strcmp($3, "inform_redirect") != 0
+ && strcmp($3, "ipset") != 0) {
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
- "always_transparent, always_refuse, "
- "always_nxdomain, noview or nodefault");
+ "inform_redirect, always_transparent, "
+ "always_refuse, always_nxdomain, "
+ "always_nodata, always_deny, always_null, "
+ "noview, nodefault or ipset");
free($2);
free($3);
} else if(strcmp($3, "nodefault")==0) {
* Snip off first label from a dname, returning the parent zone.
* @param dname: from what to strip off. uncompressed wireformat.
* @param len: length, adjusted to become less.
- * @return stripped off, or "." if input was ".".
+ * return stripped off, or "." if input was ".".
*/
void dname_remove_label(uint8_t** dname, size_t* len);
* @param len: length, adjusted to become less.
* @param n: number of labels to strip off (from the left).
* if 0, nothing happens.
- * @return stripped off, or "." if input was ".".
+ * return stripped off, or "." if input was ".".
*/
void dname_remove_labels(uint8_t** dname, size_t* len, int n);
return 0;
/* copy & decompress */
if(!parse_rr_copy(pkt, pset, *data)) {
- if(!region) free(*data);
+ if(!region) {
+ free(*data);
+ *data = NULL;
+ }
return 0;
}
return 1;
pk->rk.type = htons(pset->type);
pk->rk.rrset_class = pset->rrset_class;
/** read data part. */
- if(!parse_create_rrset(pkt, pset, &data, region))
+ if(!parse_create_rrset(pkt, pset, &data, region)) {
+ if(!region) {
+ free(pk->rk.dname);
+ pk->rk.dname = NULL;
+ }
return 0;
+ }
pk->entry.data = (void*)data;
pk->entry.key = (void*)pk;
pk->entry.hash = pset->hash;
/* not particularly fast but flexible, make wireformat and print */
sldns_buffer* buf = sldns_buffer_new(65535);
struct regional* region = regional_create();
- if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0,
+ if(!(buf && region)) {
+ log_err("%s: log_dns_msg: out of memory", str);
+ sldns_buffer_free(buf);
+ regional_destroy(region);
+ return;
+ }
+ if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0,
region, 65535, 1, 0)) {
- log_info("%s: log_dns_msg: out of memory", str);
+ log_err("%s: log_dns_msg: out of memory", str);
} else {
char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
sldns_buffer_limit(buf));
fptr_whitelist_pending_udp(comm_point_callback_type *fptr)
{
if(fptr == &serviced_udp_callback) return 1;
- else if(fptr == &worker_handle_reply) return 1;
- else if(fptr == &libworker_handle_reply) return 1;
return 0;
}
fptr_whitelist_pending_tcp(comm_point_callback_type *fptr)
{
if(fptr == &serviced_tcp_callback) return 1;
- else if(fptr == &worker_handle_reply) return 1;
- else if(fptr == &libworker_handle_reply) return 1;
return 0;
}
else if(fptr == &probe_answer_cb) return 1;
else if(fptr == &auth_xfer_probe_lookup_callback) return 1;
else if(fptr == &auth_xfer_transfer_lookup_callback) return 1;
+ else if(fptr == &auth_zonemd_dnskey_lookup_callback) return 1;
return 0;
}
140,
141,
142,
-143,
144,
145,
146,
990,
991,
992,
-993,
995,
996,
997,
5504,
5505,
5506,
+5540,
5553,
5554,
5555,
8006,
8007,
8008,
+8017,
8019,
8020,
8021,
30999,
31016,
31029,
+31337,
31416,
31457,
31620,
}
#endif /* HAVE_SSL */
-#if defined(HAVE_SSL) && defined(HAVE_NGHTTP2)
+#if defined(HAVE_SSL) && defined(HAVE_NGHTTP2) && defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out,
unsigned char* outlen, const unsigned char* in, unsigned int inlen,
void* ATTR_UNUSED(arg))
{
closesocket(socket);
}
-
# endif /* USE_WINSOCK */
#ifndef NET_HELP_H
#define NET_HELP_H
#include "util/log.h"
+#include "util/random.h"
struct sock_list;
struct regional;
struct config_strlist;
/** timeout in milliseconds for UDP queries to auth servers. */
#define UDP_AUTH_QUERY_TIMEOUT 3000
-/** timeout in milliseconds for TCP queries to auth servers. */
-#define TCP_AUTH_QUERY_TIMEOUT 3000
/** Advertised version of EDNS capabilities */
#define EDNS_ADVERTISED_VERSION 0
/** Advertised size of EDNS capabilities */
/** DNSKEY secure entry point, KSK flag */
#define DNSKEY_BIT_SEP 0x0001
+/** return a random 16-bit number given a random source */
+#define GET_RANDOM_ID(rnd) (((unsigned)ub_random(rnd)>>8) & 0xffff)
+
/** minimal responses when positive answer */
extern int MINIMAL_RESPONSES;
#include "dnstap/dnstap.h"
#include "dnscrypt/dnscrypt.h"
#include "services/listen_dnsport.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
static struct comm_point* comm_point_create_tcp_handler(
struct comm_base *base, struct comm_point* parent, size_t bufsize,
struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
- void* callback_arg);
+ void* callback_arg, struct unbound_socket* socket);
/* -------- End of local definitions -------- */
# ifdef ENETDOWN
case ENETDOWN:
# endif
+ case EPERM:
if(verbosity < VERB_ALGO)
return 0;
default:
/* 'Cannot assign requested address' also when disconnected */
|| (errno == EADDRNOTAVAIL)
# endif
- ) && verbosity < VERB_DETAIL)
+ ) && verbosity < VERB_ALGO)
return 0;
# ifdef EADDRINUSE
/* If SO_REUSEADDR is set, we could try to connect to the same server
log_info("%s: unknown srctype %d", str, r->srctype);
return;
}
+
if(r->srctype == 6) {
+#ifdef IPV6_PKTINFO
char buf[1024];
if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr,
buf, (socklen_t)sizeof(buf)) == 0) {
}
buf[sizeof(buf)-1]=0;
log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
+#endif
} else if(r->srctype == 4) {
#ifdef IP_PKTINFO
char buf1[1024], buf2[1024];
int r;
if(c->ssl_shake_state == comm_ssl_shake_hs_read) {
/* read condition satisfied back to writing */
- comm_point_listen_for_rw(c, 1, 1);
+ comm_point_listen_for_rw(c, 0, 1);
c->ssl_shake_state = comm_ssl_shake_none;
return 1;
}
if((SSL_get_verify_mode(c->ssl)&SSL_VERIFY_PEER)) {
/* verification */
if(SSL_get_verify_result(c->ssl) == X509_V_OK) {
+#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
+ X509* x = SSL_get1_peer_certificate(c->ssl);
+#else
X509* x = SSL_get_peer_certificate(c->ssl);
+#endif
if(!x) {
log_addr(VERB_ALGO, "SSL connection failed: "
"no certificate",
#endif
X509_free(x);
} else {
+#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
+ X509* x = SSL_get1_peer_certificate(c->ssl);
+#else
X509* x = SSL_get_peer_certificate(c->ssl);
+#endif
if(x) {
log_cert(VERB_ALGO, "peer certificate", x);
X509_free(x);
c->repinfo.addrlen);
}
+#ifdef HAVE_SSL_GET0_ALPN_SELECTED
/* check if http2 use is negotiated */
if(c->type == comm_http && c->h2_session) {
const unsigned char *alpn;
c->use_h2 = 1;
}
}
+#endif
/* setup listen rw correctly */
if(c->tcp_is_reading) {
if(c->ssl_shake_state != comm_ssl_shake_read)
comm_point_listen_for_rw(c, 1, 0);
} else {
- comm_point_listen_for_rw(c, 1, 1);
+ comm_point_listen_for_rw(c, 0, 1);
}
c->ssl_shake_state = comm_ssl_shake_none;
return 1;
return tcp_req_info_handle_read_close(c->tcp_req_info);
return 0; /* shutdown, closed */
} else if(want == SSL_ERROR_WANT_READ) {
+#ifdef USE_WINSOCK
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
+#endif
return 1; /* read more later */
} else if(want == SSL_ERROR_WANT_WRITE) {
c->ssl_shake_state = comm_ssl_shake_hs_write;
return tcp_req_info_handle_read_close(c->tcp_req_info);
return 0; /* shutdown, closed */
} else if(want == SSL_ERROR_WANT_READ) {
+#ifdef USE_WINSOCK
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
+#endif
return 1; /* read more later */
} else if(want == SSL_ERROR_WANT_WRITE) {
c->ssl_shake_state = comm_ssl_shake_hs_write;
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
+#ifdef USE_WINSOCK
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
+#endif
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef EPIPE
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
+#ifdef USE_WINSOCK
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
+#endif
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef EPIPE
if(errno == ECONNRESET && verbosity < 2)
return 0; /* silence reset by peer */
#endif
+#ifdef ECONNREFUSED
+ if(errno == ECONNREFUSED && verbosity < 2)
+ return 0; /* silence reset by peer */
+#endif
#ifdef ENETUNREACH
if(errno == ENETUNREACH && verbosity < 2)
return 0; /* silence it */
}
#endif
#else /* USE_WINSOCK */
+ if(WSAGetLastError() == WSAECONNREFUSED && verbosity < 2)
+ return 0;
+ if(WSAGetLastError() == WSAEHOSTDOWN && verbosity < 2)
+ return 0;
+ if(WSAGetLastError() == WSAEHOSTUNREACH && verbosity < 2)
+ return 0;
+ if(WSAGetLastError() == WSAENETDOWN && verbosity < 2)
+ return 0;
+ if(WSAGetLastError() == WSAENETUNREACH && verbosity < 2)
+ return 0;
if(WSAGetLastError() == WSAECONNRESET)
return 0;
if(WSAGetLastError() == WSAEINPROGRESS)
(int)sldns_buffer_limit(c->buffer));
}
- log_assert(sldns_buffer_remaining(c->buffer) > 0);
+ if(sldns_buffer_remaining(c->buffer) == 0)
+ log_err("in comm_point_tcp_handle_read buffer_remaining is not > 0 as expected, continuing with (harmless) 0 length recv");
r = recv(fd, (void*)sldns_buffer_current(c->buffer),
sldns_buffer_remaining(c->buffer), 0);
if(r == 0) {
log_crypto_err("could not SSL_read");
return 0;
}
+ verbose(VERB_ALGO, "ssl http read more skip to %d + %d",
+ (int)sldns_buffer_position(c->buffer), (int)r);
sldns_buffer_skip(c->buffer, (ssize_t)r);
return 1;
#else
&c->repinfo.addr, c->repinfo.addrlen);
return 0;
}
+ verbose(VERB_ALGO, "http read more skip to %d + %d",
+ (int)sldns_buffer_position(c->buffer), (int)r);
sldns_buffer_skip(c->buffer, r);
return 1;
}
return 1;
}
-/** handle nonchunked data segment */
+/** handle nonchunked data segment, 0=fail, 1=wait */
static int
http_nonchunk_segment(struct comm_point* c)
{
* we are looking to read tcp_byte_count more data
* and then the transfer is done. */
size_t remainbufferlen;
- size_t got_now = sldns_buffer_limit(c->buffer) - c->http_stored;
+ size_t got_now = sldns_buffer_limit(c->buffer);
if(c->tcp_byte_count <= got_now) {
/* done, this is the last data fragment */
c->http_stored = 0;
(void)(*c->callback)(c, c->cb_arg, NETEVENT_DONE, NULL);
return 1;
}
- c->tcp_byte_count -= got_now;
/* if we have the buffer space,
* read more data collected into the buffer */
remainbufferlen = sldns_buffer_capacity(c->buffer) -
sldns_buffer_limit(c->buffer);
- if(remainbufferlen >= c->tcp_byte_count ||
- remainbufferlen >= 2048) {
+ if(remainbufferlen+got_now >= c->tcp_byte_count ||
+ remainbufferlen >= (c->ssl?16384:2048)) {
size_t total = sldns_buffer_limit(c->buffer);
sldns_buffer_clear(c->buffer);
sldns_buffer_set_position(c->buffer, total);
}
/* call callback with this data amount, then
* wait for more */
+ c->tcp_byte_count -= got_now;
c->http_stored = 0;
sldns_buffer_set_position(c->buffer, 0);
fptr_ok(fptr_whitelist_comm_point(c->callback));
return 0;
}
+ if(c->http_stored >= sldns_buffer_position(c->buffer)) {
+ /* read did not work but we wanted more data, there is
+ * no bytes to process now. */
+ return 1;
+ }
sldns_buffer_flip(c->buffer);
/* if we are partway in a segment of data, position us at the point
* where we left off previously */
struct comm_point*
comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
- comm_point_callback_type* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
c->inuse = 0;
c->callback = callback;
c->cb_arg = callback_arg;
+ c->socket = socket;
evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
struct comm_point*
comm_point_create_udp_ancil(struct comm_base *base, int fd,
sldns_buffer* buffer,
- comm_point_callback_type* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
#endif
c->callback = callback;
c->cb_arg = callback_arg;
+ c->socket = socket;
evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_create_tcp_handler(struct comm_base *base,
struct comm_point* parent, size_t bufsize,
struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
- void* callback_arg)
+ void* callback_arg, struct unbound_socket* socket)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
+ c->socket = socket;
if(spoolbuf) {
c->tcp_req_info = tcp_req_info_create(spoolbuf);
if(!c->tcp_req_info) {
comm_point_create_http_handler(struct comm_base *base,
struct comm_point* parent, size_t bufsize, int harden_large_queries,
uint32_t http_max_streams, char* http_endpoint,
- comm_point_callback_type* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg,
+ struct unbound_socket* socket)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
+ c->socket = socket;
c->http_min_version = http_version_2;
c->http2_stream_max_qbuffer_size = bufsize;
uint32_t http_max_streams, char* http_endpoint,
struct tcl_list* tcp_conn_limit, size_t bufsize,
struct sldns_buffer* spoolbuf, enum listen_type port_type,
- comm_point_callback_type* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
#endif
c->callback = NULL;
c->cb_arg = NULL;
+ c->socket = socket;
evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
port_type == listen_type_ssl ||
port_type == listen_type_tcp_dnscrypt) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
- c, bufsize, spoolbuf, callback, callback_arg);
+ c, bufsize, spoolbuf, callback, callback_arg, socket);
} else if(port_type == listen_type_http) {
c->tcp_handlers[i] = comm_point_create_http_handler(
base, c, bufsize, harden_large_queries,
http_max_streams, http_endpoint,
- callback, callback_arg);
+ callback, callback_arg, socket);
}
else {
log_err("could not create tcp handler, unknown listen "
/* close fd after removing from event lists, or epoll.. is messed up */
if(c->fd != -1 && !c->do_not_close) {
+#ifdef USE_WINSOCK
if(c->type == comm_tcp || c->type == comm_http) {
/* delete sticky events for the fd, it gets closed */
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
}
+#endif
verbose(VERB_ALGO, "close fd %d", c->fd);
sock_close(c->fd);
}
comm_point_send_udp_msg(repinfo->c, buffer,
(struct sockaddr*)&repinfo->addr, repinfo->addrlen, 0);
#ifdef USE_DNSTAP
- if(repinfo->c->dtenv != NULL &&
- repinfo->c->dtenv->log_client_response_messages)
- dt_msg_send_client_response(repinfo->c->dtenv,
- &repinfo->addr, repinfo->c->type, repinfo->c->buffer);
+ /*
+ * sending src (client)/dst (local service) addresses over DNSTAP from udp callback
+ */
+ if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) {
+ log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+ log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
+ dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->buffer);
+ }
#endif
} else {
#ifdef USE_DNSTAP
- if(repinfo->c->tcp_parent->dtenv != NULL &&
- repinfo->c->tcp_parent->dtenv->log_client_response_messages)
- dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
- &repinfo->addr, repinfo->c->type,
- ( repinfo->c->tcp_req_info
- ? repinfo->c->tcp_req_info->spool_buffer
- : repinfo->c->buffer ));
+ /*
+ * sending src (client)/dst (local service) addresses over DNSTAP from TCP callback
+ */
+ if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) {
+ log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+ log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
+ dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type,
+ ( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer ));
+ }
#endif
if(repinfo->c->tcp_req_info) {
tcp_req_info_send_reply(repinfo->c->tcp_req_info);
struct comm_reply;
struct tcl_list;
struct ub_event_base;
+struct unbound_socket;
struct mesh_state;
struct mesh_area;
/** if the event is added or not */
int event_added;
+ struct unbound_socket* socket;
+
/** file descriptor for communication point */
int fd;
* @param buffer: shared buffer by UDP sockets from this thread.
* @param callback: callback function pointer.
* @param callback_arg: will be passed to your callback function.
+ * @param socket: and opened socket properties will be passed to your callback function.
* @return: returns the allocated communication point. NULL on error.
* Sets timeout to NULL. Turns off TCP options.
*/
struct comm_point* comm_point_create_udp(struct comm_base* base,
int fd, struct sldns_buffer* buffer,
- comm_point_callback_type* callback, void* callback_arg);
+ comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
/**
* Create an UDP with ancillary data comm point. Calls malloc.
* @param buffer: shared buffer by UDP sockets from this thread.
* @param callback: callback function pointer.
* @param callback_arg: will be passed to your callback function.
+ * @param socket: and opened socket properties will be passed to your callback function.
* @return: returns the allocated communication point. NULL on error.
* Sets timeout to NULL. Turns off TCP options.
*/
struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
int fd, struct sldns_buffer* buffer,
- comm_point_callback_type* callback, void* callback_arg);
+ comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
/**
* Create a TCP listener comm point. Calls malloc.
* to select handler type to use.
* @param callback: callback function pointer for TCP handlers.
* @param callback_arg: will be passed to your callback function.
+ * @param socket: and opened socket properties will be passed to your callback function.
* @return: returns the TCP listener commpoint. You can find the
* TCP handlers in the array inside the listener commpoint.
* returns NULL on error.
struct tcl_list* tcp_conn_limit,
size_t bufsize, struct sldns_buffer* spoolbuf,
enum listen_type port_type,
- comm_point_callback_type* callback, void* callback_arg);
+ comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
/**
* Create an outgoing TCP commpoint. No file descriptor is opened, left at -1.
/* Just release memory unused */
free(daemon->shm_info);
+ daemon->shm_info = NULL;
return 0;
}
/* Just release memory unused */
free(daemon->shm_info);
+ daemon->shm_info = NULL;
return 0;
}
/* Just release memory unused */
free(daemon->shm_info);
+ daemon->shm_info = NULL;
return 0;
}
/* Just release memory unused */
free(daemon->shm_info);
+ daemon->shm_info = NULL;
return 0;
}
if (daemon->shm_info->ptr_arr)
shmdt(daemon->shm_info->ptr_arr);
+ free(daemon->shm_info);
+ daemon->shm_info = NULL;
#else
(void)daemon;
#endif /* HAVE_SHMGET */
#include "util/storage/lookup3.h"
#include <stdio.h> /* defines printf for tests */
#include <time.h> /* defines time_t for timings in the test */
-/*#include <stdint.h> defines uint32_t etc (from config.h) */
-#include <sys/param.h> /* attempt to define endianness */
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h> /* attempt to define endianness (solaris) */
-#endif
-#if defined(linux) || defined(__OpenBSD__)
+
+/*
+ * If our build system provides endianness info, signalled by
+ * HAVE_TARGET_ENDIANNESS and the presence or absence of TARGET_IS_BIG_ENDIAN,
+ * use that. Otherwise try to work out the endianness.
+ */
+#if defined(HAVE_TARGET_ENDIANNESS)
+# if defined(TARGET_IS_BIG_ENDIAN)
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+# else
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+# endif
+#else
+# include <sys/param.h> /* attempt to define endianness */
+# ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* attempt to define endianness (solaris) */
+# endif
+# if defined(linux) || defined(__OpenBSD__)
# ifdef HAVE_ENDIAN_H
# include <endian.h> /* attempt to define endianness */
# else
# include <machine/endian.h> /* on older OpenBSD */
# endif
-#endif
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
-#include <sys/endian.h> /* attempt to define endianness */
-#endif
+# endif
+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+# include <sys/endian.h> /* attempt to define endianness */
+# endif
+ /*
+ * My best guess at if you are big-endian or little-endian. This may
+ * need adjustment.
+ */
+# if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+ __BYTE_ORDER == __LITTLE_ENDIAN) || \
+ (defined(i386) || defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL) || defined(__x86))
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+# elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+ __BYTE_ORDER == __BIG_ENDIAN) || \
+ (defined(sparc) || defined(__sparc) || defined(__sparc__) || defined(POWERPC) || defined(mc68000) || defined(sel))
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+# elif defined(_MACHINE_ENDIAN_H_)
+ /* test for machine_endian_h protects failure if some are empty strings */
+# if defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+# endif
+# if defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+# endif /* _MACHINE_ENDIAN_H_ */
+# else
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 0
+# endif
+#endif /* defined(HAVE_TARGET_ENDIANNESS) */
+
+#define hashsize(n) ((uint32_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/* random initial value */
static uint32_t raninit = (uint32_t)0xdeadbeef;
raninit = v;
}
-/*
- * My best guess at if you are big-endian or little-endian. This may
- * need adjustment.
- */
-#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
- __BYTE_ORDER == __LITTLE_ENDIAN) || \
- (defined(i386) || defined(__i386__) || defined(__i486__) || \
- defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL) || defined(__x86))
-# define HASH_LITTLE_ENDIAN 1
-# define HASH_BIG_ENDIAN 0
-#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
- __BYTE_ORDER == __BIG_ENDIAN) || \
- (defined(sparc) || defined(__sparc) || defined(__sparc__) || defined(POWERPC) || defined(mc68000) || defined(sel))
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 1
-#elif defined(_MACHINE_ENDIAN_H_)
-/* test for machine_endian_h protects failure if some are empty strings */
-# if defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 1
-# endif
-# if defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
-# define HASH_LITTLE_ENDIAN 1
-# define HASH_BIG_ENDIAN 0
-# endif /* _MACHINE_ENDIAN_H_ */
-#else
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 0
-#endif
-
-#define hashsize(n) ((uint32_t)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
-
/*
-------------------------------------------------------------------------------
mix -- mix 3 32-bit values reversibly.
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->winsock_tcp_wouldblock ==
my_winsock_tcp_wouldblock);
- (*ev->vmt->winsock_tcp_wouldblock)(ev, eventbits);
+ if (ev->vmt->winsock_tcp_wouldblock)
+ (*ev->vmt->winsock_tcp_wouldblock)(ev, eventbits);
}
}
return " UNKNOWN ";
}
+/** ctime r for autotrust */
+static char* autr_ctime_r(time_t* t, char* s)
+{
+ ctime_r(t, s);
+#ifdef USE_WINSOCK
+ if(strlen(s) > 10 && s[7]==' ' && s[8]=='0')
+ s[8]=' '; /* fix error in windows ctime */
+#endif
+ return s;
+}
+
/** print ID to file */
static int
print_id(FILE* out, char* fname, uint8_t* nm, size_t nmlen, uint16_t dclass)
}
if(fprintf(out, ";;last_queried: %u ;;%s",
(unsigned int)tp->autr->last_queried,
- ctime_r(&(tp->autr->last_queried), tmi)) < 0 ||
+ autr_ctime_r(&(tp->autr->last_queried), tmi)) < 0 ||
fprintf(out, ";;last_success: %u ;;%s",
(unsigned int)tp->autr->last_success,
- ctime_r(&(tp->autr->last_success), tmi)) < 0 ||
+ autr_ctime_r(&(tp->autr->last_success), tmi)) < 0 ||
fprintf(out, ";;next_probe_time: %u ;;%s",
(unsigned int)tp->autr->next_probe_time,
- ctime_r(&(tp->autr->next_probe_time), tmi)) < 0 ||
+ autr_ctime_r(&(tp->autr->next_probe_time), tmi)) < 0 ||
fprintf(out, ";;query_failed: %d\n", (int)tp->autr->query_failed)<0
|| fprintf(out, ";;query_interval: %d\n",
(int)tp->autr->query_interval) < 0 ||
";;lastchange=%u ;;%s", str, (int)ta->s,
trustanchor_state2str(ta->s), (int)ta->pending_count,
(unsigned int)ta->last_change,
- ctime_r(&(ta->last_change), tmi)) < 0) {
+ autr_ctime_r(&(ta->last_change), tmi)) < 0) {
log_err("could not write to %s: %s", fn, strerror(errno));
free(str);
return 0;
for(ds_idx=0; ds_idx<num; ds_idx++) {
if(!ds_digest_algo_is_supported(ds_rrset, ds_idx) ||
!ds_key_algo_is_supported(ds_rrset, ds_idx) ||
+ !dnskey_size_is_supported(dnskey_rrset, key_idx) ||
ds_get_digest_algo(ds_rrset, ds_idx) != d)
continue;
if(ds_get_key_algo(ds_rrset, ds_idx)
}
/* is a key of this type supported?. Note rr_list and
* packed_rrset are in the same order. */
- if(!dnskey_algo_is_supported(dnskey_rrset, i)) {
+ if(!dnskey_algo_is_supported(dnskey_rrset, i) ||
+ !dnskey_size_is_supported(dnskey_rrset, i)) {
/* skip unknown algorithm key, it is useless to us */
log_nametypeclass(VERB_DETAIL, "trust point has "
"unsupported algorithm at",
return;
}
if(str[0]) str[strlen(str)-1]=0; /* remove newline */
- ctime_r(&ta->last_change, buf);
+ (void)autr_ctime_r(&ta->last_change, buf);
if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
log_info("[%s] %s ;;state:%d ;;pending_count:%d%s%s last:%s",
trustanchor_state2str(ta->s), str, ta->s, ta->pending_count,
log_packed_rrset(NO_VERBOSE, "DNSKEY:", tp->dnskey_rrset);
}
log_info("file %s", tp->autr->file);
- ctime_r(&tp->autr->last_queried, buf);
+ (void)autr_ctime_r(&tp->autr->last_queried, buf);
if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
log_info("last_queried: %u %s", (unsigned)tp->autr->last_queried, buf);
- ctime_r(&tp->autr->last_success, buf);
+ (void)autr_ctime_r(&tp->autr->last_success, buf);
if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
log_info("last_success: %u %s", (unsigned)tp->autr->last_success, buf);
- ctime_r(&tp->autr->next_probe_time, buf);
+ (void)autr_ctime_r(&tp->autr->next_probe_time, buf);
if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
log_info("next_probe_time: %u %s", (unsigned)tp->autr->next_probe_time,
buf);
{
size_t i, num = 0;
for(i=0; i<ta->numDNSKEY; i++) {
- if(!dnskey_algo_is_supported(ta->dnskey_rrset, i))
+ if(!dnskey_algo_is_supported(ta->dnskey_rrset, i) ||
+ !dnskey_size_is_supported(ta->dnskey_rrset, i))
num++;
}
return num;
const char** zstr;
char* nm;
sldns_buffer* parsebuf = sldns_buffer_new(65535);
+ if(!parsebuf) {
+ log_err("malloc error in anchors_apply_cfg.");
+ return 0;
+ }
if(cfg->insecure_lan_zones) {
for(zstr = as112_zones; *zstr; zstr++) {
if(!anchor_insert_insecure(anchors, *zstr)) {
{
struct packed_rrset_data* d = (struct packed_rrset_data*)
nsec->entry.data;
+ if(!d) return 0;
if(d->security == sec_status_secure)
return 1;
rrset_check_sec_status(env->rrset_cache, nsec, *env->now);
#endif
}
+/** hash structure for keeping track of running hashes */
+struct secalgo_hash {
+ /** the openssl message digest context */
+ EVP_MD_CTX* ctx;
+};
+
+/** create secalgo hash with hash type */
+static struct secalgo_hash* secalgo_hash_create_md(const EVP_MD* md)
+{
+ struct secalgo_hash* h;
+ if(!md)
+ return NULL;
+ h = calloc(1, sizeof(*h));
+ if(!h)
+ return NULL;
+ h->ctx = EVP_MD_CTX_create();
+ if(!h->ctx) {
+ free(h);
+ return NULL;
+ }
+ if(!EVP_DigestInit_ex(h->ctx, md, NULL)) {
+ EVP_MD_CTX_destroy(h->ctx);
+ free(h);
+ return NULL;
+ }
+ return h;
+}
+
+struct secalgo_hash* secalgo_hash_create_sha384(void)
+{
+ return secalgo_hash_create_md(EVP_sha384());
+}
+
+struct secalgo_hash* secalgo_hash_create_sha512(void)
+{
+ return secalgo_hash_create_md(EVP_sha512());
+}
+
+int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
+{
+ return EVP_DigestUpdate(hash->ctx, (unsigned char*)data,
+ (unsigned int)len);
+}
+
+int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
+ size_t maxlen, size_t* resultlen)
+{
+ if(EVP_MD_CTX_size(hash->ctx) > (int)maxlen) {
+ *resultlen = 0;
+ log_err("secalgo_hash_final: hash buffer too small");
+ return 0;
+ }
+ *resultlen = EVP_MD_CTX_size(hash->ctx);
+ return EVP_DigestFinal_ex(hash->ctx, result, NULL);
+}
+
+void secalgo_hash_delete(struct secalgo_hash* hash)
+{
+ if(!hash) return;
+ EVP_MD_CTX_destroy(hash->ctx);
+ free(hash);
+}
+
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
unsigned char* key, size_t keylen)
{
-#if defined(USE_DSA) && defined(USE_SHA1)
- DSA* dsa;
-#endif
- RSA* rsa;
-
switch(algo) {
#if defined(USE_DSA) && defined(USE_SHA1)
case LDNS_DSA:
case LDNS_DSA_NSEC3:
- *evp_key = EVP_PKEY_new();
+ *evp_key = sldns_key_dsa2pkey_raw(key, keylen);
if(!*evp_key) {
- log_err("verify: malloc failure in crypto");
- return 0;
- }
- dsa = sldns_key_buf2dsa_raw(key, keylen);
- if(!dsa) {
- verbose(VERB_QUERY, "verify: "
- "sldns_key_buf2dsa_raw failed");
- return 0;
- }
- if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
- verbose(VERB_QUERY, "verify: "
- "EVP_PKEY_assign_DSA failed");
+ verbose(VERB_QUERY, "verify: sldns_key_dsa2pkey failed");
return 0;
}
#ifdef HAVE_EVP_DSS1
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
case LDNS_RSASHA512:
#endif
- *evp_key = EVP_PKEY_new();
+ *evp_key = sldns_key_rsa2pkey_raw(key, keylen);
if(!*evp_key) {
- log_err("verify: malloc failure in crypto");
- return 0;
- }
- rsa = sldns_key_buf2rsa_raw(key, keylen);
- if(!rsa) {
- verbose(VERB_QUERY, "verify: "
- "sldns_key_buf2rsa_raw SHA failed");
- return 0;
- }
- if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
- verbose(VERB_QUERY, "verify: "
- "EVP_PKEY_assign_RSA SHA failed");
+ verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey SHA failed");
return 0;
}
#endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */
case LDNS_RSAMD5:
- *evp_key = EVP_PKEY_new();
+ *evp_key = sldns_key_rsa2pkey_raw(key, keylen);
if(!*evp_key) {
- log_err("verify: malloc failure in crypto");
- return 0;
- }
- rsa = sldns_key_buf2rsa_raw(key, keylen);
- if(!rsa) {
- verbose(VERB_QUERY, "verify: "
- "sldns_key_buf2rsa_raw MD5 failed");
- return 0;
- }
- if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
- verbose(VERB_QUERY, "verify: "
- "EVP_PKEY_assign_RSA MD5 failed");
+ verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey MD5 failed");
return 0;
}
*digest_type = EVP_md5();
(void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len);
}
+/** the secalgo hash structure */
+struct secalgo_hash {
+ /** hash context */
+ HASHContext* ctx;
+};
+
+/** create hash struct of type */
+static struct secalgo_hash* secalgo_hash_create_type(HASH_HashType tp)
+{
+ struct secalgo_hash* h = calloc(1, sizeof(*h));
+ if(!h)
+ return NULL;
+ h->ctx = HASH_Create(tp);
+ if(!h->ctx) {
+ free(h);
+ return NULL;
+ }
+ return h;
+}
+
+struct secalgo_hash* secalgo_hash_create_sha384(void)
+{
+ return secalgo_hash_create_type(HASH_AlgSHA384);
+}
+
+struct secalgo_hash* secalgo_hash_create_sha512(void)
+{
+ return secalgo_hash_create_type(HASH_AlgSHA512);
+}
+
+int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
+{
+ HASH_Update(hash->ctx, (unsigned char*)data, (unsigned int)len);
+ return 1;
+}
+
+int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
+ size_t maxlen, size_t* resultlen)
+{
+ unsigned int reslen = 0;
+ if(HASH_ResultLenContext(hash->ctx) > (unsigned int)maxlen) {
+ *resultlen = 0;
+ log_err("secalgo_hash_final: hash buffer too small");
+ return 0;
+ }
+ HASH_End(hash->ctx, (unsigned char*)result, &reslen,
+ (unsigned int)maxlen);
+ *resultlen = (size_t)reslen;
+ return 1;
+}
+
+void secalgo_hash_delete(struct secalgo_hash* hash)
+{
+ if(!hash) return;
+ HASH_Destroy(hash->ctx);
+ free(hash);
+}
+
size_t
ds_digest_size_supported(int algo)
{
_digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res);
}
+/** secalgo hash structure */
+struct secalgo_hash {
+ /** if it is 384 or 512 */
+ int active;
+ /** context for sha384 */
+ struct sha384_ctx ctx384;
+ /** context for sha512 */
+ struct sha512_ctx ctx512;
+};
+
+struct secalgo_hash* secalgo_hash_create_sha384(void)
+{
+ struct secalgo_hash* h = calloc(1, sizeof(*h));
+ if(!h)
+ return NULL;
+ h->active = 384;
+ sha384_init(&h->ctx384);
+ return h;
+}
+
+struct secalgo_hash* secalgo_hash_create_sha512(void)
+{
+ struct secalgo_hash* h = calloc(1, sizeof(*h));
+ if(!h)
+ return NULL;
+ h->active = 512;
+ sha512_init(&h->ctx512);
+ return h;
+}
+
+int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
+{
+ if(hash->active == 384) {
+ sha384_update(&hash->ctx384, len, data);
+ } else if(hash->active == 512) {
+ sha512_update(&hash->ctx512, len, data);
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
+int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
+ size_t maxlen, size_t* resultlen)
+{
+ if(hash->active == 384) {
+ if(SHA384_DIGEST_SIZE > maxlen) {
+ *resultlen = 0;
+ log_err("secalgo_hash_final: hash buffer too small");
+ return 0;
+ }
+ *resultlen = SHA384_DIGEST_SIZE;
+ sha384_digest(&hash->ctx384, SHA384_DIGEST_SIZE,
+ (unsigned char*)result);
+ } else if(hash->active == 512) {
+ if(SHA512_DIGEST_SIZE > maxlen) {
+ *resultlen = 0;
+ log_err("secalgo_hash_final: hash buffer too small");
+ return 0;
+ }
+ *resultlen = SHA512_DIGEST_SIZE;
+ sha512_digest(&hash->ctx512, SHA512_DIGEST_SIZE,
+ (unsigned char*)result);
+ } else {
+ *resultlen = 0;
+ return 0;
+ }
+ return 1;
+}
+
+void secalgo_hash_delete(struct secalgo_hash* hash)
+{
+ if(!hash) return;
+ free(hash);
+}
+
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
#ifndef VALIDATOR_VAL_SECALGO_H
#define VALIDATOR_VAL_SECALGO_H
struct sldns_buffer;
+struct secalgo_hash;
/** Return size of nsec3 hash algorithm, 0 if not supported */
size_t nsec3_hash_algo_size_supported(int id);
*/
void secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res);
+/**
+ * Start a hash of type sha384. Allocates structure, then inits it,
+ * so that a series of updates can be performed, before the final result.
+ * @return hash structure. NULL on malloc failure or no support.
+ */
+struct secalgo_hash* secalgo_hash_create_sha384(void);
+
+/**
+ * Start a hash of type sha512. Allocates structure, then inits it,
+ * so that a series of updates can be performed, before the final result.
+ * @return hash structure. NULL on malloc failure or no support.
+ */
+struct secalgo_hash* secalgo_hash_create_sha512(void);
+
+/**
+ * Update a hash with more information to add to it.
+ * @param hash: the hash that is updated.
+ * @param data: data to add.
+ * @param len: length of data.
+ * @return false on failure.
+ */
+int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len);
+
+/**
+ * Get the final result of the hash.
+ * @param hash: the hash that has had updates to it.
+ * @param result: where to store the result.
+ * @param maxlen: length of the result buffer, eg. size of the allocation.
+ * If not large enough the routine fails.
+ * @param resultlen: the length of the result, returned to the caller.
+ * How much of maxlen is used.
+ * @return false on failure.
+ */
+int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
+ size_t maxlen, size_t* resultlen);
+
+/**
+ * Delete the hash structure.
+ * @param hash: the hash to delete.
+ */
+void secalgo_hash_delete(struct secalgo_hash* hash);
+
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
dnskey_idx));
}
+int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
+ size_t dnskey_idx)
+{
+#ifdef DEPRECATE_RSA_1024
+ uint8_t* rdata;
+ size_t len;
+ int alg = dnskey_get_algo(dnskey_rrset, dnskey_idx);
+ size_t keysize;
+
+ rrset_get_rdata(dnskey_rrset, dnskey_idx, &rdata, &len);
+ if(len < 2+4)
+ return 0;
+ keysize = sldns_rr_dnskey_key_size_raw(rdata+2+4, len-2-4, alg);
+
+ switch((sldns_algorithm)alg) {
+ case LDNS_RSAMD5:
+ case LDNS_RSASHA1:
+ case LDNS_RSASHA1_NSEC3:
+ case LDNS_RSASHA256:
+ case LDNS_RSASHA512:
+ /* reject RSA keys of 1024 bits and shorter */
+ if(keysize <= 1024)
+ return 0;
+ break;
+ default:
+ break;
+ }
+#else
+ (void)dnskey_rrset; (void)dnskey_idx;
+#endif /* DEPRECATE_RSA_1024 */
+ return 1;
+}
+
+int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset)
+{
+ size_t i, num = rrset_get_count(dnskey_rrset);
+ for(i=0; i<num; i++) {
+ if(!dnskey_size_is_supported(dnskey_rrset, i))
+ return 0;
+ }
+ return 1;
+}
+
void algo_needs_init_dnskey_add(struct algo_needs* n,
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg)
{
* section, to prevent that a wildcard synthesized NSEC can be used in
* the non-existence proves. */
if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC &&
- section == LDNS_SECTION_AUTHORITY) {
+ section == LDNS_SECTION_AUTHORITY && qstate) {
k->rk.dname = regional_alloc_init(qstate->region, can_owner,
can_owner_len);
if(!k->rk.dname)
return 1;
}
+int
+rrset_canonicalize_to_buffer(struct regional* region, sldns_buffer* buf,
+ struct ub_packed_rrset_key* k)
+{
+ struct rbtree_type* sortree = NULL;
+ struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
+ uint8_t* can_owner = NULL;
+ size_t can_owner_len = 0;
+ struct canon_rr* walk;
+ struct canon_rr* rrs;
+
+ sortree = (struct rbtree_type*)regional_alloc(region,
+ sizeof(rbtree_type));
+ if(!sortree)
+ return 0;
+ if(d->count > RR_COUNT_MAX)
+ return 0; /* integer overflow protection */
+ rrs = regional_alloc(region, sizeof(struct canon_rr)*d->count);
+ if(!rrs) {
+ return 0;
+ }
+ rbtree_init(sortree, &canonical_tree_compare);
+ canonical_sort(k, d, sortree, rrs);
+
+ sldns_buffer_clear(buf);
+ RBTREE_FOR(walk, struct canon_rr*, sortree) {
+ /* see if there is enough space left in the buffer */
+ if(sldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4
+ + d->rr_len[walk->rr_idx]) {
+ log_err("verify: failed to canonicalize, "
+ "rrset too big");
+ return 0;
+ }
+ /* determine canonical owner name */
+ if(can_owner)
+ sldns_buffer_write(buf, can_owner, can_owner_len);
+ else {
+ can_owner = sldns_buffer_current(buf);
+ sldns_buffer_write(buf, k->rk.dname, k->rk.dname_len);
+ query_dname_tolower(can_owner);
+ can_owner_len = k->rk.dname_len;
+ }
+ sldns_buffer_write(buf, &k->rk.type, 2);
+ sldns_buffer_write(buf, &k->rk.rrset_class, 2);
+ sldns_buffer_write_u32(buf, d->rr_ttl[walk->rr_idx]);
+ sldns_buffer_write(buf, d->rr_data[walk->rr_idx],
+ d->rr_len[walk->rr_idx]);
+ canonicalize_rdata(buf, k, d->rr_len[walk->rr_idx]);
+ }
+ sldns_buffer_flip(buf);
+ return 1;
+}
+
/** pretty print rrsig error with dates */
static void
sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now)
int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
size_t dnskey_idx);
+/**
+ * See if the DNSKEY size at that algorithm is supported.
+ * @param dnskey_rrset: DNSKEY rrset.
+ * @param dnskey_idx: index of RR in rrset.
+ * @return true if supported.
+ */
+int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
+ size_t dnskey_idx);
+
+/**
+ * See if the DNSKEY size at that algorithm is supported for all the
+ * RRs in the DNSKEY RRset.
+ * @param dnskey_rrset: DNSKEY rrset.
+ * @return true if supported.
+ */
+int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset);
+
/**
* See if DS digest algorithm is supported
* @param ds_rrset: DS rrset
int rrset_canonical_equal(struct regional* region,
struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2);
+/**
+ * Canonicalize an rrset into the buffer. For an auth zone record, so
+ * this does not use a signature, or the RRSIG TTL or the wildcard label
+ * count from the RRSIG.
+ * @param region: temporary region.
+ * @param buf: the buffer to use.
+ * @param k: the rrset to insert.
+ * @return false on alloc error.
+ */
+int rrset_canonicalize_to_buffer(struct regional* region,
+ struct sldns_buffer* buf, struct ub_packed_rrset_key* k);
+
#endif /* VALIDATOR_VAL_SIGCRYPT_H */
struct module_qstate* qstate)
{
enum sec_status sec = sec_status_bogus;
- size_t i, num, numchecked = 0, numhashok = 0;
+ size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
num = rrset_get_count(dnskey_rrset);
for(i=0; i<num; i++) {
/* Skip DNSKEYs that don't match the basic criteria. */
continue;
}
numhashok++;
+ if(!dnskey_size_is_supported(dnskey_rrset, i)) {
+ verbose(VERB_ALGO, "DS okay but that DNSKEY size is not supported");
+ numsizesupp++;
+ continue;
+ }
verbose(VERB_ALGO, "DS match digest ok, trying signature");
/* Otherwise, we have a match! Make sure that the DNSKEY
}
/* If it didn't validate with the DNSKEY, try the next one! */
}
+ if(numsizesupp != 0) {
+ /* there is a working DS, but that DNSKEY is not supported */
+ return sec_status_insecure;
+ }
if(numchecked == 0)
algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
reason, "no keys have a DS");
continue;
}
+ sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
+ ds_rrset, i, reason, qstate);
+ if(sec == sec_status_insecure)
+ continue;
+
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
* "null" KeyEntry). */
has_useful_ds = 1;
- sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
- ds_rrset, i, reason, qstate);
if(sec == sec_status_secure) {
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)ds_get_key_algo(ds_rrset, i))) {
verbose(VERB_ALGO, "DS matched DNSKEY.");
+ if(!dnskeyset_size_is_supported(dnskey_rrset)) {
+ verbose(VERB_ALGO, "DS works, but dnskeyset contain keys that are unsupported, treat as insecure");
+ return sec_status_insecure;
+ }
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {
ds_get_digest_algo(ta_ds, i) != digest_algo)
continue;
+ sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
+ ta_ds, i, reason, qstate);
+ if(sec == sec_status_insecure)
+ continue;
+
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
* "null" KeyEntry). */
has_useful_ta = 1;
- sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
- ta_ds, i, reason, qstate);
if(sec == sec_status_secure) {
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)ds_get_key_algo(ta_ds, i))) {
verbose(VERB_ALGO, "DS matched DNSKEY.");
+ if(!dnskeyset_size_is_supported(dnskey_rrset)) {
+ verbose(VERB_ALGO, "trustanchor works, but dnskeyset contain keys that are unsupported, treat as insecure");
+ return sec_status_insecure;
+ }
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {
/* Check to see if we can understand this DNSKEY */
if(!dnskey_algo_is_supported(ta_dnskey, i))
continue;
+ if(!dnskey_size_is_supported(ta_dnskey, i))
+ continue;
/* we saw a useful TA */
has_useful_ta = 1;
if(!sigalg || algo_needs_set_secure(&needs,
(uint8_t)dnskey_get_algo(ta_dnskey, i))) {
verbose(VERB_ALGO, "anchor matched DNSKEY.");
+ if(!dnskeyset_size_is_supported(dnskey_rrset)) {
+ verbose(VERB_ALGO, "trustanchor works, but dnskeyset contain keys that are unsupported, treat as insecure");
+ return sec_status_insecure;
+ }
return sec_status_secure;
}
} else if(sigalg && sec == sec_status_bogus) {
val_env->date_override = cfg->val_date_override;
val_env->skew_min = cfg->val_sig_skew_min;
val_env->skew_max = cfg->val_sig_skew_max;
+ val_env->max_restart = cfg->val_max_restart;
c = cfg_count_numbers(cfg->val_nsec3_key_iterations);
if(c < 1 || (c&1)) {
log_err("validator: unparseable or odd nsec3 key "
enum val_classification subtype = val_classify_response(
qstate->query_flags, &qstate->qinfo, &vq->qchase,
vq->orig_msg->rep, vq->rrset_skip);
- if(vq->restart_count > VAL_MAX_RESTART_COUNT) {
+ if(vq->restart_count > ve->max_restart) {
verbose(VERB_ALGO, "restart count exceeded");
return val_error(qstate, id);
}
errinf(qstate, key_entry_get_reason(vq->key_entry));
}
/* no retries, stop bothering the authority until timeout */
- vq->restart_count = VAL_MAX_RESTART_COUNT;
+ vq->restart_count = ve->max_restart;
vq->chase_reply->security = sec_status_bogus;
vq->state = VAL_FINISHED_STATE;
return 1;
LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class);
vq->chase_reply->security = sec_status_bogus;
errinf(qstate, "while building chain of trust");
- if(vq->restart_count >= VAL_MAX_RESTART_COUNT)
+ if(vq->restart_count >= ve->max_restart)
key_cache_insert(ve->kcache, vq->key_entry, qstate);
return 1;
}
* endless bogus revalidation */
if(vq->orig_msg->rep->security == sec_status_bogus) {
/* see if we can try again to fetch data */
- if(vq->restart_count < VAL_MAX_RESTART_COUNT) {
+ if(vq->restart_count < ve->max_restart) {
int restart_count = vq->restart_count+1;
verbose(VERB_ALGO, "validation failed, "
"blacklist and retry to fetch data");
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
struct sock_list* origin)
{
+ struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
struct key_entry_key* dske = NULL;
uint8_t* olds = vq->empty_DS_name;
vq->empty_DS_name = NULL;
vq->chain_blacklist = NULL; /* fresh blacklist for next part*/
/* Keep the forState.state on FINDKEY. */
} else if(key_entry_isbad(dske)
- && vq->restart_count < VAL_MAX_RESTART_COUNT) {
+ && vq->restart_count < ve->max_restart) {
vq->empty_DS_name = olds;
val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1);
qstate->errinf = NULL;
/* bad response */
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
"DNSKEY query.");
- if(vq->restart_count < VAL_MAX_RESTART_COUNT) {
+ if(vq->restart_count < ve->max_restart) {
val_blacklist(&vq->chain_blacklist, qstate->region,
origin, 1);
qstate->errinf = NULL;
* state. */
if(!key_entry_isgood(vq->key_entry)) {
if(key_entry_isbad(vq->key_entry)) {
- if(vq->restart_count < VAL_MAX_RESTART_COUNT) {
+ if(vq->restart_count < ve->max_restart) {
val_blacklist(&vq->chain_blacklist,
qstate->region, origin, 1);
qstate->errinf = NULL;
lock_basic_unlock(&ta->lock);
if(vq->key_entry) {
if(key_entry_isbad(vq->key_entry)
- && vq->restart_count < VAL_MAX_RESTART_COUNT) {
+ && vq->restart_count < ve->max_restart) {
val_blacklist(&vq->chain_blacklist, qstate->region,
origin, 1);
qstate->errinf = NULL;
*/
#define BOGUS_KEY_TTL 60 /* seconds */
-/** max number of query restarts, number of IPs to probe */
-#define VAL_MAX_RESTART_COUNT 5
-
/** Root key sentinel is ta preamble */
#define SENTINEL_IS "root-key-sentinel-is-ta-"
/** Root key sentinel is not ta preamble */
/** clock skew max for signatures */
int32_t skew_max;
+ /** max number of query restarts, number of IPs to probe */
+ int32_t max_restart;
+
/** TTL for bogus data; used instead of untrusted TTL from data.
* Bogus data will not be verified more often than this interval.
* seconds. */