summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2018-03-29 19:44:35 +0000
committerflorian <florian@openbsd.org>2018-03-29 19:44:35 +0000
commit938a3a5ef6489d21887d4422b07c8172f6006834 (patch)
tree5c0e4c75a5705946f1c0fd15f0f9971242742919
parentSet p->p_cpu in cpu_switchto() like we do on other MP architectures. (diff)
downloadwireguard-openbsd-938a3a5ef6489d21887d4422b07c8172f6006834.tar.xz
wireguard-openbsd-938a3a5ef6489d21887d4422b07c8172f6006834.zip
update to unbound 1.7.0
testing tb, sthen OK benno, sthen
-rw-r--r--usr.sbin/unbound/Makefile.in972
-rw-r--r--usr.sbin/unbound/cachedb/cachedb.c7
-rw-r--r--usr.sbin/unbound/config.h.in7
-rw-r--r--usr.sbin/unbound/configure183
-rw-r--r--usr.sbin/unbound/configure.ac35
-rw-r--r--usr.sbin/unbound/daemon/cachedump.c1
-rw-r--r--usr.sbin/unbound/daemon/daemon.c18
-rw-r--r--usr.sbin/unbound/daemon/unbound.c30
-rw-r--r--usr.sbin/unbound/daemon/worker.c33
-rw-r--r--usr.sbin/unbound/dnscrypt/dnscrypt.c8
-rw-r--r--usr.sbin/unbound/dnstap/dnstap.proto1
-rw-r--r--usr.sbin/unbound/doc/Changelog135
-rw-r--r--usr.sbin/unbound/doc/example.conf.in30
-rw-r--r--usr.sbin/unbound/doc/unbound.conf.5.in146
-rw-r--r--usr.sbin/unbound/edns-subnet/addrtree.c2
-rw-r--r--usr.sbin/unbound/edns-subnet/subnetmod.c4
-rw-r--r--usr.sbin/unbound/iterator/iter_delegpt.h2
-rw-r--r--usr.sbin/unbound/iterator/iterator.c384
-rw-r--r--usr.sbin/unbound/iterator/iterator.h5
-rw-r--r--usr.sbin/unbound/libunbound/context.c3
-rw-r--r--usr.sbin/unbound/libunbound/libunbound.c13
-rw-r--r--usr.sbin/unbound/libunbound/libworker.c29
-rw-r--r--usr.sbin/unbound/services/authzone.c2579
-rw-r--r--usr.sbin/unbound/services/authzone.h69
-rw-r--r--usr.sbin/unbound/services/cache/dns.c104
-rw-r--r--usr.sbin/unbound/services/cache/dns.h17
-rw-r--r--usr.sbin/unbound/services/cache/rrset.c32
-rw-r--r--usr.sbin/unbound/services/cache/rrset.h18
-rw-r--r--usr.sbin/unbound/services/localzone.c68
-rw-r--r--usr.sbin/unbound/services/localzone.h4
-rw-r--r--usr.sbin/unbound/services/outside_network.c212
-rw-r--r--usr.sbin/unbound/services/outside_network.h57
-rw-r--r--usr.sbin/unbound/sldns/str2wire.c11
-rw-r--r--usr.sbin/unbound/sldns/str2wire.h6
-rw-r--r--usr.sbin/unbound/sldns/wire2str.c6
-rw-r--r--usr.sbin/unbound/sldns/wire2str.h16
-rw-r--r--usr.sbin/unbound/smallapp/unbound-checkconf.c12
-rw-r--r--usr.sbin/unbound/util/config_file.c7
-rw-r--r--usr.sbin/unbound/util/config_file.h7
-rw-r--r--usr.sbin/unbound/util/configlexer.lex10
-rw-r--r--usr.sbin/unbound/util/configparser.y45
-rw-r--r--usr.sbin/unbound/util/data/msgreply.c11
-rw-r--r--usr.sbin/unbound/util/fptr_wlist.c2
-rw-r--r--usr.sbin/unbound/util/iana_ports.inc3
-rw-r--r--usr.sbin/unbound/util/log.c11
-rw-r--r--usr.sbin/unbound/util/log.h9
-rw-r--r--usr.sbin/unbound/util/net_help.c13
-rw-r--r--usr.sbin/unbound/util/net_help.h9
-rw-r--r--usr.sbin/unbound/util/netevent.c792
-rw-r--r--usr.sbin/unbound/util/netevent.h41
-rw-r--r--usr.sbin/unbound/validator/val_neg.c272
-rw-r--r--usr.sbin/unbound/validator/val_neg.h3
-rw-r--r--usr.sbin/unbound/validator/val_nsec.c7
-rw-r--r--usr.sbin/unbound/validator/val_utils.c6
-rw-r--r--usr.sbin/unbound/validator/val_utils.h4
-rw-r--r--usr.sbin/unbound/validator/validator.c61
56 files changed, 5456 insertions, 1116 deletions
diff --git a/usr.sbin/unbound/Makefile.in b/usr.sbin/unbound/Makefile.in
index 088e4722692..140ddb42436 100644
--- a/usr.sbin/unbound/Makefile.in
+++ b/usr.sbin/unbound/Makefile.in
@@ -264,7 +264,7 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_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)
-LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined
+LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined
.PHONY: clean realclean doc lint all install uninstall tests test strip lib longtest longcheck check alltargets
@@ -389,7 +389,7 @@ dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
@-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
- $(PROTOC_C) --c_out=. $(srcdir)/dnstap/dnstap.proto
+ $(PROTOC_C) --c_out=. --proto_path=$(srcdir) $(srcdir)/dnstap/dnstap.proto
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
@@ -629,68 +629,72 @@ depend:
# Dependencies
dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/locks.h $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h
rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h
+ $(srcdir)/util/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
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)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/storage/lookup3.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/storage/lookup3.h \
+ $(srcdir)/sldns/sbuffer.h
msgencode.lo msgencode.o: $(srcdir)/util/data/msgencode.c config.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/services/view.h
msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h \
+ $(srcdir)/util/regional.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/util/module.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/module.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
- $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_utils.h \
- $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_donotq.h \
- $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h $(srcdir)/iterator/iter_priv.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h \
+ $(srcdir)/iterator/iter_priv.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h \
+ $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/util/config_file.h $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/sldns/sbuffer.h
iter_donotq.lo iter_donotq.o: $(srcdir)/iterator/iter_donotq.c config.h $(srcdir)/iterator/iter_donotq.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
@@ -701,30 +705,31 @@ iter_fwd.lo iter_fwd.o: $(srcdir)/iterator/iter_fwd.c config.h $(srcdir)/iterato
iter_hints.lo iter_hints.o: $(srcdir)/iterator/iter_hints.c config.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
iter_priv.lo iter_priv.o: $(srcdir)/iterator/iter_priv.c config.h $(srcdir)/iterator/iter_priv.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h
iter_resptype.lo iter_resptype.o: $(srcdir)/iterator/iter_resptype.c config.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/data/dname.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h
iter_scrub.lo iter_scrub.o: $(srcdir)/iterator/iter_scrub.c config.h $(srcdir)/iterator/iter_scrub.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/iterator/iter_priv.h $(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_priv.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h \
+ $(srcdir)/sldns/sbuffer.h
iter_utils.lo iter_utils.o: $(srcdir)/iterator/iter_utils.c config.h $(srcdir)/iterator/iter_utils.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_priv.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@@ -738,33 +743,34 @@ iter_utils.lo iter_utils.o: $(srcdir)/iterator/iter_utils.c config.h $(srcdir)/i
listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/sbuffer.h
localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/as112.h
mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(PYTHONMOD_HEADER) \
@@ -772,120 +778,125 @@ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/service
$(srcdir)/util/alloc.h $(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h
outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rtt.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/data/msgencode.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.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/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
+ $(srcdir)/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)/dnscrypt/cert.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h
config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/configyyrename.h $(srcdir)/util/config_file.h util/configparser.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
- $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/iana_ports.inc
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/iana_ports.inc
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
- $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h \
- $(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.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)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h
authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/module.h $(srcdir)/util/random.h $(srcdir)/services/cache/dns.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)/dnscrypt/cert.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/random.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/outside_network.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/validator/val_nsec3.h \
- $(srcdir)/validator/val_secalgo.h
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_secalgo.h
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
- $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
- $(srcdir)/services/authzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h \
- $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h \
- $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h \
- $(srcdir)/edns-subnet/edns-subnet.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
+ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
+ $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
+ $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h $(PYTHONMOD_HEADER) \
+ $(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h \
+ $(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h
module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.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
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
+ \
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h \
- $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
random.lo random.o: $(srcdir)/util/random.c config.h $(srcdir)/util/random.h $(srcdir)/util/log.h
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h
regional.lo regional.o: $(srcdir)/util/regional.c config.h $(srcdir)/util/log.h $(srcdir)/util/regional.h
rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h
dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
@@ -893,51 +904,57 @@ dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/s
$(srcdir)/util/log.h $(srcdir)/util/net_help.h
lookup3.lo lookup3.o: $(srcdir)/util/storage/lookup3.c config.h $(srcdir)/util/storage/lookup3.h
lruhash.lo lruhash.o: $(srcdir)/util/storage/lruhash.c config.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h
slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.h $(srcdir)/util/log.h
tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h \
- $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/ub_event.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
+ $(srcdir)/util/rbtree.h
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/services/modstack.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kcache.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_sigcrypt.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/keyraw.h \
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/as112.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/autotrust.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/as112.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/sldns/str2wire.h
validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/validator/validator.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \
@@ -948,59 +965,64 @@ validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/val
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
- $(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)/validator/val_kentry.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h
val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
+ $(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 \
$(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/validator/val_nsec.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
+ $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/validator/val_kentry.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/validator/val_nsec.h \
+ $(srcdir)/sldns/sbuffer.h
val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/validator/val_nsec.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h
+ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h
val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h \
val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h \
- $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/sldns/parseutil.h
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
@@ -1009,37 +1031,37 @@ 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)/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)/dnscrypt/cert.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/cache/dns.h $(srcdir)/util/regional.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.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)/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)/dnscrypt/cert.h $(srcdir)/services/modstack.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.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
+ $(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)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h \
- $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h \
- $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h \
+ $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
@@ -1047,59 +1069,65 @@ checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/u
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.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)/dnscrypt/cert.h \
- $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/storage/lookup3.h
+ $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/lookup3.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)/dnscrypt/cert.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/wire2str.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)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.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
+ $(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
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)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/rrdef.h
unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
+ $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/storage/slabhash.h
unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/random.h $(srcdir)/respip/respip.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/localzone.h $(srcdir)/services/view.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)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/random.h $(srcdir)/respip/respip.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
$(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/testcode/readhex.h \
- $(srcdir)/testcode/testpkts.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+ $(srcdir)/testcode/readhex.h $(srcdir)/testcode/testpkts.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/wire2str.h
unitneg.lo unitneg.o: $(srcdir)/testcode/unitneg.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/data/dname.h $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \
- $(srcdir)/sldns/rrdef.h
+ $(srcdir)/util/data/dname.h $(srcdir)/testcode/unitmain.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h
unitregional.lo unitregional.o: $(srcdir)/testcode/unitregional.c config.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/log.h $(srcdir)/util/regional.h
unitslabhash.lo unitslabhash.o: $(srcdir)/testcode/unitslabhash.c config.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h
unitverify.lo unitverify.o: $(srcdir)/testcode/unitverify.c config.h $(srcdir)/util/log.h \
$(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/validator/val_secalgo.h \
- $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h \
- $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
$(srcdir)/testcode/testpkts.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \
$(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
@@ -1111,84 +1139,89 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h $(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)/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)/edns-subnet/edns-subnet.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)/testcode/unitmain.h \
- $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.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)/dnscrypt/cert.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
+ $(srcdir)/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 $(srcdir)/sldns/sbuffer.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/str2wire.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/str2wire.h
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
$(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.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/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.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/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)/dnscrypt/cert.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)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
- $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
+ $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.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)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
- $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
- $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
- $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
- $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h \
+ $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/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/storage/dnstree.h $(srcdir)/util/rtt.h \
- $(srcdir)/validator/val_kcache.h
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/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/storage/dnstree.h \
+ $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/remote.h \
+ $(srcdir)/util/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)/dnscrypt/cert.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h \
@@ -1199,25 +1232,27 @@ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.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/mesh.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
- $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
- $(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
- $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
+ $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/util/shm_side/shm_main.h
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
+ $(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/daemon/daemon.h \
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
@@ -1231,180 +1266,191 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.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/mesh.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
- $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
- $(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
- $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
+ $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/util/shm_side/shm_main.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/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/str2wire.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/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)/dnscrypt/cert.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/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)/dnscrypt/cert.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)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
- $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
+ $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.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/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/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/storage/dnstree.h $(srcdir)/util/rtt.h \
- $(srcdir)/validator/val_kcache.h
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/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/storage/dnstree.h \
+ $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/rrdef.h
+ $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/net_help.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/msgencode.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
- $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/net_help.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/msgencode.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
pktview.lo pktview.o: $(srcdir)/testcode/pktview.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/parseutil.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h \
+ $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
readhex.lo readhex.o: $(srcdir)/testcode/readhex.c config.h $(srcdir)/testcode/readhex.h $(srcdir)/util/log.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
- $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/regional.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h $(srcdir)/sldns/sbuffer.h \
$(PYTHONMOD_HEADER) $(srcdir)/edns-subnet/subnet-whitelist.h
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h
context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
- $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h \
+ $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/libworker.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
- $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \
- $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/libunbound/libworker.h $(srcdir)/util/config_file.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h \
+ $(srcdir)/util/ub_event.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h \
+ $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/services/mesh.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h \
- $(srcdir)/util/random.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/libunbound/unbound-event.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/services/authzone.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/sldns/rrdef.h
+ $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
-perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+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)/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
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/regional.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.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/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)/dnscrypt/cert.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
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 \
diff --git a/usr.sbin/unbound/cachedb/cachedb.c b/usr.sbin/unbound/cachedb/cachedb.c
index d07d76973fd..80bdc380f3f 100644
--- a/usr.sbin/unbound/cachedb/cachedb.c
+++ b/usr.sbin/unbound/cachedb/cachedb.c
@@ -568,14 +568,17 @@ cachedb_intcache_lookup(struct module_qstate* qstate)
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);
+ qstate->region, qstate->env->scratch,
+ 1 /* no partial messages with only a CNAME */
+ );
if(!msg && qstate->env->neg_cache) {
/* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
qstate->region, qstate->env->rrset_cache,
qstate->env->scratch_buffer,
- *qstate->env->now, 1/*add SOA*/, NULL);
+ *qstate->env->now, 1/*add SOA*/, NULL,
+ qstate->env->cfg);
}
if(!msg)
return 0;
diff --git a/usr.sbin/unbound/config.h.in b/usr.sbin/unbound/config.h.in
index 90038a88fac..e7405603dda 100644
--- a/usr.sbin/unbound/config.h.in
+++ b/usr.sbin/unbound/config.h.in
@@ -425,6 +425,12 @@
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
+/* Define to 1 if you have the `SSL_get0_peername' function. */
+#undef HAVE_SSL_GET0_PEERNAME
+
+/* Define to 1 if you have the `SSL_set1_host' function. */
+#undef HAVE_SSL_SET1_HOST
+
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
@@ -1150,6 +1156,7 @@ uint32_t arc4random(void);
void arc4random_buf(void* buf, size_t n);
void _ARC4_LOCK(void);
void _ARC4_UNLOCK(void);
+void _ARC4_LOCK_DESTROY(void);
#endif
#ifndef HAVE_ARC4RANDOM_UNIFORM
uint32_t arc4random_uniform(uint32_t upper_bound);
diff --git a/usr.sbin/unbound/configure b/usr.sbin/unbound/configure
index 9cccf64e2b0..8581e6ed402 100644
--- a/usr.sbin/unbound/configure
+++ b/usr.sbin/unbound/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.6.8.
+# Generated by GNU Autoconf 2.69 for unbound 1.7.0.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.6.8'
-PACKAGE_STRING='unbound 1.6.8'
+PACKAGE_VERSION='1.7.0'
+PACKAGE_STRING='unbound 1.7.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
PACKAGE_URL=''
@@ -848,6 +848,7 @@ with_pthreads
with_solaris_threads
with_pyunbound
with_pythonmodule
+enable_swig_version_check
with_nss
with_nettle
with_ssl
@@ -1437,7 +1438,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures unbound 1.6.8 to adapt to many kinds of systems.
+\`configure' configures unbound 1.7.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1502,7 +1503,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of unbound 1.6.8:";;
+ short | recursive ) echo "Configuration of unbound 1.7.0:";;
esac
cat <<\_ACEOF
@@ -1532,6 +1533,9 @@ Optional Features:
enable nonregional allocs, slow but exposes regional
allocations to other memory purifiers, for debug
purposes
+ --disable-swig-version-check
+ Disable swig version check to build python modules
+ with older swig even though that is unreliable
--disable-sha1 Disable SHA1 RRSIG support, does not disable nsec3
support
--disable-sha2 Disable SHA256 and SHA512 RRSIG support
@@ -1714,7 +1718,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-unbound configure 1.6.8
+unbound configure 1.7.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2423,7 +2427,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by unbound $as_me 1.6.8, which was
+It was created by unbound $as_me 1.7.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2773,9 +2777,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
-UNBOUND_VERSION_MINOR=6
+UNBOUND_VERSION_MINOR=7
-UNBOUND_VERSION_MICRO=8
+UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=7
@@ -2838,6 +2842,7 @@ LIBUNBOUND_AGE=5
# 1.6.6 had 7:5:5
# 1.6.7 had 7:6:5
# 1.6.8 had 7:7:5
+# 1.7.0 had 7:8:5
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -16922,6 +16927,12 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
# Check for SWIG
ub_have_swig=no
+ # Check whether --enable-swig-version-check was given.
+if test "${enable_swig_version_check+set}" = set; then :
+ enableval=$enable_swig_version_check;
+fi
+
+ if test "$enable_swig_version_check" = "yes"; then
# Extract the first word of "swig", so it can be a program name with args.
set dummy swig; ac_word=$2
@@ -17038,6 +17049,124 @@ $as_echo "$as_me: WARNING: cannot determine SWIG version" >&2;}
fi
+ else
+
+ # Extract the first word of "swig", so it can be a program name with args.
+set dummy swig; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SWIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $SWIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SWIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+SWIG=$ac_cv_path_SWIG
+if test -n "$SWIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5
+$as_echo "$SWIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test -z "$SWIG" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5
+$as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;}
+ SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
+ elif test -n "" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5
+$as_echo_n "checking for SWIG version... " >&6; }
+ swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5
+$as_echo "$swig_version" >&6; }
+ if test -n "$swig_version" ; then
+ # Calculate the required version number components
+ required=
+ required_major=`echo $required | sed 's/[^0-9].*//'`
+ if test -z "$required_major" ; then
+ required_major=0
+ fi
+ required=`echo $required | sed 's/[0-9]*[^0-9]//'`
+ required_minor=`echo $required | sed 's/[^0-9].*//'`
+ if test -z "$required_minor" ; then
+ required_minor=0
+ fi
+ required=`echo $required | sed 's/[0-9]*[^0-9]//'`
+ required_patch=`echo $required | sed 's/[^0-9].*//'`
+ if test -z "$required_patch" ; then
+ required_patch=0
+ fi
+ # Calculate the available version number components
+ available=$swig_version
+ available_major=`echo $available | sed 's/[^0-9].*//'`
+ if test -z "$available_major" ; then
+ available_major=0
+ fi
+ available=`echo $available | sed 's/[0-9]*[^0-9]//'`
+ available_minor=`echo $available | sed 's/[^0-9].*//'`
+ if test -z "$available_minor" ; then
+ available_minor=0
+ fi
+ available=`echo $available | sed 's/[0-9]*[^0-9]//'`
+ available_patch=`echo $available | sed 's/[^0-9].*//'`
+ if test -z "$available_patch" ; then
+ available_patch=0
+ fi
+ badversion=0
+ if test $available_major -lt $required_major ; then
+ badversion=1
+ fi
+ if test $available_major -eq $required_major \
+ -a $available_minor -lt $required_minor ; then
+ badversion=1
+ fi
+ if test $available_major -eq $required_major \
+ -a $available_minor -eq $required_minor \
+ -a $available_patch -lt $required_patch ; then
+ badversion=1
+ fi
+ if test $badversion -eq 1 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&5
+$as_echo "$as_me: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
+ SWIG='echo "Error: SWIG version >= is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: SWIG executable is '$SWIG'" >&5
+$as_echo "$as_me: SWIG executable is '$SWIG'" >&6;}
+ SWIG_LIB=`$SWIG -swiglib`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: SWIG library directory is '$SWIG_LIB'" >&5
+$as_echo "$as_me: SWIG library directory is '$SWIG_LIB'" >&6;}
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5
+$as_echo "$as_me: WARNING: cannot determine SWIG version" >&2;}
+ SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
+ fi
+ fi
+
+
+ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SWIG" >&5
$as_echo_n "checking SWIG... " >&6; }
if test ! -x "$SWIG"; then
@@ -17658,7 +17787,7 @@ done
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
-for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level
+for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18077,6 +18206,28 @@ case "$enable_dsa" in
ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
if test "x$ac_cv_func_DSA_SIG_new" = xyes; then :
+ as_ac_Type=`$as_echo "ac_cv_type_DSA_SIG*" | $as_tr_sh`
+ac_fn_c_check_type "$LINENO" "DSA_SIG*" "$as_ac_Type" "
+$ac_includes_default
+#ifdef HAVE_OPENSSL_ERR_H
+#include <openssl/err.h>
+#endif
+
+#ifdef HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+#ifdef HAVE_OPENSSL_CONF_H
+#include <openssl/conf.h>
+#endif
+
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+
+"
+if eval test \"x\$"$as_ac_Type"\" = x"yes"; then :
+
cat >>confdefs.h <<_ACEOF
#define USE_DSA 1
@@ -18088,6 +18239,12 @@ else
fi
fi
+
+else
+ if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
+ fi
+fi
+
else
cat >>confdefs.h <<_ACEOF
@@ -20771,7 +20928,7 @@ _ACEOF
-version=1.6.8
+version=1.7.0
date=`date +'%b %e, %Y'`
@@ -21290,7 +21447,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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.6.8, which was
+This file was extended by unbound $as_me 1.7.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -21356,7 +21513,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-unbound config.status 1.6.8
+unbound config.status 1.7.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/usr.sbin/unbound/configure.ac b/usr.sbin/unbound/configure.ac
index 6e4eec561c9..a5e16eb69ce 100644
--- a/usr.sbin/unbound/configure.ac
+++ b/usr.sbin/unbound/configure.ac
@@ -10,8 +10,8 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
-m4_define([VERSION_MINOR],[6])
-m4_define([VERSION_MICRO],[8])
+m4_define([VERSION_MINOR],[7])
+m4_define([VERSION_MICRO],[0])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
@@ -77,6 +77,7 @@ LIBUNBOUND_AGE=5
# 1.6.6 had 7:5:5
# 1.6.7 had 7:6:5
# 1.6.8 had 7:7:5
+# 1.7.0 had 7:8:5
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -586,7 +587,12 @@ if test x_$ub_test_python != x_no; then
# Check for SWIG
ub_have_swig=no
- AC_PROG_SWIG(2.0.1)
+ AC_ARG_ENABLE(swig-version-check, AC_HELP_STRING([--disable-swig-version-check], [Disable swig version check to build python modules with older swig even though that is unreliable]))
+ if test "$enable_swig_version_check" = "yes"; then
+ AC_PROG_SWIG(2.0.1)
+ else
+ AC_PROG_SWIG
+ fi
AC_MSG_CHECKING(SWIG)
if test ! -x "$SWIG"; then
AC_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound])
@@ -718,7 +724,7 @@ AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_C
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
-AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level])
+AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
@@ -934,8 +940,28 @@ case "$enable_dsa" in
# detect if DSA is supported, and turn it off if not.
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
AC_CHECK_FUNC(DSA_SIG_new, [
+ AC_CHECK_TYPE(DSA_SIG*, [
AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
+ fi ], [
+AC_INCLUDES_DEFAULT
+#ifdef HAVE_OPENSSL_ERR_H
+#include <openssl/err.h>
+#endif
+
+#ifdef HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+#ifdef HAVE_OPENSSL_CONF_H
+#include <openssl/conf.h>
+#endif
+
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+ ])
+ ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
fi ])
else
AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
@@ -1660,6 +1686,7 @@ uint32_t arc4random(void);
void arc4random_buf(void* buf, size_t n);
void _ARC4_LOCK(void);
void _ARC4_UNLOCK(void);
+void _ARC4_LOCK_DESTROY(void);
#endif
#ifndef HAVE_ARC4RANDOM_UNIFORM
uint32_t arc4random_uniform(uint32_t upper_bound);
diff --git a/usr.sbin/unbound/daemon/cachedump.c b/usr.sbin/unbound/daemon/cachedump.c
index 8992e6cb8f3..81061870b58 100644
--- a/usr.sbin/unbound/daemon/cachedump.c
+++ b/usr.sbin/unbound/daemon/cachedump.c
@@ -79,6 +79,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
size_t i;
/* rd lock held by caller */
if(!k || !d) return 1;
+ if(k->id == 0) return 1; /* deleted */
if(d->ttl < now) return 1; /* expired */
/* meta line */
diff --git a/usr.sbin/unbound/daemon/daemon.c b/usr.sbin/unbound/daemon/daemon.c
index 7411fabe757..f68bd981b01 100644
--- a/usr.sbin/unbound/daemon/daemon.c
+++ b/usr.sbin/unbound/daemon/daemon.c
@@ -82,6 +82,7 @@
#include "services/localzone.h"
#include "services/view.h"
#include "services/modstack.h"
+#include "services/authzone.h"
#include "util/module.h"
#include "util/random.h"
#include "util/tube.h"
@@ -281,6 +282,13 @@ daemon_init(void)
if(gettimeofday(&daemon->time_boot, NULL) < 0)
log_err("gettimeofday: %s", strerror(errno));
daemon->time_last_stat = daemon->time_boot;
+ if((daemon->env->auth_zones = auth_zones_create()) == 0) {
+ acl_list_delete(daemon->acl);
+ edns_known_options_delete(daemon->env);
+ free(daemon->env);
+ free(daemon);
+ return NULL;
+ }
return daemon;
}
@@ -603,6 +611,10 @@ daemon_fork(struct daemon* daemon)
fatal_exit("Could not set up per-view response IP sets");
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
have_view_respip_cfg;
+
+ /* read auth zonefiles */
+ if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
+ fatal_exit("auth_zones could not be setup");
/* setup modules */
daemon_setup_modules(daemon);
@@ -683,6 +695,8 @@ daemon_cleanup(struct daemon* daemon)
daemon->respip_set = NULL;
views_delete(daemon->views);
daemon->views = NULL;
+ if(daemon->env->auth_zones)
+ auth_zones_cleanup(daemon->env->auth_zones);
/* key cache is cleared by module desetup during next daemon_fork() */
daemon_remote_clear(daemon->rc);
for(i=0; i<daemon->num; i++)
@@ -716,6 +730,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env);
+ auth_zones_delete(daemon->env->auth_zones);
}
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
@@ -763,6 +778,9 @@ daemon_delete(struct daemon* daemon)
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
ub_openssl_lock_delete();
# endif
+#ifndef HAVE_ARC4RANDOM
+ _ARC4_LOCK_DESTROY();
+#endif
#elif defined(HAVE_NSS)
NSS_Shutdown();
#endif /* HAVE_SSL or HAVE_NSS */
diff --git a/usr.sbin/unbound/daemon/unbound.c b/usr.sbin/unbound/daemon/unbound.c
index 432aa912e68..e4caf004819 100644
--- a/usr.sbin/unbound/daemon/unbound.c
+++ b/usr.sbin/unbound/daemon/unbound.c
@@ -421,17 +421,6 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
w_config_adjust_directory(cfg);
#endif
- /* init syslog (as root) if needed, before daemonize, otherwise
- * a fork error could not be printed since daemonize closed stderr.*/
- if(cfg->use_syslog) {
- log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
- }
- /* if using a logfile, we cannot open it because the logfile would
- * be created with the wrong permissions, we cannot chown it because
- * we cannot chown system logfiles, so we do not open at all.
- * So, using a logfile, the user does not see errors unless -d is
- * given to unbound on the commandline. */
-
/* read ssl keys while superuser and outside chroot */
#ifdef HAVE_SSL
if(!(daemon->rc = daemon_remote_create(cfg)))
@@ -441,10 +430,22 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
fatal_exit("could not set up listen SSL_CTX");
}
- if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, NULL)))
+ if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
+ cfg->tls_cert_bundle)))
fatal_exit("could not set up connect SSL_CTX");
#endif
+ /* init syslog (as root) if needed, before daemonize, otherwise
+ * a fork error could not be printed since daemonize closed stderr.*/
+ if(cfg->use_syslog) {
+ log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
+ }
+ /* if using a logfile, we cannot open it because the logfile would
+ * be created with the wrong permissions, we cannot chown it because
+ * we cannot chown system logfiles, so we do not open at all.
+ * So, using a logfile, the user does not see errors unless -d is
+ * given to unbound on the commandline. */
+
#ifdef HAVE_KILL
/* true if pidfile is inside chrootdir, or nochroot */
pidinchroot = need_pidfile && (!(cfg->chrootdir && cfg->chrootdir[0]) ||
@@ -744,5 +745,10 @@ main(int argc, char* argv[])
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile);
log_init(NULL, 0, NULL); /* close logfile */
+#ifndef unbound_testbound
+ if(log_get_lock()) {
+ lock_quick_destroy((lock_quick_type*)log_get_lock());
+ }
+#endif
return 0;
}
diff --git a/usr.sbin/unbound/daemon/worker.c b/usr.sbin/unbound/daemon/worker.c
index 233ae38e76f..389a1de530e 100644
--- a/usr.sbin/unbound/daemon/worker.c
+++ b/usr.sbin/unbound/daemon/worker.c
@@ -58,6 +58,7 @@
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
#include "services/cache/dns.h"
+#include "services/authzone.h"
#include "services/mesh.h"
#include "services/localzone.h"
#include "util/data/msgparse.h"
@@ -1251,6 +1252,22 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
+ if(worker->env.auth_zones &&
+ auth_zones_answer(worker->env.auth_zones, &worker->env,
+ &qinfo, &edns, c->buffer, worker->scratchpad)) {
+ regional_free_all(worker->scratchpad);
+ if(sldns_buffer_limit(c->buffer) == 0) {
+ comm_point_drop_reply(repinfo);
+ return 0;
+ }
+ /* set RA for everyone that can have recursion (based on
+ * access control list) */
+ if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) &&
+ acl != acl_deny_non_local && acl != acl_refuse_non_local)
+ LDNS_RA_SET(sldns_buffer_begin(c->buffer));
+ server_stats_insrcode(&worker->stats, c->buffer);
+ goto send_reply;
+ }
/* We've looked in our local zones. If the answer isn't there, we
* might need to bail out based on ACLs now. */
@@ -1322,11 +1339,11 @@ lookup_cache:
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
- if(answer_from_cache(worker, &qinfo,
+ if(answer_from_cache(worker, &qinfo,
cinfo, &need_drop, &alias_rrset, &partial_rep,
- (struct reply_info*)e->data,
- *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
- sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
+ (struct reply_info*)e->data,
+ *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
+ sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
&edns)) {
/* prefetch it if the prefetch TTL expired.
* Note that if there is more than one pass
@@ -1721,6 +1738,14 @@ worker_init(struct worker* worker, struct config_file *cfg,
comm_timer_set(worker->env.probe_timer, &tv);
}
}
+ /* zone transfer tasks, setup once per process, if any */
+ if(worker->env.auth_zones
+#ifndef THREADS_DISABLED
+ && worker->thread_num == 0
+#endif
+ ) {
+ auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env);
+ }
if(!worker->env.mesh || !worker->env.scratch_buffer) {
worker_delete(worker);
return 0;
diff --git a/usr.sbin/unbound/dnscrypt/dnscrypt.c b/usr.sbin/unbound/dnscrypt/dnscrypt.c
index f139ce8b22b..3545d3d9b43 100644
--- a/usr.sbin/unbound/dnscrypt/dnscrypt.c
+++ b/usr.sbin/unbound/dnscrypt/dnscrypt.c
@@ -980,6 +980,7 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
if(dnsc_load_local_data(env, cfg) <= 0) {
fatal_exit("dnsc_apply_cfg: could not load local data");
}
+ lock_basic_lock(&env->shared_secrets_cache_lock);
env->shared_secrets_cache = slabhash_create(
cfg->dnscrypt_shared_secret_cache_slabs,
HASH_DEFAULT_STARTARRAY,
@@ -990,9 +991,11 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
dnsc_shared_secrets_deldatafunc,
NULL
);
+ lock_basic_unlock(&env->shared_secrets_cache_lock);
if(!env->shared_secrets_cache){
fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
}
+ lock_basic_lock(&env->nonces_cache_lock);
env->nonces_cache = slabhash_create(
cfg->dnscrypt_nonce_cache_slabs,
HASH_DEFAULT_STARTARRAY,
@@ -1003,6 +1006,7 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
dnsc_nonces_deldatafunc,
NULL
);
+ lock_basic_unlock(&env->nonces_cache_lock);
return 0;
}
@@ -1017,10 +1021,10 @@ dnsc_delete(struct dnsc_env *env)
sodium_free(env->rotated_certs);
sodium_free(env->certs);
sodium_free(env->keypairs);
- slabhash_delete(env->shared_secrets_cache);
- slabhash_delete(env->nonces_cache);
lock_basic_destroy(&env->shared_secrets_cache_lock);
lock_basic_destroy(&env->nonces_cache_lock);
+ slabhash_delete(env->shared_secrets_cache);
+ slabhash_delete(env->nonces_cache);
free(env);
}
diff --git a/usr.sbin/unbound/dnstap/dnstap.proto b/usr.sbin/unbound/dnstap/dnstap.proto
index 32871f409cf..88bfb4e9412 100644
--- a/usr.sbin/unbound/dnstap/dnstap.proto
+++ b/usr.sbin/unbound/dnstap/dnstap.proto
@@ -13,6 +13,7 @@
// with this file. If not, see:
//
// <http://creativecommons.org/publicdomain/zero/1.0/>.
+syntax = "proto2";
package dnstap;
diff --git a/usr.sbin/unbound/doc/Changelog b/usr.sbin/unbound/doc/Changelog
index 05929c48d2e..cc4844813f7 100644
--- a/usr.sbin/unbound/doc/Changelog
+++ b/usr.sbin/unbound/doc/Changelog
@@ -1,3 +1,137 @@
+13 March 2018: Wouter
+ - Fix typo in documentation.
+ - Fix #3736: Fix 0 TTL domains stuck on SERVFAIL unless manually
+ flushed with serve-expired on.
+
+12 March 2018: Wouter
+ - Added documentation for aggressive-nsec: yes.
+ - tag 1.7.0rc3.
+ - Fix #3727: Protocol name is TLS, options have been renamed but
+ documentation is not consistent.
+ - Check IXFR start serial.
+
+9 March 2018: Wouter
+ - Fix #3598: Fix swig build issue on rhel6 based system.
+ configure --disable-swig-version-check stops the swig version check.
+
+8 March 2018: Wouter
+ - tag 1.7.0rc2.
+
+7 March 2018: Wouter
+ - Fixed contrib/fastrpz.patch, even though this already applied
+ cleanly for me, now also for others.
+ - patch to log creates keytag queries, from A. Schulze.
+ - patch suggested by Debian lintian: allow to -> allow one to, from
+ A. Schulze.
+ - Attempt to remove warning about trailing whitespace.
+
+6 March 2018: Wouter
+ - Reverted fix for #3512, this may not be the best way forward;
+ although it could be changed at a later time, to stay similar to
+ other implementations.
+ - svn trunk contains 1.7.0, this is the number for the next release.
+ - Fix for windows compile.
+ - tag 1.7.0rc1.
+
+5 March 2018: Wouter
+ - Fix to check define of DSA for when openssl is without deprecated.
+ - iana port update.
+ - Fix #3582: Squelch address already in use log when reuseaddr option
+ causes same port to be used twice for tcp connections.
+
+27 February 2018: Wouter
+ - Fixup contrib/fastrpz.patch so that it applies.
+ - Fix compile without threads, and remove unused variable.
+ - Fix compile with staticexe and python module.
+ - Fix nettle compile.
+
+22 February 2018: Ralph
+ - Save wildcard RRset from answer with original owner for use in
+ aggressive NSEC.
+
+21 February 2018: Wouter
+ - Fix #3512: unbound incorrectly reports SERVFAIL for CAA query
+ when there is a CNAME loop.
+ - Fix validation for CNAME loops. When it detects a cname loop,
+ by finding the cname, cname in the existing list, it returns
+ the partial result with the validation result up to then.
+ - more robust cachedump rrset routine.
+
+19 February 2018: Wouter
+ - Fix #3505: Documentation for default local zones references
+ wrong RFC.
+ - Fix #3494: local-zone noview can be used to break out of the view
+ to the global local zone contents, for queries for that zone.
+ - Fix for more maintainable code in localzone.
+
+16 February 2018: Wouter
+ - Fixes for clang static analyzer, the missing ; in
+ edns-subnet/addrtree.c after the assert made clang analyzer
+ produce a failure to analyze it.
+
+13 February 2018: Ralph
+ - Aggressive NSEC tests
+
+13 February 2018: Wouter
+ - tls-cert-bundle option in unbound.conf enables TLS authentication.
+ - iana port update.
+
+12 February 2018: Wouter
+ - Unit test for auth zone https url download.
+
+12 February 2018: Ralph
+ - Added tests with wildcard expanded NSEC records (CVE-2017-15105 test)
+ - Processed aggressive NSEC code review remarks Wouter
+
+8 February 2018: Ralph
+ - Aggressive use of NSEC implementation. Use cached NSEC records to
+ generate NXDOMAIN, NODATA and positive wildcard answers.
+
+8 February 2018: Wouter
+ - iana port update.
+ - auth zone url config.
+
+5 February 2018: Wouter
+ - Fix #3451: dnstap not building when you have a separate build dir.
+ And removed protoc warning, set dnstap.proto syntax to proto2.
+ - auth-zone provides a way to configure RFC7706 from unbound.conf,
+ eg. with auth-zone: name: "." for-downstream: no for-upstream: yes
+ fallback-enabled: yes and masters or a zonefile with data.
+
+2 February 2018: Wouter
+ - Fix unfreed locks in log and arc4random at exit of unbound.
+ - unit test with valgrind
+ - Fix lock race condition in dns cache dname synthesis.
+ - lock subnet new item before insertion to please checklocks,
+ no modification of critical regions outside of lock region.
+
+1 February 2018: Wouter
+ - fix unaligned structure making a false positive in checklock
+ unitialised memory.
+
+29 January 2018: Ralph
+ - Use NSEC with longest ce to prove wildcard absence.
+ - Only use *.ce to prove wildcard absence, no longer names.
+
+25 January 2018: Wouter
+ - ltrace.conf file for libunbound in contrib.
+
+23 January 2018: Wouter
+ - Fix that unbound-checkconf -f flag works with auto-trust-anchor-file
+ for startup scripts to get the full pathname(s) of anchor file(s).
+ - Print fatal errors about remote control setup before log init,
+ so that it is printed to console.
+
+22 January 2018: Wouter
+ - Accept tls-upstream in unbound.conf, the ssl-upstream keyword is
+ also recognized and means the same. Also for tls-port,
+ tls-service-key, tls-service-pem, stub-tls-upstream and
+ forward-tls-upstream.
+ - Fix #3397: Fix that cachedb could return a partial CNAME chain.
+ - Fix #3397: Fix that when the cache contains an unsigned DNAME in
+ the middle of a cname chain, a result without the DNAME could
+ be returned.
+
19 January 2018: Wouter
- tag 1.6.8 for release with CVE fix.
- trunk has 1.6.9 with fix and previous commits.
@@ -73,6 +207,7 @@
fail.
- lexer output.
- iana port update.
+ - make depend: code dependencies updated in Makefile.
25 October 2017: Ralph
- Fixed libunbound manual typo.
diff --git a/usr.sbin/unbound/doc/example.conf.in b/usr.sbin/unbound/doc/example.conf.in
index 2d14d69c0f9..1511c1b21c0 100644
--- a/usr.sbin/unbound/doc/example.conf.in
+++ b/usr.sbin/unbound/doc/example.conf.in
@@ -380,6 +380,10 @@ server:
# This option only has effect when qname-minimisation is enabled.
# qname-minimisation-strict: no
+ # Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
+ # and other denials, using information from previous NXDOMAINs answers.
+ # aggressive-nsec: no
+
# Use 0x20-encoded random bits in the query to foil spoof attempts.
# This feature is an experimental implementation of draft dns-0x20.
# use-caps-for-id: no
@@ -627,6 +631,7 @@ server:
# o inform_deny drops queries and logs client IP address
# o always_transparent, always_refuse, always_nxdomain, resolve in
# that way but ignore local data for that name.
+ # o noview breaks out of that view towards global local-zones.
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
# and nxdomain for AS112 zones. If you configure one of these zones
@@ -659,16 +664,19 @@ server:
# add a netblock specific override to a localzone, with zone type
# local-zone-override: "example.com" 192.0.2.0/24 refuse
- # service clients over SSL (on the TCP sockets), with plain DNS inside
- # the SSL stream. Give the certificate to use and private key.
+ # service clients over TLS (on the TCP sockets), with plain DNS inside
+ # the TLS stream. Give the certificate to use and private key.
# default is "" (disabled). requires restart to take effect.
- # ssl-service-key: "path/to/privatekeyfile.key"
- # ssl-service-pem: "path/to/publiccertfile.pem"
- # ssl-port: 853
+ # tls-service-key: "path/to/privatekeyfile.key"
+ # tls-service-pem: "path/to/publiccertfile.pem"
+ # tls-port: 853
- # request upstream over SSL (with plain DNS inside the SSL stream).
+ # request upstream over TLS (with plain DNS inside the TLS stream).
# Default is no. Can be turned on and off with unbound-control.
- # ssl-upstream: no
+ # tls-upstream: no
+
+ # Certificates used to authenticate connections made upstream.
+ # tls-cert-bundle: ""
# DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
@@ -787,7 +795,7 @@ remote-control:
# stub-addr: 192.0.2.68
# stub-prime: no
# stub-first: no
-# stub-ssl-upstream: no
+# stub-tls-upstream: no
# stub-zone:
# name: "example.org"
# stub-host: ns.example.com.
@@ -803,7 +811,7 @@ remote-control:
# forward-addr: 192.0.2.68
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
# forward-first: no
-# forward-ssl-upstream: no
+# forward-tls-upstream: no
# forward-zone:
# name: "example.org"
# forward-host: fwd.example.com
@@ -814,11 +822,12 @@ remote-control:
# upstream (which saves a lookup to the upstream). The first example
# has a copy of the root for local usage. The second serves example.org
# authoritatively. zonefile: reads from file (and writes to it if you also
-# download it), master: fetches with AXFR, url: fetches zonefile over http.
+# download it), master: fetches with AXFR and IXFR, or url to zonefile.
# auth-zone:
# name: "."
# for-downstream: no
# for-upstream: yes
+# fallback-enabled: yes
# master: b.root-servers.net
# master: c.root-servers.net
# master: e.root-servers.net
@@ -830,7 +839,6 @@ remote-control:
# for-downstream: yes
# for-upstream: yes
# zonefile: "example.org.zone"
-# url: "http://www.example.com/example.org.zone"
# Views
# Create named views. Name must be unique. Map views to requests using
diff --git a/usr.sbin/unbound/doc/unbound.conf.5.in b/usr.sbin/unbound/doc/unbound.conf.5.in
index 7dc507c86a7..b83e8808dfe 100644
--- a/usr.sbin/unbound/doc/unbound.conf.5.in
+++ b/usr.sbin/unbound/doc/unbound.conf.5.in
@@ -252,7 +252,7 @@ silently (unless verbosity 3) without the option.
.B ip\-transparent: \fI<yes or no>
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
is listening for incoming traffic. Default no. Allows you to bind to
-non\-local interfaces. For example for non\-existant IP addresses that
+non\-local interfaces. For example for non\-existent IP addresses that
are going to exist later on, with host failover configuration. This is
a lot like interface\-automatic, but that one services all interfaces
and with this option you can select which (future) interfaces unbound
@@ -362,29 +362,51 @@ Enable udp upstream even if do-udp is no. Default is no, and this does not
change anything. Useful for TLS service providers, that want no udp downstream
but use udp to fetch data upstream.
.TP
-.B ssl\-upstream: \fI<yes or no>
-Enabled or disable whether the upstream queries use SSL only for transport.
-Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in
+.B tls\-upstream: \fI<yes or no>
+Enabled or disable whether the upstream queries use TLS only for transport.
+Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
TCP wireformat. The other server must support this (see
-\fBssl\-service\-key\fR).
+\fBtls\-service\-key\fR).
+.TP
+.B ssl\-upstream: \fI<yes or no>
+Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
+file the last is used.
.TP
-.B ssl\-service-key: \fI<file>
-If enabled, the server provider SSL service on its TCP sockets. The clients
-have to use ssl\-upstream: yes. The file is the private key for the TLS
-session. The public certificate is in the ssl\-service\-pem file. Default
+.B tls\-service\-key: \fI<file>
+If enabled, the server provider TLS service on its TCP sockets. The clients
+have to use tls\-upstream: yes. The file is the private key for the TLS
+session. The public certificate is in the tls\-service\-pem file. Default
is "", turned off. Requires a restart (a reload is not enough) if changed,
because the private key is read while root permissions are held and before
chroot (if any). Normal DNS TCP service is not provided and gives errors,
this service is best run with a different \fBport:\fR config or \fI@port\fR
suffixes in the \fBinterface\fR config.
.TP
-.B ssl\-service\-pem: \fI<file>
-The public key certificate pem file for the ssl service. Default is "",
+.B ssl\-service\-key: \fI<file>
+Alternate syntax for \fBtls\-service\-key\fR.
+.TP
+.B tls\-service\-pem: \fI<file>
+The public key certificate pem file for the tls service. Default is "",
turned off.
.TP
+.B ssl\-service\-pem: \fI<file>
+Alternate syntax for \fBtls\-service\-pem\fR.
+.TP
+.B tls\-port: \fI<number>
+The port number on which to provide TCP TLS service, default 853, only
+interfaces configured with that port number as @number get the TLS service.
+.TP
.B ssl\-port: \fI<number>
-The port number on which to provide TCP SSL service, default 853, only
-interfaces configured with that port number as @number get the SSL service.
+Alternate syntax for \fBtls\-port\fR.
+.TP
+.B tls\-cert\-bundle: \fI<file>
+If null or "", no file is used. Set it to the certificate bundle file,
+for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used
+for authenticating connections made to outside peers. For example auth\-zone
+urls, and also DNS over TLS connections.
+.TP
+.B ssl\-cert\-bundle: \fI<file>
+Alternate syntax for \fBtls\-cert\-bundle\fR.
.TP
.B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation.
@@ -658,6 +680,12 @@ potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is off.
.TP
+.B aggressive\-nsec: \fI<yes or no>
+Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
+and other denials, using information from previous NXDOMAINs answers.
+Default is no. It helps to reduce the query rate towards targets that get
+a very high nonexistent name lookup rate.
+.TP
.B private\-address: \fI<IP address or subnet>
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
on your private network, and are not allowed to be returned for
@@ -933,7 +961,7 @@ address space are not validated. This is usually required whenever
Configure a local zone. The type determines the answer to give if
there is no match from local\-data. The types are deny, refuse, static,
transparent, redirect, nodefault, typetransparent, inform, inform_deny,
-always_transparent, always_refuse, always_nxdomain,
+always_transparent, always_refuse, always_nxdomain, noview,
and are explained below. After that the default settings are listed. Use
local\-data: to enter data into the local zone. Answers for local zones
are authoritative DNS answers. By default the zones are class IN.
@@ -1003,6 +1031,13 @@ Like refuse, but ignores local data and refuses the query.
\h'5'\fIalways_nxdomain\fR
Like static, but ignores local data and returns nxdomain for the query.
.TP 10
+\h'5'\fInoview\fR
+Breaks out of that view and moves towards the global local zones for answer
+to the query. If the view first is no, it'll resolve normally. If view first
+is enabled, it'll break perform that step and check the global answers.
+For when the view has view specific overrides but some zone has to be
+answered from global local zone contents.
+.TP 10
\h'5'\fInodefault\fR
Used to turn off default contents for AS112 zones. The other types
also turn off default contents for the zone. The 'nodefault' option
@@ -1066,7 +1101,7 @@ local\-data: "onion. 10800 IN
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
.fi
.TP 10
-\h'5'\fItest (RFC 7686)\fR
+\h'5'\fItest (RFC 2606)\fR
Default content:
.nf
local\-zone: "test." static
@@ -1075,7 +1110,7 @@ local\-data: "test. 10800 IN
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
.fi
.TP 10
-\h'5'\fIinvalid (RFC 7686)\fR
+\h'5'\fIinvalid (RFC 2606)\fR
Default content:
.nf
local\-zone: "invalid." static
@@ -1230,7 +1265,7 @@ In the
clause are the declarations for the remote control facility. If this is
enabled, the \fIunbound\-control\fR(8) utility can be used to send
commands to the running unbound server. The server uses these clauses
-to setup SSLv3 / TLSv1 security for the connection. The
+to setup TLSv1 security for the connection. The
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
section for options. To setup the correct self\-signed certificates use the
\fIunbound\-control\-setup\fR(8) utility.
@@ -1335,9 +1370,12 @@ The data could not be retrieved and would have caused SERVFAIL because
the servers are unreachable, instead it is tried without this clause.
The default is no.
.TP
-.B stub\-ssl\-upstream: \fI<yes or no>
-Enabled or disable whether the queries to this stub use SSL for transport.
+.B stub\-tls\-upstream: \fI<yes or no>
+Enabled or disable whether the queries to this stub use TLS for transport.
Default is no.
+.TP
+.B stub\-ssl\-upstream: \fI<yes or no>
+Alternate syntax for \fBstub\-tls\-upstream\fR.
.SS "Forward Zone Options"
.LP
There may be multiple
@@ -1372,9 +1410,73 @@ The data could not be retrieved and would have caused SERVFAIL because
the servers are unreachable, instead it is tried without this clause.
The default is no.
.TP
-.B forward\-ssl\-upstream: \fI<yes or no>
-Enabled or disable whether the queries to this forwarder use SSL for transport.
+.B forward\-tls\-upstream: \fI<yes or no>
+Enabled or disable whether the queries to this forwarder use TLS for transport.
Default is no.
+.TP
+.B forward\-ssl\-upstream: \fI<yes or no>
+Alternate syntax for \fBforward\-tls\-upstream\fR.
+.SS "Authority Zone Options"
+.LP
+Authority zones are configured with \fBauth\-zone:\fR, and each one must
+have a \fBname:\fR. There can be multiple ones, by listing multiple auth\-zone clauses, each with a different name, pertaining to that part of the namespace.
+The authority zone with the name closest to the name looked up is used.
+Authority zones are processed after \fBlocal\-zones\fR and before
+cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner
+make unbound respond like an authority server. Authority zones are also
+processed after cache, just before going to the network to fetch
+information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used
+in this manner provide a local copy of an authority server that speeds up
+lookups of that data.
+.LP
+Authority zones can be read from zonefile. And can be kept updated via
+AXFR and IXFR. After update the zonefile is rewritten. The update mechanism
+uses the SOA timer values and performs SOA UDP queries to detect zone changes.
+.TP
+.B name: \fI<zone name>
+Name of the authority zone.
+.TP
+.B master: \fI<IP address or host name>
+Where to download a copy of the zone from, with AXFR and IXFR. Multiple
+masters can be specified. They are all tried if one fails.
+.TP
+.B url: \fI<url to zonefile>
+Where to download a zonefile for the zone. With http or https. An example
+for the url is "http://www.example.com/example.org.zone". Multiple url
+statements can be given, they are tried in turn. If only urls are given
+the SOA refresh timer is used to wait for making new downloads. If also
+masters are listed, the masters are first probed with UDP SOA queries to
+see if the SOA serial number has changed, reducing the number of downloads.
+If none of the urls work, the masters are tried with IXFR and AXFR.
+For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
+to authenticate the connection.
+.TP
+.B fallback\-enabled: \fI<yes or no>
+Default no. If enabled, unbound falls back to querying the internet as
+a resolver for this zone when lookups fail. For example for DNSSEC
+validation failures.
+.TP
+.B for\-downstream: \fI<yes or no>
+Default yes. If enabled, unbound serves authority responses to
+downstream clients for this zone. This option makes unbound behave, for
+the queries with names in this zone, like one of the authority servers for
+that zone. Turn it off if you want unbound to provide recursion for the
+zone but have a local copy of zone data. If for\-downstream is no and
+for\-upstream is yes, then unbound will DNSSEC validate the contents of the
+zone before serving the zone contents to clients and store validation
+results in the cache.
+.TP
+.B for\-upstream: \fI<yes or no>
+Default yes. If enabled, unbound fetches data from this data collection
+for answering recursion queries. Instead of sending queries over the internet
+to the authority servers for this zone, it'll fetch the data directly from
+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 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
+data (eg. from the master servers).
.SS "View Options"
.LP
There may be multiple
@@ -1479,7 +1581,7 @@ but do not want to advertise over \fBdnscrypt\-provider\fR's TXT record certs
distribution.
A typical use case is when rotating certificates, existing clients may still use
the client magic from the old cert in their queries until they fetch and update
-the new cert. Likewise, it would allow to prime the new cert/key without
+the new cert. Likewise, it would allow one to prime the new cert/key without
distributing the new cert yet, this can be useful when using a network of
servers using anycast and on which the configuration may not get updated at the
exact same time. By priming the cert, the servers can handle both old and new
diff --git a/usr.sbin/unbound/edns-subnet/addrtree.c b/usr.sbin/unbound/edns-subnet/addrtree.c
index 050eb31fc98..9a02db062c5 100644
--- a/usr.sbin/unbound/edns-subnet/addrtree.c
+++ b/usr.sbin/unbound/edns-subnet/addrtree.c
@@ -485,7 +485,7 @@ addrtree_find(struct addrtree *tree, const addrkey_t *addr,
/* does this node have data? if yes, see if we have a match */
if (node->elem && node->ttl >= now) {
/* saved at wrong depth */;
- log_assert(node->scope >= depth)
+ log_assert(node->scope >= depth);
if (depth == node->scope ||
(node->scope > sourcemask &&
depth == sourcemask)) {
diff --git a/usr.sbin/unbound/edns-subnet/subnetmod.c b/usr.sbin/unbound/edns-subnet/subnetmod.c
index 4b8a4b21127..ae2523b86c2 100644
--- a/usr.sbin/unbound/edns-subnet/subnetmod.c
+++ b/usr.sbin/unbound/edns-subnet/subnetmod.c
@@ -339,6 +339,7 @@ update_cache(struct module_qstate *qstate, int id)
return;
}
lru_entry = &mrep_entry->entry;
+ lock_rw_wrlock(&lru_entry->lock);
lru_entry->data = calloc(1,
sizeof(struct subnet_msg_cache_data));
if (!lru_entry->data) {
@@ -352,7 +353,9 @@ update_cache(struct module_qstate *qstate, int id)
log_err("Subnet cache insertion failed");
return;
}
+ lock_quick_lock(&sne->alloc.lock);
rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL);
+ lock_quick_unlock(&sne->alloc.lock);
if (!rep) {
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
log_err("Subnet cache insertion failed");
@@ -374,6 +377,7 @@ update_cache(struct module_qstate *qstate, int id)
if (acquired_lock) {
lock_rw_unlock(&lru_entry->lock);
} else {
+ lock_rw_unlock(&lru_entry->lock);
slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
NULL);
}
diff --git a/usr.sbin/unbound/iterator/iter_delegpt.h b/usr.sbin/unbound/iterator/iter_delegpt.h
index 4bd79c81af0..24f0574901d 100644
--- a/usr.sbin/unbound/iterator/iter_delegpt.h
+++ b/usr.sbin/unbound/iterator/iter_delegpt.h
@@ -83,6 +83,8 @@ struct delegpt {
uint8_t dp_type_mlc;
/** use SSL for upstream query */
uint8_t ssl_upstream;
+ /** delegpt from authoritative zone that is locally hosted */
+ uint8_t auth_dp;
};
/**
diff --git a/usr.sbin/unbound/iterator/iterator.c b/usr.sbin/unbound/iterator/iterator.c
index d95a6e03459..7f3c65737d5 100644
--- a/usr.sbin/unbound/iterator/iterator.c
+++ b/usr.sbin/unbound/iterator/iterator.c
@@ -53,6 +53,7 @@
#include "validator/val_neg.h"
#include "services/cache/dns.h"
#include "services/cache/infra.h"
+#include "services/authzone.h"
#include "util/module.h"
#include "util/netevent.h"
#include "util/net_help.h"
@@ -771,6 +772,11 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
if(!stub)
return 0;
stub_dp = stub->dp;
+ /* if we have an auth_zone dp, and stub is equal, don't prime stub
+ * yet, unless we want to fallback and avoid the auth_zone */
+ if(!iq->auth_zone_avoid && iq->dp && iq->dp->auth_dp &&
+ query_dname_compare(iq->dp->name, stub_dp->name) == 0)
+ return 0;
/* is it a noprime stub (always use) */
if(stub->noprime) {
@@ -832,6 +838,96 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
}
/**
+ * Generate a delegation point for an auth zone (unless cached dp is better)
+ * false on alloc failure.
+ */
+static int
+auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
+ uint8_t* delname, size_t delnamelen)
+{
+ struct auth_zone* z;
+ if(iq->auth_zone_avoid)
+ return 1;
+ if(!delname) {
+ delname = iq->qchase.qname;
+ delnamelen = iq->qchase.qname_len;
+ }
+ lock_rw_rdlock(&qstate->env->auth_zones->lock);
+ z = auth_zones_find_zone(qstate->env->auth_zones, delname, delnamelen,
+ qstate->qinfo.qclass);
+ if(!z) {
+ lock_rw_unlock(&qstate->env->auth_zones->lock);
+ return 1;
+ }
+ lock_rw_rdlock(&z->lock);
+ lock_rw_unlock(&qstate->env->auth_zones->lock);
+ if(z->for_upstream) {
+ if(iq->dp && query_dname_compare(z->name, iq->dp->name) == 0
+ && iq->dp->auth_dp && qstate->blacklist &&
+ z->fallback_enabled) {
+ /* cache is blacklisted and fallback, and we
+ * already have an auth_zone dp */
+ if(verbosity>=VERB_ALGO) {
+ char buf[255+1];
+ dname_str(z->name, buf);
+ verbose(VERB_ALGO, "auth_zone %s "
+ "fallback because cache blacklisted",
+ buf);
+ }
+ lock_rw_unlock(&z->lock);
+ iq->dp = NULL;
+ return 1;
+ }
+ if(iq->dp==NULL || dname_subdomain_c(z->name, iq->dp->name)) {
+ struct delegpt* dp;
+ if(qstate->blacklist && z->fallback_enabled) {
+ /* cache is blacklisted because of a DNSSEC
+ * validation failure, and the zone allows
+ * fallback to the internet, query there. */
+ if(verbosity>=VERB_ALGO) {
+ char buf[255+1];
+ dname_str(z->name, buf);
+ verbose(VERB_ALGO, "auth_zone %s "
+ "fallback because cache blacklisted",
+ buf);
+ }
+ lock_rw_unlock(&z->lock);
+ return 1;
+ }
+ dp = (struct delegpt*)regional_alloc_zero(
+ qstate->region, sizeof(*dp));
+ if(!dp) {
+ log_err("alloc failure");
+ if(z->fallback_enabled) {
+ lock_rw_unlock(&z->lock);
+ return 1; /* just fallback */
+ }
+ lock_rw_unlock(&z->lock);
+ return 0;
+ }
+ dp->name = regional_alloc_init(qstate->region,
+ z->name, z->namelen);
+ if(!dp->name) {
+ log_err("alloc failure");
+ if(z->fallback_enabled) {
+ lock_rw_unlock(&z->lock);
+ return 1; /* just fallback */
+ }
+ lock_rw_unlock(&z->lock);
+ return 0;
+ }
+ dp->namelen = z->namelen;
+ dp->namelabs = z->namelabs;
+ dp->auth_dp = 1;
+ iq->dp = dp;
+ }
+ }
+
+ lock_rw_unlock(&z->lock);
+ return 1;
+}
+
+/**
* Generate A and AAAA checks for glue that is in-zone for the referral
* we just got to obtain authoritative information on the addresses.
*
@@ -1109,14 +1205,15 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
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);
+ qstate->region, qstate->env->scratch, 0);
if(!msg && qstate->env->neg_cache) {
/* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
qstate->region, qstate->env->rrset_cache,
qstate->env->scratch_buffer,
- *qstate->env->now, 1/*add SOA*/, NULL);
+ *qstate->env->now, 1/*add SOA*/, NULL,
+ qstate->env->cfg);
}
/* item taken from cache does not match our query name, thus
* security needs to be re-examined later */
@@ -1167,7 +1264,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response = msg;
return final_state(iq);
}
-
+
/* attempt to forward the request */
if(forward_request(qstate, iq))
{
@@ -1228,8 +1325,15 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* If the cache has returned nothing, then we have a
* root priming situation. */
if(iq->dp == NULL) {
+ int r;
+ /* if under auth zone, no prime needed */
+ if(!auth_zone_delegpt(qstate, iq, delname, delnamelen))
+ return error_response(qstate, id,
+ LDNS_RCODE_SERVFAIL);
+ if(iq->dp) /* use auth zone dp */
+ return next_state(iq, INIT_REQUEST_2_STATE);
/* if there is a stub, then no root prime needed */
- int r = prime_stub(qstate, iq, id, delname,
+ r = prime_stub(qstate, iq, id, delname,
iq->qchase.qclass);
if(r == 2)
break; /* got noprime-stub-zone, continue */
@@ -1398,6 +1502,12 @@ processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
dname_remove_label(&delname, &delnamelen);
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
}
+
+ /* see if we have an auth zone to answer from, improves dp from cache
+ * (if any dp from cache) with auth zone dp, if that is lower */
+ if(!auth_zone_delegpt(qstate, iq, delname, delnamelen))
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+
/* Check to see if we need to prime a stub zone. */
if(prime_stub(qstate, iq, id, delname, iq->qchase.qclass)) {
/* A priming sub request was made */
@@ -1882,6 +1992,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int tf_policy;
struct delegpt_addr* target;
struct outbound_entry* outq;
+ int auth_fallback = 0;
/* NOTE: a request will encounter this state for each target it
* needs to send a query to. That is, at least one per referral,
@@ -1926,6 +2037,152 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
+ if(iq->minimisation_state == INIT_MINIMISE_STATE) {
+ /* (Re)set qinfo_out to (new) delegation point, except when
+ * qinfo_out is already a subdomain of dp. This happens when
+ * increasing by more than one label at once (QNAMEs with more
+ * than MAX_MINIMISE_COUNT labels). */
+ if(!(iq->qinfo_out.qname_len
+ && dname_subdomain_c(iq->qchase.qname,
+ iq->qinfo_out.qname)
+ && dname_subdomain_c(iq->qinfo_out.qname,
+ iq->dp->name))) {
+ iq->qinfo_out.qname = iq->dp->name;
+ iq->qinfo_out.qname_len = iq->dp->namelen;
+ iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
+ iq->qinfo_out.qclass = iq->qchase.qclass;
+ iq->qinfo_out.local_alias = NULL;
+ iq->minimise_count = 0;
+ }
+
+ iq->minimisation_state = MINIMISE_STATE;
+ }
+ if(iq->minimisation_state == MINIMISE_STATE) {
+ int qchaselabs = dname_count_labels(iq->qchase.qname);
+ int labdiff = qchaselabs -
+ dname_count_labels(iq->qinfo_out.qname);
+
+ iq->qinfo_out.qname = iq->qchase.qname;
+ iq->qinfo_out.qname_len = iq->qchase.qname_len;
+ iq->minimise_count++;
+ iq->minimise_timeout_count = 0;
+
+ iter_dec_attempts(iq->dp, 1);
+
+ /* Limit number of iterations for QNAMEs with more
+ * than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
+ * labels of QNAME always individually.
+ */
+ if(qchaselabs > MAX_MINIMISE_COUNT && labdiff > 1 &&
+ iq->minimise_count > MINIMISE_ONE_LAB) {
+ if(iq->minimise_count < MAX_MINIMISE_COUNT) {
+ int multilabs = qchaselabs - 1 -
+ MINIMISE_ONE_LAB;
+ int extralabs = multilabs /
+ MINIMISE_MULTIPLE_LABS;
+
+ if (MAX_MINIMISE_COUNT - iq->minimise_count >=
+ multilabs % MINIMISE_MULTIPLE_LABS)
+ /* Default behaviour is to add 1 label
+ * every iteration. Therefore, decrement
+ * the extralabs by 1 */
+ extralabs--;
+ if (extralabs < labdiff)
+ labdiff -= extralabs;
+ else
+ labdiff = 1;
+ }
+ /* Last minimised iteration, send all labels with
+ * QTYPE=NS */
+ else
+ labdiff = 1;
+ }
+
+ if(labdiff > 1) {
+ verbose(VERB_QUERY, "removing %d labels", labdiff-1);
+ dname_remove_labels(&iq->qinfo_out.qname,
+ &iq->qinfo_out.qname_len,
+ labdiff-1);
+ }
+ if(labdiff < 1 || (labdiff < 2
+ && (iq->qchase.qtype == LDNS_RR_TYPE_DS
+ || iq->qchase.qtype == LDNS_RR_TYPE_A)))
+ /* Stop minimising this query, resolve "as usual" */
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
+ else if(!qstate->no_cache_lookup) {
+ struct dns_msg* msg = dns_cache_lookup(qstate->env,
+ 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);
+ if(msg && msg->rep->an_numrrsets == 0
+ && FLAGS_GET_RCODE(msg->rep->flags) ==
+ LDNS_RCODE_NOERROR)
+ /* no need to send query if it is already
+ * cached as NOERROR/NODATA */
+ return 1;
+ }
+ }
+ if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
+ if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
+ /* Do not increment qname, continue incrementing next
+ * iteration */
+ iq->minimisation_state = MINIMISE_STATE;
+ else if(!qstate->env->cfg->qname_minimisation_strict)
+ /* Too many time-outs detected for this QNAME and QTYPE.
+ * We give up, disable QNAME minimisation. */
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
+ }
+ if(iq->minimisation_state == DONOT_MINIMISE_STATE)
+ iq->qinfo_out = iq->qchase;
+
+ /* now find an answer to this query */
+ /* see if authority zones have an answer */
+ /* now we know the dp, we can check the auth zone for locally hosted
+ * contents */
+ if(!iq->auth_zone_avoid && qstate->blacklist) {
+ if(auth_zones_can_fallback(qstate->env->auth_zones,
+ iq->dp->name, iq->dp->namelen, iq->qinfo_out.qclass)) {
+ /* if cache is blacklisted and this zone allows us
+ * to fallback to the internet, then do so, and
+ * fetch results from the internet servers */
+ iq->auth_zone_avoid = 1;
+ }
+ }
+ if(iq->auth_zone_avoid) {
+ iq->auth_zone_avoid = 0;
+ auth_fallback = 1;
+ } else if(auth_zones_lookup(qstate->env->auth_zones, &iq->qinfo_out,
+ qstate->region, &iq->response, &auth_fallback, iq->dp->name,
+ iq->dp->namelen)) {
+ /* use this as a response to be processed by the iterator */
+ if(verbosity >= VERB_ALGO) {
+ log_dns_msg("msg from auth zone",
+ &iq->response->qinfo, iq->response->rep);
+ }
+ iq->num_current_queries++;
+ iq->chase_to_rd = 0;
+ iq->dnssec_lame_query = 0;
+ iq->auth_zone_response = 1;
+ return next_state(iq, QUERY_RESP_STATE);
+ }
+ iq->auth_zone_response = 0;
+ if(auth_fallback == 0) {
+ /* like we got servfail from the auth zone lookup, and
+ * no internet fallback */
+ verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
+ " servfail");
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ }
+ if(iq->dp && iq->dp->auth_dp) {
+ /* we wanted to fallback, but had no delegpt, only the
+ * auth zone generated delegpt, create an actual one */
+ iq->auth_zone_avoid = 1;
+ return next_state(iq, INIT_REQUEST_STATE);
+ }
+ /* but mostly, fallback==1 (like, when no such auth zone exists)
+ * and we continue with lookups */
+
tf_policy = 0;
/* < not <=, because although the array is large enough for <=, the
* generated query will immediately be discarded due to depth and
@@ -2093,105 +2350,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
- if(iq->minimisation_state == INIT_MINIMISE_STATE) {
- /* (Re)set qinfo_out to (new) delegation point, except when
- * qinfo_out is already a subdomain of dp. This happens when
- * increasing by more than one label at once (QNAMEs with more
- * than MAX_MINIMISE_COUNT labels). */
- if(!(iq->qinfo_out.qname_len
- && dname_subdomain_c(iq->qchase.qname,
- iq->qinfo_out.qname)
- && dname_subdomain_c(iq->qinfo_out.qname,
- iq->dp->name))) {
- iq->qinfo_out.qname = iq->dp->name;
- iq->qinfo_out.qname_len = iq->dp->namelen;
- iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
- iq->qinfo_out.qclass = iq->qchase.qclass;
- iq->qinfo_out.local_alias = NULL;
- iq->minimise_count = 0;
- }
-
- iq->minimisation_state = MINIMISE_STATE;
- }
- if(iq->minimisation_state == MINIMISE_STATE) {
- int qchaselabs = dname_count_labels(iq->qchase.qname);
- int labdiff = qchaselabs -
- dname_count_labels(iq->qinfo_out.qname);
-
- iq->qinfo_out.qname = iq->qchase.qname;
- iq->qinfo_out.qname_len = iq->qchase.qname_len;
- iq->minimise_count++;
- iq->minimise_timeout_count = 0;
-
- iter_dec_attempts(iq->dp, 1);
-
- /* Limit number of iterations for QNAMEs with more
- * than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
- * labels of QNAME always individually.
- */
- if(qchaselabs > MAX_MINIMISE_COUNT && labdiff > 1 &&
- iq->minimise_count > MINIMISE_ONE_LAB) {
- if(iq->minimise_count < MAX_MINIMISE_COUNT) {
- int multilabs = qchaselabs - 1 -
- MINIMISE_ONE_LAB;
- int extralabs = multilabs /
- MINIMISE_MULTIPLE_LABS;
-
- if (MAX_MINIMISE_COUNT - iq->minimise_count >=
- multilabs % MINIMISE_MULTIPLE_LABS)
- /* Default behaviour is to add 1 label
- * every iteration. Therefore, decrement
- * the extralabs by 1 */
- extralabs--;
- if (extralabs < labdiff)
- labdiff -= extralabs;
- else
- labdiff = 1;
- }
- /* Last minimised iteration, send all labels with
- * QTYPE=NS */
- else
- labdiff = 1;
- }
-
- if(labdiff > 1) {
- verbose(VERB_QUERY, "removing %d labels", labdiff-1);
- dname_remove_labels(&iq->qinfo_out.qname,
- &iq->qinfo_out.qname_len,
- labdiff-1);
- }
- if(labdiff < 1 || (labdiff < 2
- && (iq->qchase.qtype == LDNS_RR_TYPE_DS
- || iq->qchase.qtype == LDNS_RR_TYPE_A)))
- /* Stop minimising this query, resolve "as usual" */
- iq->minimisation_state = DONOT_MINIMISE_STATE;
- else if(!qstate->no_cache_lookup) {
- struct dns_msg* msg = dns_cache_lookup(qstate->env,
- 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);
- if(msg && msg->rep->an_numrrsets == 0
- && FLAGS_GET_RCODE(msg->rep->flags) ==
- LDNS_RCODE_NOERROR)
- /* no need to send query if it is already
- * cached as NOERROR/NODATA */
- return 1;
- }
- }
- if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
- if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
- /* Do not increment qname, continue incrementing next
- * iteration */
- iq->minimisation_state = MINIMISE_STATE;
- else if(!qstate->env->cfg->qname_minimisation_strict)
- /* Too many time-outs detected for this QNAME and QTYPE.
- * We give up, disable QNAME minimisation. */
- iq->minimisation_state = DONOT_MINIMISE_STATE;
- }
- if(iq->minimisation_state == DONOT_MINIMISE_STATE)
- iq->qinfo_out = iq->qchase;
-
/* We have a valid target. */
if(verbosity >= VERB_QUERY) {
log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out);
@@ -2584,6 +2742,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->deleg_msg = NULL;
iq->dp = NULL;
iq->dsns_point = NULL;
+ iq->auth_zone_response = 0;
/* Note the query restart. */
iq->query_restart_count++;
iq->sent_count = 0;
@@ -2656,6 +2815,25 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
if (qstate->env->cfg->qname_minimisation &&
!qstate->env->cfg->qname_minimisation_strict)
iq->minimisation_state = DONOT_MINIMISE_STATE;
+ if(iq->auth_zone_response) {
+ /* can we fallback? */
+ iq->auth_zone_response = 0;
+ if(!auth_zones_can_fallback(qstate->env->auth_zones,
+ iq->dp->name, iq->dp->namelen, qstate->qinfo.qclass)) {
+ verbose(VERB_ALGO, "auth zone response bad, and no"
+ " fallback possible, servfail");
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ }
+ verbose(VERB_ALGO, "auth zone response was bad, "
+ "fallback enabled");
+ iq->auth_zone_avoid = 1;
+ if(iq->dp->auth_dp) {
+ /* we are using a dp for the auth zone, with no
+ * nameservers, get one first */
+ iq->dp = NULL;
+ return next_state(iq, INIT_REQUEST_STATE);
+ }
+ }
return next_state(iq, QUERYTARGETS_STATE);
}
diff --git a/usr.sbin/unbound/iterator/iterator.h b/usr.sbin/unbound/iterator/iterator.h
index 841a3643669..67ffeb14763 100644
--- a/usr.sbin/unbound/iterator/iterator.h
+++ b/usr.sbin/unbound/iterator/iterator.h
@@ -387,6 +387,11 @@ struct iter_qstate {
* Count number of time-outs. Used to prevent resolving failures when
* the QNAME minimisation QTYPE is blocked. */
int minimise_timeout_count;
+
+ /** True if the current response is from auth_zone */
+ int auth_zone_response;
+ /** True if the auth_zones should not be consulted for the query */
+ int auth_zone_avoid;
};
/**
diff --git a/usr.sbin/unbound/libunbound/context.c b/usr.sbin/unbound/libunbound/context.c
index e203111b70d..8bff713bca3 100644
--- a/usr.sbin/unbound/libunbound/context.c
+++ b/usr.sbin/unbound/libunbound/context.c
@@ -47,6 +47,7 @@
#include "services/localzone.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
+#include "services/authzone.h"
#include "util/data/msgreply.h"
#include "util/storage/slabhash.h"
#include "sldns/sbuffer.h"
@@ -68,6 +69,8 @@ context_finalize(struct ub_ctx* ctx)
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))
+ return UB_INITFAIL;
if(!ctx->env->msg_cache ||
cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) ||
cfg->msg_cache_slabs != ctx->env->msg_cache->size) {
diff --git a/usr.sbin/unbound/libunbound/libunbound.c b/usr.sbin/unbound/libunbound/libunbound.c
index 9b4dcab1579..b4cd7fa0bcc 100644
--- a/usr.sbin/unbound/libunbound/libunbound.c
+++ b/usr.sbin/unbound/libunbound/libunbound.c
@@ -62,6 +62,7 @@
#include "services/localzone.h"
#include "services/cache/infra.h"
#include "services/cache/rrset.h"
+#include "services/authzone.h"
#include "sldns/sbuffer.h"
#ifdef HAVE_PTHREAD
#include <signal.h>
@@ -88,6 +89,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
WSADATA wsa_data;
#endif
+ checklock_start();
log_init(NULL, 0, NULL); /* logs to stderr */
log_ident_set("libunbound");
#ifdef USE_WINSOCK
@@ -141,6 +143,16 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM;
return NULL;
}
+ ctx->env->auth_zones = auth_zones_create();
+ if(!ctx->env->auth_zones) {
+ edns_known_options_delete(ctx->env);
+ config_delete(ctx->env->cfg);
+ free(ctx->env);
+ ub_randfree(ctx->seed_rnd);
+ free(ctx);
+ errno = ENOMEM;
+ return NULL;
+ }
ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL;
ctx->env->need_to_validate = 0;
@@ -310,6 +322,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
+ auth_zones_delete(ctx->env->auth_zones);
free(ctx->env);
}
ub_randfree(ctx->seed_rnd);
diff --git a/usr.sbin/unbound/libunbound/libworker.c b/usr.sbin/unbound/libunbound/libworker.c
index c991d5df3f4..2c7b2cf072a 100644
--- a/usr.sbin/unbound/libunbound/libworker.c
+++ b/usr.sbin/unbound/libunbound/libworker.c
@@ -55,6 +55,7 @@
#include "services/localzone.h"
#include "services/cache/rrset.h"
#include "services/outbound_list.h"
+#include "services/authzone.h"
#include "util/fptr_wlist.h"
#include "util/module.h"
#include "util/regional.h"
@@ -158,7 +159,8 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
w->env->hints = NULL;
}
if(cfg->ssl_upstream) {
- w->sslctx = connect_sslctx_create(NULL, NULL, NULL);
+ w->sslctx = connect_sslctx_create(NULL, NULL,
+ cfg->tls_cert_bundle);
if(!w->sslctx) {
/* to make the setup fail after unlock */
hints_delete(w->env->hints);
@@ -604,6 +606,15 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
free(qinfo.qname);
return UB_NOERROR;
}
+ if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
+ w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
+ regional_free_all(w->env->scratch);
+ libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
+ w->back->udp_buff, sec_status_insecure, NULL);
+ libworker_delete(w);
+ free(qinfo.qname);
+ return UB_NOERROR;
+ }
/* process new query */
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
w->back->udp_buff, qid, libworker_fg_done_cb, q)) {
@@ -674,6 +685,14 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
w->back->udp_buff, sec_status_insecure, NULL);
return UB_NOERROR;
}
+ if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
+ w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
+ regional_free_all(w->env->scratch);
+ free(qinfo.qname);
+ libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
+ w->back->udp_buff, sec_status_insecure, NULL);
+ return UB_NOERROR;
+ }
/* process new query */
if(async_id)
*async_id = q->querynum;
@@ -795,6 +814,14 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
free(qinfo.qname);
return;
}
+ if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
+ w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
+ regional_free_all(w->env->scratch);
+ q->msg_security = sec_status_insecure;
+ add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
+ free(qinfo.qname);
+ return;
+ }
q->w = w;
/* process new query */
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
diff --git a/usr.sbin/unbound/services/authzone.c b/usr.sbin/unbound/services/authzone.c
index 35f4cd3d41a..13e36b2cbee 100644
--- a/usr.sbin/unbound/services/authzone.c
+++ b/usr.sbin/unbound/services/authzone.c
@@ -65,8 +65,10 @@
#include "sldns/str2wire.h"
#include "sldns/wire2str.h"
#include "sldns/parseutil.h"
+#include "sldns/keyraw.h"
#include "validator/val_nsec3.h"
#include "validator/val_secalgo.h"
+#include <ctype.h>
/** bytes to use for NSEC3 hash buffer. 20 for sha1 */
#define N3HASHBUFLEN 32
@@ -78,6 +80,12 @@
#define AUTH_PROBE_TIMEOUT_STOP 1000 /* msec */
/* auth transfer timeout for TCP connections, in msec */
#define AUTH_TRANSFER_TIMEOUT 10000 /* msec */
+/* auth transfer max backoff for failed tranfers and probes */
+#define AUTH_TRANSFER_MAX_BACKOFF 86400 /* sec */
+/* auth http port number */
+#define AUTH_HTTP_PORT 80
+/* auth https port number */
+#define AUTH_HTTPS_PORT 443
/** pick up nextprobe task to start waiting to perform transfer actions */
static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
@@ -267,7 +275,6 @@ msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
struct auth_zones* auth_zones_create(void)
{
- /* TODO: create and put in env in worker and libworker */
struct auth_zones* az = (struct auth_zones*)calloc(1, sizeof(*az));
if(!az) {
log_err("out of memory");
@@ -442,30 +449,36 @@ auth_zone_find_less_equal(struct auth_zones* az, uint8_t* nm, size_t nmlen,
return rbtree_find_less_equal(&az->ztree, &key, (rbnode_type**)z);
}
-/** find the auth zone that is above the given qname */
+
+/** find the auth zone that is above the given name */
struct auth_zone*
-auth_zones_find_zone(struct auth_zones* az, struct query_info* qinfo)
+auth_zones_find_zone(struct auth_zones* az, uint8_t* name, size_t name_len,
+ uint16_t dclass)
{
- uint8_t* nm = qinfo->qname;
- size_t nmlen = qinfo->qname_len;
+ uint8_t* nm = name;
+ size_t nmlen = name_len;
struct auth_zone* z;
- if(auth_zone_find_less_equal(az, nm, nmlen, qinfo->qclass, &z)) {
+ if(auth_zone_find_less_equal(az, nm, nmlen, dclass, &z)) {
/* exact match */
return z;
} else {
/* less-or-nothing */
if(!z) return NULL; /* nothing smaller, nothing above it */
- /* we found smaller name; smaller may be above the qname,
+ /* we found smaller name; smaller may be above the name,
* but not below it. */
- nm = dname_get_shared_topdomain(z->name, qinfo->qname);
+ nm = dname_get_shared_topdomain(z->name, name);
dname_count_size_labels(nm, &nmlen);
+ z = NULL;
}
+
/* search up */
- while(!z && !dname_is_root(nm)) {
+ while(!z) {
+ z = auth_zone_find(az, nm, nmlen, dclass);
+ if(z) return z;
+ if(dname_is_root(nm)) break;
dname_remove_label(&nm, &nmlen);
- z = auth_zone_find(az, nm, nmlen, qinfo->qclass);
}
- return z;
+ return NULL;
}
/** find or create zone with name str. caller must have lock on az.
@@ -501,7 +514,6 @@ auth_zones_find_or_add_xfer(struct auth_zones* az, struct auth_zone* z)
if(!x) {
/* not found, create the zone */
x = auth_xfer_create(az, z);
- lock_basic_lock(&x->lock);
} else {
lock_basic_lock(&x->lock);
}
@@ -635,6 +647,40 @@ domain_remove_rrset(struct auth_data* node, uint16_t rr_type)
}
}
+/** find an rr index in the rrset. returns true if found */
+static int
+az_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
+ size_t* index)
+{
+ size_t i;
+ for(i=0; i<d->count; i++) {
+ if(d->rr_len[i] != len)
+ continue;
+ if(memcmp(d->rr_data[i], rdata, len) == 0) {
+ *index = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/** find an rrsig index in the rrset. returns true if found */
+static int
+az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
+ size_t* index)
+{
+ size_t i;
+ for(i=d->count; i<d->count + d->rrsig_count; i++) {
+ if(d->rr_len[i] != len)
+ continue;
+ if(memcmp(d->rr_data[i], rdata, len) == 0) {
+ *index = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
/** see if rdata is duplicate */
static int
rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata, size_t len)
@@ -662,6 +708,68 @@ rrsig_rdata_get_type_covered(uint8_t* rdata, size_t rdatalen)
return sldns_read_uint16(rdata+2);
}
+/** remove RR from existing RRset. Also sig, if it is a signature.
+ * reallocates the packed rrset for a new one, false on alloc failure */
+static int
+rrset_remove_rr(struct auth_rrset* rrset, size_t index)
+{
+ struct packed_rrset_data* d, *old = rrset->data;
+ size_t i;
+ if(index >= old->count + old->rrsig_count)
+ return 0; /* index out of bounds */
+ d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old) - (
+ sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t) +
+ old->rr_len[index]));
+ if(!d) {
+ log_err("malloc failure");
+ return 0;
+ }
+ d->ttl = old->ttl;
+ d->count = old->count;
+ d->rrsig_count = old->rrsig_count;
+ if(index < d->count) d->count--;
+ else d->rrsig_count--;
+ d->trust = old->trust;
+ d->security = old->security;
+
+ /* set rr_len, needed for ptr_fixup */
+ d->rr_len = (size_t*)((uint8_t*)d +
+ sizeof(struct packed_rrset_data));
+ if(index > 0)
+ memmove(d->rr_len, old->rr_len, (index)*sizeof(size_t));
+ if(index+1 < old->count+old->rrsig_count)
+ memmove(&d->rr_len[index], &old->rr_len[index+1],
+ (old->count+old->rrsig_count - (index+1))*sizeof(size_t));
+ packed_rrset_ptr_fixup(d);
+
+ /* move over ttls */
+ if(index > 0)
+ memmove(d->rr_ttl, old->rr_ttl, (index)*sizeof(time_t));
+ if(index+1 < old->count+old->rrsig_count)
+ memmove(&d->rr_ttl[index], &old->rr_ttl[index+1],
+ (old->count+old->rrsig_count - (index+1))*sizeof(time_t));
+
+ /* move over rr_data */
+ for(i=0; i<d->count+d->rrsig_count; i++) {
+ size_t oldi;
+ if(i < index) oldi = i;
+ else oldi = i+1;
+ memmove(d->rr_data[i], old->rr_data[oldi], d->rr_len[i]);
+ }
+
+ /* recalc ttl (lowest of remaining RR ttls) */
+ if(d->count + d->rrsig_count > 0)
+ d->ttl = d->rr_ttl[0];
+ for(i=0; i<d->count+d->rrsig_count; i++) {
+ if(d->rr_ttl[i] < d->ttl)
+ d->ttl = d->rr_ttl[i];
+ }
+
+ free(rrset->data);
+ rrset->data = d;
+ return 1;
+}
+
/** add RR to existing RRset. If insert_sig is true, add to rrsigs.
* This reallocates the packed rrset for a new one */
static int
@@ -821,7 +929,6 @@ rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type,
/* 0 rrsigs to move over, done */
return 1;
}
- log_info("moveover %d sigs size %d", (int)sigs, (int)sigsz);
/* allocate rrset sigsz larger for extra sigs elements, and
* allocate rrsig sigsz smaller for less sigs elements. */
@@ -938,11 +1045,38 @@ rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type,
return 1;
}
+/** copy the rrsigs from the rrset to the rrsig rrset, because the rrset
+ * is going to be deleted. reallocates the RRSIG rrset data. */
+static int
+rrsigs_copy_from_rrset_to_rrsigset(struct auth_rrset* rrset,
+ struct auth_rrset* rrsigset)
+{
+ size_t i;
+ if(rrset->data->rrsig_count == 0)
+ return 1;
+
+ /* move them over one by one, because there might be duplicates,
+ * duplicates are ignored */
+ for(i=rrset->data->count;
+ i<rrset->data->count+rrset->data->rrsig_count; i++) {
+ uint8_t* rdata = rrset->data->rr_data[i];
+ size_t rdatalen = rrset->data->rr_len[i];
+ time_t rr_ttl = rrset->data->rr_ttl[i];
+
+ if(rdata_duplicate(rrsigset->data, rdata, rdatalen)) {
+ continue;
+ }
+ if(!rrset_add_rr(rrsigset, rr_ttl, rdata, rdatalen, 0))
+ return 0;
+ }
+ return 1;
+}
+
/** Add rr to node, ignores duplicate RRs,
* rdata points to buffer with rdatalen octets, starts with 2bytelength. */
static int
az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
- uint8_t* rdata, size_t rdatalen)
+ uint8_t* rdata, size_t rdatalen, int* duplicate)
{
struct auth_rrset* rrset;
/* packed rrsets have their rrsigs along with them, sort them out */
@@ -951,14 +1085,18 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
if((rrset=az_domain_rrset(node, ctype))!= NULL) {
/* a node of the correct type exists, add the RRSIG
* to the rrset of the covered data type */
- if(rdata_duplicate(rrset->data, rdata, rdatalen))
+ if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
+ if(duplicate) *duplicate = 1;
return 1;
+ }
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 1))
return 0;
} else if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
/* add RRSIG to rrset of type RRSIG */
- if(rdata_duplicate(rrset->data, rdata, rdatalen))
+ if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
+ if(duplicate) *duplicate = 1;
return 1;
+ }
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
return 0;
} else {
@@ -971,8 +1109,10 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
/* normal RR type */
if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
/* add data to existing node with data type */
- if(rdata_duplicate(rrset->data, rdata, rdatalen))
+ if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
+ if(duplicate) *duplicate = 1;
return 1;
+ }
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
return 0;
} else {
@@ -999,7 +1139,7 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
/** insert RR into zone, ignore duplicates */
static int
az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
- size_t dname_len)
+ size_t dname_len, int* duplicate)
{
struct auth_data* node;
uint8_t* dname = rr;
@@ -1019,13 +1159,273 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
log_err("cannot create domain");
return 0;
}
- if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen)) {
+ if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen,
+ duplicate)) {
log_err("cannot add RR to domain");
return 0;
}
return 1;
}
+/** Remove rr from node, ignores nonexisting RRs,
+ * rdata points to buffer with rdatalen octets, starts with 2bytelength. */
+static int
+az_domain_remove_rr(struct auth_data* node, uint16_t rr_type,
+ uint8_t* rdata, size_t rdatalen, int* nonexist)
+{
+ struct auth_rrset* rrset;
+ size_t index = 0;
+
+ /* find the plain RR of the given type */
+ if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
+ if(az_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) {
+ if(rrset->data->count == 1 &&
+ rrset->data->rrsig_count == 0) {
+ /* last RR, delete the rrset */
+ domain_remove_rrset(node, rr_type);
+ } else if(rrset->data->count == 1 &&
+ rrset->data->rrsig_count != 0) {
+ /* move RRSIGs to the RRSIG rrset, or
+ * this one becomes that RRset */
+ struct auth_rrset* rrsigset = az_domain_rrset(
+ node, LDNS_RR_TYPE_RRSIG);
+ if(rrsigset) {
+ /* move left over rrsigs to the
+ * existing rrset of type RRSIG */
+ rrsigs_copy_from_rrset_to_rrsigset(
+ rrset, rrsigset);
+ /* and then delete the rrset */
+ domain_remove_rrset(node, rr_type);
+ } else {
+ /* no rrset of type RRSIG, this
+ * set is now of that type,
+ * just remove the rr */
+ if(!rrset_remove_rr(rrset, index))
+ return 0;
+ rrset->type = LDNS_RR_TYPE_RRSIG;
+ rrset->data->count = rrset->data->rrsig_count;
+ rrset->data->rrsig_count = 0;
+ }
+ } else {
+ /* remove the RR from the rrset */
+ if(!rrset_remove_rr(rrset, index))
+ return 0;
+ }
+ return 1;
+ }
+ /* rr not found in rrset */
+ }
+
+ /* is it a type RRSIG, look under the covered type */
+ if(rr_type == LDNS_RR_TYPE_RRSIG) {
+ uint16_t ctype = rrsig_rdata_get_type_covered(rdata, rdatalen);
+ if((rrset=az_domain_rrset(node, ctype))!= NULL) {
+ if(az_rrset_find_rrsig(rrset->data, rdata, rdatalen,
+ &index)) {
+ /* rrsig should have d->count > 0, be
+ * over some rr of that type */
+ /* remove the rrsig from the rrsigs list of the
+ * rrset */
+ if(!rrset_remove_rr(rrset, index))
+ return 0;
+ return 1;
+ }
+ }
+ /* also RRSIG not found */
+ }
+
+ /* nothing found to delete */
+ if(nonexist) *nonexist = 1;
+ return 1;
+}
+
+/** remove RR from zone, ignore if it does not exist, false on alloc failure*/
+static int
+az_remove_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
+ size_t dname_len, int* nonexist)
+{
+ struct auth_data* node;
+ uint8_t* dname = rr;
+ uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len);
+ uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len);
+ size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len,
+ dname_len))+2;
+ /* rdata points to rdata prefixed with uint16 rdatalength */
+ uint8_t* rdata = sldns_wirerr_get_rdatawl(rr, rr_len, dname_len);
+
+ if(rr_class != z->dclass) {
+ log_err("wrong class for RR");
+ /* really also a nonexisting entry, because no records
+ * of that class in the zone, but return an error because
+ * getting records of the wrong class is a failure of the
+ * zone transfer */
+ return 0;
+ }
+ node = az_find_name(z, dname, dname_len);
+ if(!node) {
+ /* node with that name does not exist */
+ /* nonexisting entry, because no such name */
+ *nonexist = 1;
+ return 1;
+ }
+ if(!az_domain_remove_rr(node, rr_type, rdata, rdatalen, nonexist)) {
+ /* alloc failure or so */
+ return 0;
+ }
+ /* remove the node, if necessary */
+ /* an rrsets==NULL entry is not kept around for empty nonterminals,
+ * and also parent nodes are not kept around, so we just delete it */
+ if(node->rrsets == NULL) {
+ (void)rbtree_delete(&z->data, node);
+ auth_data_delete(node);
+ }
+ return 1;
+}
+
+/** decompress an RR into the buffer where it'll be an uncompressed RR
+ * with uncompressed dname and uncompressed rdata (dnames) */
+static int
+decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
+ size_t pktlen, uint8_t* dname, uint16_t rr_type, uint16_t rr_class,
+ uint32_t rr_ttl, uint8_t* rr_data, uint16_t rr_rdlen)
+{
+ sldns_buffer pktbuf;
+ size_t dname_len = 0;
+ size_t rdlenpos;
+ size_t rdlen;
+ uint8_t* rd;
+ const sldns_rr_descriptor* desc;
+ sldns_buffer_init_frm_data(&pktbuf, pkt, pktlen);
+ sldns_buffer_clear(buf);
+
+ /* decompress dname */
+ sldns_buffer_set_position(&pktbuf,
+ (size_t)(dname - sldns_buffer_current(&pktbuf)));
+ dname_len = pkt_dname_len(&pktbuf);
+ if(dname_len == 0) return 0; /* parse fail on dname */
+ if(!sldns_buffer_available(buf, dname_len)) return 0;
+ dname_pkt_copy(&pktbuf, sldns_buffer_current(buf), dname);
+ sldns_buffer_skip(buf, (ssize_t)dname_len);
+
+ /* type, class, ttl and rdatalength fields */
+ if(!sldns_buffer_available(buf, 10)) return 0;
+ sldns_buffer_write_u16(buf, rr_type);
+ sldns_buffer_write_u16(buf, rr_class);
+ sldns_buffer_write_u32(buf, rr_ttl);
+ rdlenpos = sldns_buffer_position(buf);
+ sldns_buffer_write_u16(buf, 0); /* rd length position */
+
+ /* decompress rdata */
+ desc = sldns_rr_descript(rr_type);
+ rd = rr_data;
+ rdlen = rr_rdlen;
+ if(rdlen > 0 && desc && desc->_dname_count > 0) {
+ int count = (int)desc->_dname_count;
+ int rdf = 0;
+ size_t len; /* how much rdata to plain copy */
+ size_t uncompressed_len, compressed_len;
+ size_t oldpos;
+ /* decompress dnames. */
+ while(rdlen > 0 && count) {
+ switch(desc->_wireformat[rdf]) {
+ case LDNS_RDF_TYPE_DNAME:
+ sldns_buffer_set_position(&pktbuf,
+ (size_t)(rd -
+ sldns_buffer_begin(&pktbuf)));
+ oldpos = sldns_buffer_position(&pktbuf);
+ /* moves pktbuf to right after the
+ * compressed dname, and returns uncompressed
+ * dname length */
+ uncompressed_len = pkt_dname_len(&pktbuf);
+ if(!uncompressed_len)
+ return 0; /* parse error in dname */
+ if(!sldns_buffer_available(buf,
+ uncompressed_len))
+ /* dname too long for buffer */
+ return 0;
+ dname_pkt_copy(&pktbuf,
+ sldns_buffer_current(buf), rd);
+ sldns_buffer_skip(buf, (ssize_t)uncompressed_len);
+ compressed_len = sldns_buffer_position(
+ &pktbuf) - oldpos;
+ rd += compressed_len;
+ rdlen -= compressed_len;
+ count--;
+ len = 0;
+ break;
+ case LDNS_RDF_TYPE_STR:
+ len = rd[0] + 1;
+ break;
+ default:
+ len = get_rdf_size(desc->_wireformat[rdf]);
+ break;
+ }
+ if(len) {
+ if(!sldns_buffer_available(buf, len))
+ return 0; /* too long for buffer */
+ sldns_buffer_write(buf, rd, len);
+ rd += len;
+ rdlen -= len;
+ }
+ rdf++;
+ }
+ }
+ /* copy remaining data */
+ if(rdlen > 0) {
+ if(!sldns_buffer_available(buf, rdlen)) return 0;
+ sldns_buffer_write(buf, rd, rdlen);
+ }
+ /* fixup rdlength */
+ sldns_buffer_write_u16_at(buf, rdlenpos,
+ sldns_buffer_position(buf)-rdlenpos-2);
+ sldns_buffer_flip(buf);
+ return 1;
+}
+
+/** insert RR into zone, from packet, decompress RR,
+ * if duplicate is nonNULL set the flag but otherwise ignore duplicates */
+static int
+az_insert_rr_decompress(struct auth_zone* z, uint8_t* pkt, size_t pktlen,
+ struct sldns_buffer* scratch_buffer, uint8_t* dname, uint16_t rr_type,
+ uint16_t rr_class, uint32_t rr_ttl, uint8_t* rr_data,
+ uint16_t rr_rdlen, int* duplicate)
+{
+ uint8_t* rr;
+ size_t rr_len;
+ size_t dname_len;
+ if(!decompress_rr_into_buffer(scratch_buffer, pkt, pktlen, dname,
+ rr_type, rr_class, rr_ttl, rr_data, rr_rdlen)) {
+ log_err("could not decompress RR");
+ return 0;
+ }
+ rr = sldns_buffer_begin(scratch_buffer);
+ rr_len = sldns_buffer_limit(scratch_buffer);
+ dname_len = dname_valid(rr, rr_len);
+ return az_insert_rr(z, rr, rr_len, dname_len, duplicate);
+}
+
+/** remove RR from zone, from packet, decompress RR,
+ * if nonexist is nonNULL set the flag but otherwise ignore nonexisting entries*/
+static int
+az_remove_rr_decompress(struct auth_zone* z, uint8_t* pkt, size_t pktlen,
+ struct sldns_buffer* scratch_buffer, uint8_t* dname, uint16_t rr_type,
+ uint16_t rr_class, uint32_t rr_ttl, uint8_t* rr_data,
+ uint16_t rr_rdlen, int* nonexist)
+{
+ uint8_t* rr;
+ size_t rr_len;
+ size_t dname_len;
+ if(!decompress_rr_into_buffer(scratch_buffer, pkt, pktlen, dname,
+ rr_type, rr_class, rr_ttl, rr_data, rr_rdlen)) {
+ log_err("could not decompress RR");
+ return 0;
+ }
+ rr = sldns_buffer_begin(scratch_buffer);
+ rr_len = sldns_buffer_limit(scratch_buffer);
+ dname_len = dname_valid(rr, rr_len);
+ return az_remove_rr(z, rr, rr_len, dname_len, nonexist);
+}
+
/**
* Parse zonefile
* @param z: zone to read in.
@@ -1062,6 +1462,11 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
/* skip spaces */
while(*incfile == ' ' || *incfile == '\t')
incfile++;
+ incfile = strdup(incfile);
+ if(!incfile) {
+ log_err("malloc failure");
+ return 0;
+ }
verbose(VERB_ALGO, "opening $INCLUDE %s",
incfile);
inc = fopen(incfile, "r");
@@ -1070,6 +1475,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
"file %s: %s", z->zonefile,
lineno_orig, incfile,
strerror(errno));
+ free(incfile);
return 0;
}
/* recurse read that file now */
@@ -1084,6 +1490,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
fclose(inc);
verbose(VERB_ALGO, "done with $INCLUDE %s",
incfile);
+ free(incfile);
state->lineno = lineno_orig;
}
continue;
@@ -1099,7 +1506,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
continue;
}
/* insert wirerr in rrbuf */
- if(!az_insert_rr(z, rr, rr_len, dname_len)) {
+ if(!az_insert_rr(z, rr, rr_len, dname_len, NULL)) {
char buf[17];
sldns_wire2str_type_buf(sldns_wirerr_get_type(rr,
rr_len, dname_len), buf, sizeof(buf));
@@ -1119,7 +1526,11 @@ auth_zone_read_zonefile(struct auth_zone* z)
FILE* in;
if(!z || !z->zonefile || z->zonefile[0]==0)
return 1; /* no file, or "", nothing to read */
- verbose(VERB_ALGO, "read zonefile %s", z->zonefile);
+ if(verbosity >= VERB_ALGO) {
+ char nm[255+1];
+ dname_str(z->name, nm);
+ verbose(VERB_ALGO, "read zonefile %s for %s", z->zonefile, nm);
+ }
in = fopen(z->zonefile, "r");
if(!in) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
@@ -1174,6 +1585,42 @@ write_out(FILE* out, const char* str)
return 1;
}
+/** convert auth rr to string */
+static int
+auth_rr_to_string(uint8_t* nm, size_t nmlen, uint16_t tp, uint16_t cl,
+ struct packed_rrset_data* data, size_t i, char* s, size_t buflen)
+{
+ int w = 0;
+ size_t slen = buflen, datlen;
+ uint8_t* dat;
+ if(i >= data->count) tp = LDNS_RR_TYPE_RRSIG;
+ dat = nm;
+ datlen = nmlen;
+ w += sldns_wire2str_dname_scan(&dat, &datlen, &s, &slen, NULL, 0);
+ w += sldns_str_print(&s, &slen, "\t");
+ w += sldns_str_print(&s, &slen, "%lu\t", (unsigned long)data->rr_ttl[i]);
+ w += sldns_wire2str_class_print(&s, &slen, cl);
+ w += sldns_str_print(&s, &slen, "\t");
+ w += sldns_wire2str_type_print(&s, &slen, tp);
+ w += sldns_str_print(&s, &slen, "\t");
+ datlen = data->rr_len[i]-2;
+ dat = data->rr_data[i]+2;
+ w += sldns_wire2str_rdata_scan(&dat, &datlen, &s, &slen, tp, NULL, 0);
+
+ if(tp == LDNS_RR_TYPE_DNSKEY) {
+ w += sldns_str_print(&s, &slen, " ;{id = %u}",
+ sldns_calc_keytag_raw(data->rr_data[i]+2,
+ data->rr_len[i]-2));
+ }
+ w += sldns_str_print(&s, &slen, "\n");
+
+ if(w > (int)buflen) {
+ log_nametypeclass(0, "RR too long to print", nm, tp, cl);
+ return 0;
+ }
+ return 1;
+}
+
/** write rrset to file */
static int
auth_zone_write_rrset(struct auth_zone* z, struct auth_data* node,
@@ -1182,15 +1629,8 @@ auth_zone_write_rrset(struct auth_zone* z, struct auth_data* node,
size_t i, count = r->data->count + r->data->rrsig_count;
char buf[LDNS_RR_BUF_SIZE];
for(i=0; i<count; i++) {
- struct ub_packed_rrset_key key;
- memset(&key, 0, sizeof(key));
- key.entry.key = &key;
- key.entry.data = r->data;
- key.rk.dname = node->name;
- key.rk.dname_len = node->namelen;
- key.rk.type = htons(r->type);
- key.rk.rrset_class = htons(z->dclass);
- if(!packed_rr_to_string(&key, i, 0, buf, sizeof(buf))) {
+ if(!auth_rr_to_string(node->name, node->namelen, r->type,
+ z->dclass, r->data, i, buf, sizeof(buf))) {
verbose(VERB_ALGO, "failed to rr2str rr %d", (int)i);
continue;
}
@@ -1281,8 +1721,8 @@ xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
d = soa->data;
xfr->have_zone = 1;
xfr->serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20));
- xfr->retry = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-16));
- xfr->refresh = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-12));
+ xfr->refresh = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-16));
+ xfr->retry = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-12));
xfr->expiry = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-8));
/* soa minimum at d->rr_len[0]-4 */
return 1;
@@ -1290,36 +1730,32 @@ xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
/**
* Setup auth_xfer zone
- * This populates the have_zone, soa values, next_probe and so on times.
- * Doesn't do network traffic yet, sets the timeout.
+ * This populates the have_zone, soa values, and so on times.
+ * Doesn't do network traffic yet, can set option flags.
* @param z: locked by caller, and modified for setup
- * @param x: locked by caller, and modified, timers and timeouts.
- * @param env: module env with time.
+ * @param x: locked by caller, and modified.
* @return false on failure.
*/
static int
-auth_xfer_setup(struct auth_zone* z, struct auth_xfer* x, struct module_env* env)
+auth_xfer_setup(struct auth_zone* z, struct auth_xfer* x)
{
+ /* for a zone without zone transfers, x==NULL, so skip them,
+ * i.e. the zone config is fixed with no masters or urls */
if(!z || !x) return 1;
if(!xfr_find_soa(z, x)) {
return 1;
}
- /* nextprobe setup */
- x->task_nextprobe->next_probe = 0;
- if(x->have_zone)
- x->task_nextprobe->lease_time = *env->now;
- /* nothing for probe and transfer tasks */
+ /* nothing for probe, nextprobe and transfer tasks */
return 1;
}
/**
* Setup all zones
* @param az: auth zones structure
- * @param env: module env with time.
* @return false on failure.
*/
static int
-auth_zones_setup_zones(struct auth_zones* az, struct module_env* env)
+auth_zones_setup_zones(struct auth_zones* az)
{
struct auth_zone* z;
struct auth_xfer* x;
@@ -1330,7 +1766,7 @@ auth_zones_setup_zones(struct auth_zones* az, struct module_env* env)
if(x) {
lock_basic_lock(&x->lock);
}
- if(!auth_xfer_setup(z, x, env)) {
+ if(!auth_xfer_setup(z, x)) {
if(x) {
lock_basic_unlock(&x->lock);
}
@@ -1381,20 +1817,18 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
}
z->for_downstream = c->for_downstream;
z->for_upstream = c->for_upstream;
- /* TODO fallback option */
- //if(!auth_zone_set_fallback(z, zlist->str2)) {
- /* TODO other options */
+ z->fallback_enabled = c->fallback_enabled;
/* xfer zone */
if(x) {
z->zone_is_slave = 1;
/* set options on xfer zone */
- if(!xfer_set_masters(&x->task_probe->masters, c)) {
+ if(!xfer_set_masters(&x->task_probe->masters, c, 0)) {
lock_basic_unlock(&x->lock);
lock_rw_unlock(&z->lock);
return 0;
}
- if(!xfer_set_masters(&x->task_transfer->masters, c)) {
+ if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) {
lock_basic_unlock(&x->lock);
lock_rw_unlock(&z->lock);
return 0;
@@ -1407,7 +1841,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
}
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
- int setup, struct module_env* env)
+ int setup)
{
struct config_auth* p;
for(p = cfg->auths; p; p = p->next) {
@@ -1423,7 +1857,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
if(!auth_zones_read_zones(az))
return 0;
if(setup) {
- if(!auth_zones_setup_zones(az, env))
+ if(!auth_zones_setup_zones(az))
return 0;
}
return 1;
@@ -1628,9 +2062,9 @@ az_domain_go_up(struct auth_zone* z, struct auth_data* n)
* return true if the node (param node) is existing, nonobscured and
* can be used to generate answers from. It is then also node_exact.
* returns false if the node is not good enough (or it wasn't node_exact)
- * in this case the ce can be filled.
- * if ce is NULL, no ce exists, and likely the zone is completely empty,
- * not even with a zone apex.
+ * in this case the ce can be filled.
+ * if ce is NULL, no ce exists, and likely the zone is completely empty,
+ * not even with a zone apex.
* if ce is nonNULL it is the closest enclosing upper name (that exists
* itself for answer purposes). That name may have DNAME, NS or wildcard
* rrset is the closest DNAME or NS rrset that was found.
@@ -2428,12 +2862,6 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
struct auth_data* wildcard, struct auth_data* node)
{
struct auth_rrset* rrset, *nsec;
- if(verbosity>=VERB_ALGO) {
- char wcname[256];
- sldns_wire2str_dname_buf(wildcard->name, wildcard->namelen,
- wcname, sizeof(wcname));
- log_info("wildcard %s", wcname);
- }
if((rrset=az_domain_rrset(wildcard, qinfo->qtype)) != NULL) {
/* wildcard has type, add it */
if(!msg_add_rrset_an(z, region, msg, wildcard, rrset))
@@ -2616,15 +3044,11 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
{
int r;
struct auth_zone* z;
- /* TODO: in iterator, after cache lookup, before network lookup,
- * call this to get answer */
-
/* find the zone that should contain the answer. */
lock_rw_rdlock(&az->lock);
z = auth_zone_find(az, dp_nm, dp_nmlen, qinfo->qclass);
if(!z) {
lock_rw_unlock(&az->lock);
- verbose(VERB_ALGO, "no auth zone for query, fallback");
/* no auth zone, fallback to internet */
*fallback = 1;
return 0;
@@ -2632,6 +3056,12 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
lock_rw_rdlock(&z->lock);
lock_rw_unlock(&az->lock);
+ /* if not for upstream queries, fallback */
+ if(!z->for_upstream) {
+ lock_rw_unlock(&z->lock);
+ *fallback = 1;
+ return 0;
+ }
/* see what answer that zone would generate */
r = auth_zone_generate_answer(z, qinfo, region, msg, fallback);
lock_rw_unlock(&z->lock);
@@ -2687,8 +3117,6 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf,
struct regional* temp)
{
- /* TODO: in handle after localzones, before cache, if az != NULL,
- * call this function to answer downstream */
struct dns_msg* msg = NULL;
struct auth_zone* z;
int r;
@@ -2700,12 +3128,22 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
lock_rw_unlock(&az->lock);
return 0;
}
- z = auth_zones_find_zone(az, qinfo);
+ if(qinfo->qtype == LDNS_RR_TYPE_DS) {
+ uint8_t* delname = qinfo->qname;
+ size_t delnamelen = qinfo->qname_len;
+ dname_remove_label(&delname, &delnamelen);
+ z = auth_zones_find_zone(az, delname, delnamelen,
+ qinfo->qclass);
+ } else {
+ z = auth_zones_find_zone(az, qinfo->qname, qinfo->qname_len,
+ qinfo->qclass);
+ }
if(!z) {
/* no zone above it */
lock_rw_unlock(&az->lock);
return 0;
}
+ lock_rw_rdlock(&z->lock);
lock_rw_unlock(&az->lock);
if(!z->for_downstream) {
lock_rw_unlock(&z->lock);
@@ -2729,6 +3167,25 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
return 1;
}
+int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
+ uint16_t dclass)
+{
+ int r;
+ struct auth_zone* z;
+ lock_rw_rdlock(&az->lock);
+ z = auth_zone_find(az, nm, nmlen, dclass);
+ if(!z) {
+ lock_rw_unlock(&az->lock);
+ /* no such auth zone, fallback */
+ return 1;
+ }
+ lock_rw_rdlock(&z->lock);
+ lock_rw_unlock(&az->lock);
+ r = z->fallback_enabled || (!z->for_upstream);
+ lock_rw_unlock(&z->lock);
+ return r;
+}
+
/** set a zone expired */
static void
auth_xfer_set_expired(struct auth_xfer* xfr, struct module_env* env,
@@ -2757,34 +3214,6 @@ auth_xfer_set_expired(struct auth_xfer* xfr, struct module_env* env,
lock_rw_unlock(&z->lock);
}
-/** the current transfer has finished, apply the results.
- * set timer for future probe. See if zone is expired now. */
-void
-xfr_master_transferresult(struct auth_xfer* xfr)
-{
- (void)xfr;
- /* TODO */
-}
-
-/** the current probe has finished, inspect the results.
- * move on to the next master or start a transfer, or at last master,
- * set timer for future probe. See if zone is expired now. */
-void
-xfr_master_proberesult(struct auth_xfer* xfr)
-{
- (void)xfr;
- /* TODO */
-}
-
-/** with current master selected, start the probe, or transfer */
-int
-xfr_master_start(struct auth_xfer* xfr)
-{
- (void)xfr;
- /* TODO */
- return 0;
-}
-
/** find master (from notify or probe) in list of masters */
static struct auth_master*
find_master_by_host(struct auth_master* list, char* host)
@@ -2956,154 +3385,108 @@ xfr_probe_end_of_list(struct auth_xfer* xfr)
}
/** move to next master in list, task_transfer */
-static int
+static void
xfr_transfer_nextmaster(struct auth_xfer* xfr)
{
- /* TODO: no return value */
if(!xfr->task_transfer->scan_specific &&
!xfr->task_transfer->scan_target)
- return 0;
+ return;
if(xfr->task_transfer->scan_addr) {
xfr->task_transfer->scan_addr =
xfr->task_transfer->scan_addr->next;
if(xfr->task_transfer->scan_addr)
- return 1;
+ return;
}
if(xfr->task_transfer->scan_specific) {
xfr->task_transfer->scan_specific = NULL;
xfr->task_transfer->scan_target = xfr->task_transfer->masters;
- return 1;
+ return;
}
if(!xfr->task_transfer->scan_target)
- return 0;
- if(!xfr->task_transfer->scan_target->next)
- return 0;
+ return;
xfr->task_transfer->scan_target = xfr->task_transfer->scan_target->next;
- return 1;
+ return;
}
/** move to next master in list, task_probe */
-static int
+static void
xfr_probe_nextmaster(struct auth_xfer* xfr)
{
- /* TODO: no return value */
if(!xfr->task_probe->scan_specific && !xfr->task_probe->scan_target)
- return 0;
+ return;
if(xfr->task_probe->scan_addr) {
xfr->task_probe->scan_addr = xfr->task_probe->scan_addr->next;
if(xfr->task_probe->scan_addr)
- return 1;
+ return;
}
if(xfr->task_probe->scan_specific) {
xfr->task_probe->scan_specific = NULL;
xfr->task_probe->scan_target = xfr->task_probe->masters;
- return 1;
+ return;
}
if(!xfr->task_probe->scan_target)
- return 0;
- if(!xfr->task_probe->scan_target->next)
- return 0;
+ return;
xfr->task_probe->scan_target = xfr->task_probe->scan_target->next;
- return 1;
+ return;
}
-/** create fd to send to this master */
-static int
-xfr_fd_for_master(struct module_env* env, struct sockaddr_storage* to_addr,
- socklen_t to_addrlen, char* host)
+/** create SOA probe packet for xfr */
+static void
+xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf,
+ uint16_t id)
{
- struct sockaddr_storage* addr;
- socklen_t addrlen;
- int i;
- int try;
+ struct query_info qinfo;
- /* select interface */
- if(addr_is_ip6(to_addr, to_addrlen)) {
- if(env->outnet->num_ip6 == 0) {
- verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", host);
- return -1;
- }
- i = ub_random_max(env->rnd, env->outnet->num_ip6);
- addr = &env->outnet->ip6_ifs[i].addr;
- addrlen = env->outnet->ip6_ifs[i].addrlen;
- } else {
- if(env->outnet->num_ip4 == 0) {
- verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", host);
- return -1;
- }
- i = ub_random_max(env->rnd, env->outnet->num_ip4);
- addr = &env->outnet->ip4_ifs[i].addr;
- addrlen = env->outnet->ip4_ifs[i].addrlen;
- }
-
- /* create fd */
- for(try = 0; try<1000; try++) {
- int freebind = 0;
- int noproto = 0;
- int inuse = 0;
- int port = ub_random(env->rnd)&0xffff;
- int fd = -1;
- if(addr_is_ip6(to_addr, to_addrlen)) {
- struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
- sa.sin6_port = (in_port_t)htons((uint16_t)port);
- fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
- (struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
- 0, 0, 0, NULL, 0, freebind, 0);
- } else {
- struct sockaddr_in* sa = (struct sockaddr_in*)addr;
- sa->sin_port = (in_port_t)htons((uint16_t)port);
- fd = create_udp_sock(AF_INET, SOCK_DGRAM,
- (struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
- 0, 0, 0, NULL, 0, freebind, 0);
- }
- if(fd != -1) {
- return fd;
- }
- if(!inuse) {
- return -1;
- }
- }
- /* too many tries */
- log_err("cannot send probe, ports are in use");
- return -1;
+ memset(&qinfo, 0, sizeof(qinfo));
+ qinfo.qname = xfr->name;
+ qinfo.qname_len = xfr->namelen;
+ qinfo.qtype = LDNS_RR_TYPE_SOA;
+ qinfo.qclass = xfr->dclass;
+ qinfo_query_encode(buf, &qinfo);
+ sldns_buffer_write_u16_at(buf, 0, id);
}
-/** create probe packet for xfr */
+/** create IXFR/AXFR packet for xfr */
static void
-xfr_create_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf, int soa,
- uint16_t id)
+xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
+ struct auth_master* master)
{
struct query_info qinfo;
uint32_t serial;
int have_zone;
- lock_basic_lock(&xfr->lock);
have_zone = xfr->have_zone;
serial = xfr->serial;
- lock_basic_unlock(&xfr->lock);
memset(&qinfo, 0, sizeof(qinfo));
qinfo.qname = xfr->name;
qinfo.qname_len = xfr->namelen;
- if(soa) {
- qinfo.qtype = LDNS_RR_TYPE_SOA;
- } else {
- qinfo.qtype = LDNS_RR_TYPE_IXFR;
- if(!have_zone)
- qinfo.qtype = LDNS_RR_TYPE_AXFR;
+ xfr->task_transfer->got_xfr_serial = 0;
+ xfr->task_transfer->rr_scan_num = 0;
+ xfr->task_transfer->incoming_xfr_serial = 0;
+ xfr->task_transfer->on_ixfr_is_axfr = 0;
+ xfr->task_transfer->on_ixfr = 1;
+ qinfo.qtype = LDNS_RR_TYPE_IXFR;
+ if(!have_zone || xfr->task_transfer->ixfr_fail || !master->ixfr) {
+ qinfo.qtype = LDNS_RR_TYPE_AXFR;
+ xfr->task_transfer->ixfr_fail = 0;
+ xfr->task_transfer->on_ixfr = 0;
}
+
qinfo.qclass = xfr->dclass;
qinfo_query_encode(buf, &qinfo);
- sldns_buffer_write_at(buf, 0, &id, 2);
+ sldns_buffer_write_u16_at(buf, 0, id);
/* append serial for IXFR */
if(qinfo.qtype == LDNS_RR_TYPE_IXFR) {
- sldns_buffer_set_position(buf, sldns_buffer_limit(buf));
+ size_t end = sldns_buffer_limit(buf);
+ sldns_buffer_clear(buf);
+ sldns_buffer_set_position(buf, end);
/* auth section count 1 */
- sldns_buffer_write_u16_at(buf, 1, LDNS_NSCOUNT_OFF);
+ sldns_buffer_write_u16_at(buf, LDNS_NSCOUNT_OFF, 1);
/* write SOA */
sldns_buffer_write_u8(buf, 0xC0); /* compressed ptr to qname */
sldns_buffer_write_u8(buf, 0x0C);
- sldns_buffer_write_u16(buf, qinfo.qtype);
+ sldns_buffer_write_u16(buf, LDNS_RR_TYPE_SOA);
sldns_buffer_write_u16(buf, qinfo.qclass);
sldns_buffer_write_u32(buf, 0); /* ttl */
sldns_buffer_write_u16(buf, 22); /* rdata length */
@@ -3123,7 +3506,6 @@ static int
check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
uint32_t* serial)
{
- uint16_t id;
/* parse to see if packet worked, valid reply */
/* check serial number of SOA */
@@ -3131,8 +3513,7 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
return 0;
/* check ID */
- sldns_buffer_read_at(pkt, 0, &id, 2);
- if(id != xfr->task_probe->id)
+ if(LDNS_ID_WIRE(sldns_buffer_begin(pkt)) != xfr->task_probe->id)
return 0;
/* check flag bits and rcode */
@@ -3205,25 +3586,913 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
static int
xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial)
{
- uint32_t zserial;
- int have_zone, zone_expired;
- lock_basic_lock(&xfr->lock);
- zserial = xfr->serial;
- have_zone = xfr->have_zone;
- zone_expired = xfr->zone_expired;
- lock_basic_unlock(&xfr->lock);
-
- if(!have_zone)
+ if(!xfr->have_zone)
return 1; /* no zone, anything is better */
- if(zone_expired)
+ if(xfr->zone_expired)
return 1; /* expired, the sent serial is better than expired
data */
- if(compare_serial(zserial, serial) < 0)
+ if(compare_serial(xfr->serial, serial) < 0)
return 1; /* our serial is smaller than the sent serial,
the data is newer, fetch it */
return 0;
}
+/** read one line from chunks into buffer at current position */
+static int
+chunkline_get_line(struct auth_chunk** chunk, size_t* chunk_pos,
+ sldns_buffer* buf)
+{
+ int readsome = 0;
+ while(*chunk) {
+ /* more text in this chunk? */
+ if(*chunk_pos < (*chunk)->len) {
+ readsome = 1;
+ while(*chunk_pos < (*chunk)->len) {
+ char c = (char)((*chunk)->data[*chunk_pos]);
+ (*chunk_pos)++;
+ if(sldns_buffer_remaining(buf) < 2) {
+ /* buffer too short */
+ verbose(VERB_ALGO, "http chunkline, "
+ "line too long");
+ return 0;
+ }
+ sldns_buffer_write_u8(buf, (uint8_t)c);
+ if(c == '\n') {
+ /* we are done */
+ return 1;
+ }
+ }
+ }
+ /* move to next chunk */
+ *chunk = (*chunk)->next;
+ *chunk_pos = 0;
+ }
+ /* no more text */
+ if(readsome) return 1;
+ return 0;
+}
+
+/** count number of open and closed parenthesis in a chunkline */
+static int
+chunkline_count_parens(sldns_buffer* buf, size_t start)
+{
+ size_t end = sldns_buffer_position(buf);
+ size_t i;
+ int count = 0;
+ int squote = 0, dquote = 0;
+ for(i=start; i<end; i++) {
+ char c = (char)sldns_buffer_read_u8_at(buf, i);
+ if(squote && c != '\'') continue;
+ if(dquote && c != '"') continue;
+ if(c == '"')
+ dquote = !dquote; /* skip quoted part */
+ else if(c == '\'')
+ squote = !squote; /* skip quoted part */
+ else if(c == '(')
+ count ++;
+ else if(c == ')')
+ count --;
+ else if(c == ';') {
+ /* rest is a comment */
+ return count;
+ }
+ }
+ return count;
+}
+
+/** remove trailing ;... comment from a line in the chunkline buffer */
+static void
+chunkline_remove_trailcomment(sldns_buffer* buf, size_t start)
+{
+ size_t end = sldns_buffer_position(buf);
+ size_t i;
+ int squote = 0, dquote = 0;
+ for(i=start; i<end; i++) {
+ char c = (char)sldns_buffer_read_u8_at(buf, i);
+ if(squote && c != '\'') continue;
+ if(dquote && c != '"') continue;
+ if(c == '"')
+ dquote = !dquote; /* skip quoted part */
+ else if(c == '\'')
+ squote = !squote; /* skip quoted part */
+ else if(c == ';') {
+ /* rest is a comment */
+ sldns_buffer_set_position(buf, i);
+ return;
+ }
+ }
+ /* nothing to remove */
+}
+
+/** see if a chunkline is a comment line (or empty line) */
+static int
+chunkline_is_comment_line_or_empty(sldns_buffer* buf)
+{
+ size_t i, end = sldns_buffer_limit(buf);
+ for(i=0; i<end; i++) {
+ char c = (char)sldns_buffer_read_u8_at(buf, i);
+ if(c == ';')
+ return 1; /* comment */
+ else if(c != ' ' && c != '\t' && c != '\r' && c != '\n')
+ return 0; /* not a comment */
+ }
+ return 1; /* empty */
+}
+
+/** find a line with ( ) collated */
+static int
+chunkline_get_line_collated(struct auth_chunk** chunk, size_t* chunk_pos,
+ sldns_buffer* buf)
+{
+ size_t pos;
+ int parens = 0;
+ sldns_buffer_clear(buf);
+ pos = sldns_buffer_position(buf);
+ if(!chunkline_get_line(chunk, chunk_pos, buf)) {
+ if(sldns_buffer_position(buf) < sldns_buffer_limit(buf))
+ sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf), 0);
+ else sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf)-1, 0);
+ sldns_buffer_flip(buf);
+ return 0;
+ }
+ parens += chunkline_count_parens(buf, pos);
+ while(parens > 0) {
+ chunkline_remove_trailcomment(buf, pos);
+ pos = sldns_buffer_position(buf);
+ if(!chunkline_get_line(chunk, chunk_pos, buf)) {
+ if(sldns_buffer_position(buf) < sldns_buffer_limit(buf))
+ sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf), 0);
+ else sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf)-1, 0);
+ sldns_buffer_flip(buf);
+ return 0;
+ }
+ parens += chunkline_count_parens(buf, pos);
+ }
+
+ if(sldns_buffer_remaining(buf) < 1) {
+ verbose(VERB_ALGO, "http chunkline: "
+ "line too long");
+ return 0;
+ }
+ sldns_buffer_write_u8_at(buf, sldns_buffer_position(buf), 0);
+ sldns_buffer_flip(buf);
+ return 1;
+}
+
+/** process $ORIGIN for http */
+static int
+http_parse_origin(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
+{
+ char* line = (char*)sldns_buffer_begin(buf);
+ if(strncmp(line, "$ORIGIN", 7) == 0 &&
+ isspace((unsigned char)line[7])) {
+ int s;
+ pstate->origin_len = sizeof(pstate->origin);
+ s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8),
+ pstate->origin, &pstate->origin_len);
+ if(s) pstate->origin_len = 0;
+ return 1;
+ }
+ return 0;
+}
+
+/** process $TTL for http */
+static int
+http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
+{
+ char* line = (char*)sldns_buffer_begin(buf);
+ if(strncmp(line, "$TTL", 4) == 0 &&
+ isspace((unsigned char)line[4])) {
+ const char* end = NULL;
+ pstate->default_ttl = sldns_str2period(
+ sldns_strip_ws(line+5), &end);
+ return 1;
+ }
+ return 0;
+}
+
+/** find noncomment RR line in chunks, collates lines if ( ) format */
+static int
+chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
+ sldns_buffer* buf, struct sldns_file_parse_state* pstate)
+{
+ while(chunkline_get_line_collated(chunk, chunk_pos, buf)) {
+ if(chunkline_is_comment_line_or_empty(buf)) {
+ /* a comment, go to next line */
+ continue;
+ }
+ if(http_parse_origin(buf, pstate)) {
+ continue; /* $ORIGIN has been handled */
+ }
+ if(http_parse_ttl(buf, pstate)) {
+ continue; /* $TTL has been handled */
+ }
+ return 1;
+ }
+ /* no noncomments, fail */
+ return 0;
+}
+
+/** check syntax of chunklist zonefile, parse SOA RR, return false on
+ * failure and return a string in the scratch buffer (SOA RR string)
+ * on failure. */
+static int
+http_zonefile_syntax_check(struct auth_xfer* xfr, sldns_buffer* buf)
+{
+ uint8_t rr[LDNS_RR_BUF_SIZE];
+ size_t rr_len, dname_len = 0;
+ struct sldns_file_parse_state pstate;
+ struct auth_chunk* chunk;
+ size_t chunk_pos;
+ int e;
+ memset(&pstate, 0, sizeof(pstate));
+ pstate.default_ttl = 3600;
+ if(xfr->namelen < sizeof(pstate.origin)) {
+ pstate.origin_len = xfr->namelen;
+ memmove(pstate.origin, xfr->name, xfr->namelen);
+ }
+ chunk = xfr->task_transfer->chunks_first;
+ chunk_pos = 0;
+ if(!chunkline_non_comment_RR(&chunk, &chunk_pos, buf, &pstate)) {
+ return 0;
+ }
+ rr_len = sizeof(rr);
+ e=sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr, &rr_len,
+ &dname_len, pstate.default_ttl,
+ pstate.origin_len?pstate.origin:NULL, pstate.origin_len,
+ pstate.prev_rr_len?pstate.prev_rr:NULL, pstate.prev_rr_len);
+ if(e != 0) {
+ log_err("parse failure on SOA RR[%d]: %s",
+ LDNS_WIREPARSE_OFFSET(e),
+ sldns_get_errorstr_parse(LDNS_WIREPARSE_ERROR(e)));
+ return 0;
+ }
+ /* check that name is correct */
+ if(query_dname_compare(rr, xfr->name) != 0) {
+ char nm[255+1], zname[255+1];
+ dname_str(rr, nm);
+ dname_str(xfr->name, zname);
+ log_err("parse failure for %s, SOA RR for %s found instead",
+ zname, nm);
+ return 0;
+ }
+ /* check that type is SOA */
+ if(sldns_wirerr_get_type(rr, rr_len, dname_len) != LDNS_RR_TYPE_SOA) {
+ log_err("parse failure: first record in downloaded zonefile "
+ "not of type SOA");
+ return 0;
+ }
+ /* check that class is correct */
+ if(sldns_wirerr_get_class(rr, rr_len, dname_len) != xfr->dclass) {
+ log_err("parse failure: first record in downloaded zonefile "
+ "from wrong RR class");
+ return 0;
+ }
+ return 1;
+}
+
+/** sum sizes of chunklist */
+static size_t
+chunklist_sum(struct auth_chunk* list)
+{
+ struct auth_chunk* p;
+ size_t s = 0;
+ for(p=list; p; p=p->next) {
+ s += p->len;
+ }
+ return s;
+}
+
+/** remove newlines from collated line */
+static void
+chunkline_newline_removal(sldns_buffer* buf)
+{
+ size_t i, end=sldns_buffer_limit(buf);
+ for(i=0; i<end; i++) {
+ char c = (char)sldns_buffer_read_u8_at(buf, i);
+ if(c == '\n')
+ sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
+ }
+}
+
+/** for http download, parse and add RR to zone */
+static int
+http_parse_add_rr(struct auth_xfer* xfr, struct auth_zone* z,
+ sldns_buffer* buf, struct sldns_file_parse_state* pstate)
+{
+ uint8_t rr[LDNS_RR_BUF_SIZE];
+ size_t rr_len, dname_len = 0;
+ int e;
+ char* line = (char*)sldns_buffer_begin(buf);
+ rr_len = sizeof(rr);
+ e = sldns_str2wire_rr_buf(line, rr, &rr_len, &dname_len,
+ pstate->default_ttl,
+ pstate->origin_len?pstate->origin:NULL, pstate->origin_len,
+ pstate->prev_rr_len?pstate->prev_rr:NULL, pstate->prev_rr_len);
+ if(e != 0) {
+ log_err("%s/%s parse failure RR[%d]: %s in '%s'",
+ xfr->task_transfer->master->host,
+ xfr->task_transfer->master->file,
+ LDNS_WIREPARSE_OFFSET(e),
+ sldns_get_errorstr_parse(LDNS_WIREPARSE_ERROR(e)),
+ line);
+ return 0;
+ }
+ if(rr_len == 0)
+ return 1; /* empty line or so */
+
+ /* set prev */
+ if(dname_len < sizeof(pstate->prev_rr)) {
+ memmove(pstate->prev_rr, rr, dname_len);
+ pstate->prev_rr_len = dname_len;
+ }
+
+ return az_insert_rr(z, rr, rr_len, dname_len, NULL);
+}
+
+/** RR list iterator, returns RRs from answer section one by one from the
+ * dns packets in the chunklist */
+static void
+chunk_rrlist_start(struct auth_xfer* xfr, struct auth_chunk** rr_chunk,
+ int* rr_num, size_t* rr_pos)
+{
+ *rr_chunk = xfr->task_transfer->chunks_first;
+ *rr_num = 0;
+ *rr_pos = 0;
+}
+
+/** RR list iterator, see if we are at the end of the list */
+static int
+chunk_rrlist_end(struct auth_chunk* rr_chunk, int rr_num)
+{
+ while(rr_chunk) {
+ if(rr_chunk->len < LDNS_HEADER_SIZE)
+ return 1;
+ if(rr_num < (int)LDNS_ANCOUNT(rr_chunk->data))
+ return 0;
+ /* no more RRs in this chunk */
+ /* continue with next chunk, see if it has RRs */
+ rr_chunk = rr_chunk->next;
+ rr_num = 0;
+ }
+ return 1;
+}
+
+/** RR list iterator, move to next RR */
+static void
+chunk_rrlist_gonext(struct auth_chunk** rr_chunk, int* rr_num,
+ size_t* rr_pos, size_t rr_nextpos)
+{
+ /* already at end of chunks? */
+ if(!*rr_chunk)
+ return;
+ /* move within this chunk */
+ if((*rr_chunk)->len >= LDNS_HEADER_SIZE &&
+ (*rr_num)+1 < (int)LDNS_ANCOUNT((*rr_chunk)->data)) {
+ (*rr_num) += 1;
+ *rr_pos = rr_nextpos;
+ return;
+ }
+ /* no more RRs in this chunk */
+ /* continue with next chunk, see if it has RRs */
+ if(*rr_chunk)
+ *rr_chunk = (*rr_chunk)->next;
+ while(*rr_chunk) {
+ *rr_num = 0;
+ *rr_pos = 0;
+ if((*rr_chunk)->len >= LDNS_HEADER_SIZE &&
+ LDNS_ANCOUNT((*rr_chunk)->data) > 0) {
+ return;
+ }
+ *rr_chunk = (*rr_chunk)->next;
+ }
+}
+
+/** RR iterator, get current RR information, false on parse error */
+static int
+chunk_rrlist_get_current(struct auth_chunk* rr_chunk, int rr_num,
+ size_t rr_pos, uint8_t** rr_dname, uint16_t* rr_type,
+ uint16_t* rr_class, uint32_t* rr_ttl, uint16_t* rr_rdlen,
+ uint8_t** rr_rdata, size_t* rr_nextpos)
+{
+ sldns_buffer pkt;
+ /* integrity checks on position */
+ if(!rr_chunk) return 0;
+ if(rr_chunk->len < LDNS_HEADER_SIZE) return 0;
+ if(rr_num >= (int)LDNS_ANCOUNT(rr_chunk->data)) return 0;
+ if(rr_pos >= rr_chunk->len) return 0;
+
+ /* fetch rr information */
+ sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len);
+ if(rr_pos == 0) {
+ size_t i;
+ /* skip question section */
+ sldns_buffer_set_position(&pkt, LDNS_HEADER_SIZE);
+ for(i=0; i<LDNS_QDCOUNT(rr_chunk->data); i++) {
+ if(pkt_dname_len(&pkt) == 0) return 0;
+ if(sldns_buffer_remaining(&pkt) < 4) return 0;
+ sldns_buffer_skip(&pkt, 4); /* type and class */
+ }
+ } else {
+ sldns_buffer_set_position(&pkt, rr_pos);
+ }
+ *rr_dname = sldns_buffer_current(&pkt);
+ if(pkt_dname_len(&pkt) == 0) return 0;
+ if(sldns_buffer_remaining(&pkt) < 10) return 0;
+ *rr_type = sldns_buffer_read_u16(&pkt);
+ *rr_class = sldns_buffer_read_u16(&pkt);
+ *rr_ttl = sldns_buffer_read_u32(&pkt);
+ *rr_rdlen = sldns_buffer_read_u16(&pkt);
+ if(sldns_buffer_remaining(&pkt) < (*rr_rdlen)) return 0;
+ *rr_rdata = sldns_buffer_current(&pkt);
+ sldns_buffer_skip(&pkt, (ssize_t)(*rr_rdlen));
+ *rr_nextpos = sldns_buffer_position(&pkt);
+ return 1;
+}
+
+/** print log message where we are in parsing the zone transfer */
+static void
+log_rrlist_position(const char* label, struct auth_chunk* rr_chunk,
+ uint8_t* rr_dname, uint16_t rr_type, size_t rr_counter)
+{
+ sldns_buffer pkt;
+ size_t dlen;
+ uint8_t buf[256];
+ char str[256];
+ char typestr[32];
+ sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len);
+ sldns_buffer_set_position(&pkt, (size_t)(rr_dname -
+ sldns_buffer_begin(&pkt)));
+ if((dlen=pkt_dname_len(&pkt)) == 0) return;
+ if(dlen >= sizeof(buf)) return;
+ dname_pkt_copy(&pkt, buf, rr_dname);
+ dname_str(buf, str);
+ (void)sldns_wire2str_type_buf(rr_type, typestr, sizeof(typestr));
+ verbose(VERB_ALGO, "%s at[%d] %s %s", label, (int)rr_counter,
+ str, typestr);
+}
+
+/** check that start serial is OK for ixfr. we are at rr_counter == 0,
+ * and we are going to check rr_counter == 1 (has to be type SOA) serial */
+static int
+ixfr_start_serial(struct auth_chunk* rr_chunk, int rr_num, size_t rr_pos,
+ uint8_t* rr_dname, uint16_t rr_type, uint16_t rr_class,
+ uint32_t rr_ttl, uint16_t rr_rdlen, uint8_t* rr_rdata,
+ size_t rr_nextpos, uint32_t transfer_serial, uint32_t xfr_serial)
+{
+ uint32_t startserial;
+ /* move forward on RR */
+ chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos);
+ if(chunk_rrlist_end(rr_chunk, rr_num)) {
+ /* no second SOA */
+ verbose(VERB_OPS, "IXFR has no second SOA record");
+ return 0;
+ }
+ if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos,
+ &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen,
+ &rr_rdata, &rr_nextpos)) {
+ verbose(VERB_OPS, "IXFR cannot parse second SOA record");
+ /* failed to parse RR */
+ return 0;
+ }
+ if(rr_type != LDNS_RR_TYPE_SOA) {
+ verbose(VERB_OPS, "IXFR second record is not type SOA");
+ return 0;
+ }
+ if(rr_rdlen < 22) {
+ verbose(VERB_OPS, "IXFR, second SOA has short rdlength");
+ return 0; /* bad SOA rdlen */
+ }
+ startserial = sldns_read_uint32(rr_rdata+rr_rdlen-20);
+ if(startserial == transfer_serial) {
+ /* empty AXFR, not an IXFR */
+ verbose(VERB_OPS, "IXFR second serial same as first");
+ return 0;
+ }
+ if(startserial != xfr_serial) {
+ /* wrong start serial, it does not match the serial in
+ * memory */
+ verbose(VERB_OPS, "IXFR is from serial %u to %u but %u "
+ "in memory, rejecting the zone transfer",
+ (unsigned)startserial, (unsigned)transfer_serial,
+ (unsigned)xfr_serial);
+ return 0;
+ }
+ /* everything OK in second SOA serial */
+ return 1;
+}
+
+/** apply IXFR to zone in memory. z is locked. false on failure(mallocfail) */
+static int
+apply_ixfr(struct auth_xfer* xfr, struct auth_zone* z,
+ struct sldns_buffer* scratch_buffer)
+{
+ struct auth_chunk* rr_chunk;
+ int rr_num;
+ size_t rr_pos;
+ uint8_t* rr_dname, *rr_rdata;
+ uint16_t rr_type, rr_class, rr_rdlen;
+ uint32_t rr_ttl;
+ size_t rr_nextpos;
+ int have_transfer_serial = 0;
+ uint32_t transfer_serial = 0;
+ size_t rr_counter = 0;
+ int delmode = 0;
+ int softfail = 0;
+
+ /* start RR iterator over chunklist of packets */
+ chunk_rrlist_start(xfr, &rr_chunk, &rr_num, &rr_pos);
+ while(!chunk_rrlist_end(rr_chunk, rr_num)) {
+ if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos,
+ &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen,
+ &rr_rdata, &rr_nextpos)) {
+ /* failed to parse RR */
+ return 0;
+ }
+ if(verbosity>=7) log_rrlist_position("apply ixfr",
+ rr_chunk, rr_dname, rr_type, rr_counter);
+ /* twiddle add/del mode and check for start and end */
+ if(rr_counter == 0 && rr_type != LDNS_RR_TYPE_SOA)
+ return 0;
+ if(rr_counter == 1 && rr_type != LDNS_RR_TYPE_SOA) {
+ /* this is an AXFR returned from the IXFR master */
+ /* but that should already have been detected, by
+ * on_ixfr_is_axfr */
+ return 0;
+ }
+ if(rr_type == LDNS_RR_TYPE_SOA) {
+ uint32_t serial;
+ if(rr_rdlen < 22) return 0; /* bad SOA rdlen */
+ serial = sldns_read_uint32(rr_rdata+rr_rdlen-20);
+ if(have_transfer_serial == 0) {
+ have_transfer_serial = 1;
+ transfer_serial = serial;
+ delmode = 1; /* gets negated below */
+ /* check second RR before going any further */
+ if(!ixfr_start_serial(rr_chunk, rr_num, rr_pos,
+ rr_dname, rr_type, rr_class, rr_ttl,
+ rr_rdlen, rr_rdata, rr_nextpos,
+ transfer_serial, xfr->serial)) {
+ return 0;
+ }
+ } else if(transfer_serial == serial) {
+ have_transfer_serial++;
+ if(rr_counter == 1) {
+ /* empty AXFR, with SOA; SOA; */
+ /* should have been detected by
+ * on_ixfr_is_axfr */
+ return 0;
+ }
+ if(have_transfer_serial == 3) {
+ /* see serial three times for end */
+ /* eg. IXFR:
+ * SOA 3 start
+ * SOA 1 second RR, followed by del
+ * SOA 2 followed by add
+ * SOA 2 followed by del
+ * SOA 3 followed by add
+ * SOA 3 end */
+ /* ended by SOA record */
+ xfr->serial = transfer_serial;
+ break;
+ }
+ }
+ /* twiddle add/del mode */
+ /* switch from delete part to add part and back again
+ * just before the soa, it gets deleted and added too
+ * this means we switch to delete mode for the final
+ * SOA(so skip that one) */
+ delmode = !delmode;
+ }
+ /* process this RR */
+ /* if the RR is deleted twice or added twice, then we
+ * softfail, and continue with the rest of the IXFR, so
+ * that we serve something fairly nice during the refetch */
+ if(verbosity>=7) log_rrlist_position((delmode?"del":"add"),
+ rr_chunk, rr_dname, rr_type, rr_counter);
+ if(delmode) {
+ /* delete this RR */
+ int nonexist = 0;
+ if(!az_remove_rr_decompress(z, rr_chunk->data,
+ rr_chunk->len, scratch_buffer, rr_dname,
+ rr_type, rr_class, rr_ttl, rr_rdata, rr_rdlen,
+ &nonexist)) {
+ /* failed, malloc error or so */
+ return 0;
+ }
+ if(nonexist) {
+ /* it was removal of a nonexisting RR */
+ if(verbosity>=4) log_rrlist_position(
+ "IXFR error nonexistent RR",
+ rr_chunk, rr_dname, rr_type, rr_counter);
+ softfail = 1;
+ }
+ } else if(rr_counter != 0) {
+ /* skip first SOA RR for addition, it is added in
+ * the addition part near the end of the ixfr, when
+ * that serial is seen the second time. */
+ int duplicate = 0;
+ /* add this RR */
+ if(!az_insert_rr_decompress(z, rr_chunk->data,
+ rr_chunk->len, scratch_buffer, rr_dname,
+ rr_type, rr_class, rr_ttl, rr_rdata, rr_rdlen,
+ &duplicate)) {
+ /* failed, malloc error or so */
+ return 0;
+ }
+ if(duplicate) {
+ /* it was a duplicate */
+ if(verbosity>=4) log_rrlist_position(
+ "IXFR error duplicate RR",
+ rr_chunk, rr_dname, rr_type, rr_counter);
+ softfail = 1;
+ }
+ }
+
+ rr_counter++;
+ chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos);
+ }
+ if(softfail) {
+ verbose(VERB_ALGO, "IXFR did not apply cleanly, fetching full zone");
+ return 0;
+ }
+ return 1;
+}
+
+/** apply AXFR to zone in memory. z is locked. false on failure(mallocfail) */
+static int
+apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
+ struct sldns_buffer* scratch_buffer)
+{
+ struct auth_chunk* rr_chunk;
+ int rr_num;
+ size_t rr_pos;
+ uint8_t* rr_dname, *rr_rdata;
+ uint16_t rr_type, rr_class, rr_rdlen;
+ uint32_t rr_ttl;
+ uint32_t serial = 0;
+ size_t rr_nextpos;
+ size_t rr_counter = 0;
+ int have_end_soa = 0;
+
+ /* clear the data tree */
+ traverse_postorder(&z->data, auth_data_del, NULL);
+ rbtree_init(&z->data, &auth_data_cmp);
+ xfr->have_zone = 0;
+ xfr->serial = 0;
+
+ /* insert all RRs in to the zone */
+ /* insert the SOA only once, skip the last one */
+ /* start RR iterator over chunklist of packets */
+ chunk_rrlist_start(xfr, &rr_chunk, &rr_num, &rr_pos);
+ while(!chunk_rrlist_end(rr_chunk, rr_num)) {
+ if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos,
+ &rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen,
+ &rr_rdata, &rr_nextpos)) {
+ /* failed to parse RR */
+ return 0;
+ }
+ if(verbosity>=7) log_rrlist_position("apply_axfr",
+ rr_chunk, rr_dname, rr_type, rr_counter);
+ if(rr_type == LDNS_RR_TYPE_SOA) {
+ if(rr_counter != 0) {
+ /* end of the axfr */
+ have_end_soa = 1;
+ break;
+ }
+ if(rr_rdlen < 22) return 0; /* bad SOA rdlen */
+ serial = sldns_read_uint32(rr_rdata+rr_rdlen-20);
+ }
+
+ /* add this RR */
+ if(!az_insert_rr_decompress(z, rr_chunk->data, rr_chunk->len,
+ scratch_buffer, rr_dname, rr_type, rr_class, rr_ttl,
+ rr_rdata, rr_rdlen, NULL)) {
+ /* failed, malloc error or so */
+ return 0;
+ }
+
+ rr_counter++;
+ chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos);
+ }
+ if(!have_end_soa) {
+ log_err("no end SOA record for AXFR");
+ return 0;
+ }
+
+ xfr->serial = serial;
+ xfr->have_zone = 1;
+ return 1;
+}
+
+/** apply HTTP to zone in memory. z is locked. false on failure(mallocfail) */
+static int
+apply_http(struct auth_xfer* xfr, struct auth_zone* z,
+ struct sldns_buffer* scratch_buffer)
+{
+ /* parse data in chunks */
+ /* parse RR's and read into memory. ignore $INCLUDE from the
+ * downloaded file*/
+ struct sldns_file_parse_state pstate;
+ struct auth_chunk* chunk;
+ size_t chunk_pos;
+ memset(&pstate, 0, sizeof(pstate));
+ pstate.default_ttl = 3600;
+ if(xfr->namelen < sizeof(pstate.origin)) {
+ pstate.origin_len = xfr->namelen;
+ memmove(pstate.origin, xfr->name, xfr->namelen);
+ }
+
+ if(verbosity >= VERB_ALGO)
+ verbose(VERB_ALGO, "http download %s of size %d",
+ xfr->task_transfer->master->file,
+ (int)chunklist_sum(xfr->task_transfer->chunks_first));
+ if(xfr->task_transfer->chunks_first && verbosity >= VERB_ALGO) {
+ char preview[1024];
+ if(xfr->task_transfer->chunks_first->len+1 > sizeof(preview)) {
+ memmove(preview, xfr->task_transfer->chunks_first->data,
+ sizeof(preview)-1);
+ preview[sizeof(preview)-1]=0;
+ } else {
+ memmove(preview, xfr->task_transfer->chunks_first->data,
+ xfr->task_transfer->chunks_first->len);
+ preview[xfr->task_transfer->chunks_first->len]=0;
+ }
+ log_info("auth zone http downloaded content preview: %s",
+ preview);
+ }
+
+ /* perhaps a little syntax check before we try to apply the data? */
+ if(!http_zonefile_syntax_check(xfr, scratch_buffer)) {
+ log_err("http download %s/%s does not contain a zonefile, "
+ "but got '%s'", xfr->task_transfer->master->host,
+ xfr->task_transfer->master->file,
+ sldns_buffer_begin(scratch_buffer));
+ return 0;
+ }
+
+ /* clear the data tree */
+ traverse_postorder(&z->data, auth_data_del, NULL);
+ rbtree_init(&z->data, &auth_data_cmp);
+ xfr->have_zone = 0;
+ xfr->serial = 0;
+
+ chunk = xfr->task_transfer->chunks_first;
+ chunk_pos = 0;
+ pstate.lineno = 0;
+ while(chunkline_get_line_collated(&chunk, &chunk_pos, scratch_buffer)) {
+ /* process this line */
+ pstate.lineno++;
+ chunkline_newline_removal(scratch_buffer);
+ if(chunkline_is_comment_line_or_empty(scratch_buffer)) {
+ continue;
+ }
+ /* parse line and add RR */
+ if(http_parse_origin(scratch_buffer, &pstate)) {
+ continue; /* $ORIGIN has been handled */
+ }
+ if(http_parse_ttl(scratch_buffer, &pstate)) {
+ continue; /* $TTL has been handled */
+ }
+ if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) {
+ verbose(VERB_ALGO, "error parsing line [%s:%d] %s",
+ xfr->task_transfer->master->file,
+ pstate.lineno,
+ sldns_buffer_begin(scratch_buffer));
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/** write to zonefile after zone has been updated */
+static void
+xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
+{
+ struct auth_zone* z;
+ char tmpfile[1024];
+ lock_basic_unlock(&xfr->lock);
+
+ /* get lock again, so it is a readlock and concurrently queries
+ * can be answered */
+ 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);
+ /* the zone is gone, ignore xfr results */
+ lock_basic_lock(&xfr->lock);
+ return;
+ }
+ lock_rw_rdlock(&z->lock);
+ lock_basic_lock(&xfr->lock);
+ lock_rw_unlock(&env->auth_zones->lock);
+
+ if(z->zonefile == NULL) {
+ lock_rw_unlock(&z->lock);
+ /* no write needed, no zonefile set */
+ return;
+ }
+
+ /* write to tempfile first */
+ if((size_t)strlen(z->zonefile) + 16 > sizeof(tmpfile)) {
+ verbose(VERB_ALGO, "tmpfilename too long, cannot update "
+ " zonefile %s", z->zonefile);
+ lock_rw_unlock(&z->lock);
+ return;
+ }
+ snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", z->zonefile,
+ (unsigned)getpid());
+ if(!auth_zone_write_file(z, tmpfile)) {
+ unlink(tmpfile);
+ lock_rw_unlock(&z->lock);
+ return;
+ }
+ if(rename(tmpfile, z->zonefile) < 0) {
+ log_err("could not rename(%s, %s): %s", tmpfile, z->zonefile,
+ strerror(errno));
+ unlink(tmpfile);
+ lock_rw_unlock(&z->lock);
+ return;
+ }
+ lock_rw_unlock(&z->lock);
+}
+
+/** process chunk list and update zone in memory,
+ * return false if it did not work */
+static int
+xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
+ int* ixfr_fail)
+{
+ 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);
+ /* 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);
+
+ /* apply data */
+ if(xfr->task_transfer->master->http) {
+ if(!apply_http(xfr, z, env->scratch_buffer)) {
+ lock_rw_unlock(&z->lock);
+ verbose(VERB_ALGO, "http from %s: could not store data",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ } else if(xfr->task_transfer->on_ixfr &&
+ !xfr->task_transfer->on_ixfr_is_axfr) {
+ if(!apply_ixfr(xfr, z, env->scratch_buffer)) {
+ lock_rw_unlock(&z->lock);
+ verbose(VERB_ALGO, "xfr from %s: could not store IXFR"
+ " data", xfr->task_transfer->master->host);
+ *ixfr_fail = 1;
+ return 0;
+ }
+ } else {
+ if(!apply_axfr(xfr, z, env->scratch_buffer)) {
+ lock_rw_unlock(&z->lock);
+ verbose(VERB_ALGO, "xfr from %s: could not store AXFR"
+ " data", xfr->task_transfer->master->host);
+ return 0;
+ }
+ }
+ xfr->zone_expired = 0;
+ z->zone_expired = 0;
+ if(!xfr_find_soa(z, xfr)) {
+ lock_rw_unlock(&z->lock);
+ verbose(VERB_ALGO, "xfr from %s: no SOA in zone after update"
+ " (or malformed RR)", xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(xfr->have_zone)
+ xfr->lease_time = *env->now;
+
+ /* unlock */
+ lock_rw_unlock(&z->lock);
+
+ if(verbosity >= VERB_QUERY && xfr->have_zone) {
+ char zname[256];
+ dname_str(xfr->name, zname);
+ verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname,
+ (unsigned)xfr->serial);
+ }
+ /* see if we need to write to a zonefile */
+ xfr_write_after_update(xfr, env);
+ return 1;
+}
+
/** disown task_transfer. caller must hold xfr.lock */
static void
xfr_transfer_disown(struct auth_xfer* xfr)
@@ -3281,17 +4550,20 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
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;
+ if(sldns_buffer_capacity(buf) < 65535)
+ edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
+ else edns.udp_size = 65535;
+ /* unlock xfr during mesh_new_callback() because the callback can be
+ * called straight away */
+ lock_basic_unlock(&xfr->lock);
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
&auth_xfer_transfer_lookup_callback, xfr)) {
+ lock_basic_lock(&xfr->lock);
log_err("out of memory lookup up master %s", master->host);
- free(qinfo.qname);
return 0;
}
- free(qinfo.qname);
+ lock_basic_lock(&xfr->lock);
return 1;
}
@@ -3301,7 +4573,7 @@ static int
xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
{
struct sockaddr_storage addr;
- socklen_t addrlen = 0;
+ socklen_t addrlen = 0;
struct auth_master* master = xfr->task_transfer->master;
if(!master) return 0;
@@ -3311,10 +4583,13 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
memmove(&addr, &xfr->task_transfer->scan_addr->addr, addrlen);
} else {
if(!extstrtoaddr(master->host, &addr, &addrlen)) {
+ /* the ones that are not in addr format are supposed
+ * to be looked up. The lookup has failed however,
+ * so skip them */
char zname[255+1];
dname_str(xfr->name, zname);
- log_err("%s: cannot parse master %s", zname,
- master->host);
+ log_err("%s: failed lookup, cannot transfer from master %s",
+ zname, master->host);
return 0;
}
}
@@ -3325,47 +4600,45 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
xfr->task_transfer->cp = NULL;
}
- /* connect on fd */
- if(!xfr->task_transfer->cp) {
- int fd = outnet_get_tcp_fd(&addr, addrlen, env->cfg->tcp_mss);
- if(fd == -1) {
- char zname[255+1];
- dname_str(xfr->name, zname);
- verbose(VERB_ALGO, "cannot create fd for "
- "xfr %s to %s", zname, master->host);
- return 0;
- }
- fd_set_nonblock(fd);
- if(!outnet_tcp_connect(fd, &addr, addrlen)) {
- /* outnet_tcp_connect has closed fd on error for us */
+ if(master->http) {
+ /* perform http fetch */
+ /* store http port number into sockaddr,
+ * unless someone used unbound's host@port notation */
+ if(strchr(master->host, '@') == NULL)
+ sockaddr_store_port(&addr, addrlen, master->port);
+ xfr->task_transfer->cp = outnet_comm_point_for_http(
+ env->outnet, auth_xfer_transfer_http_callback, xfr,
+ &addr, addrlen, AUTH_TRANSFER_TIMEOUT, master->ssl,
+ master->host, master->file);
+ if(!xfr->task_transfer->cp) {
char zname[255+1];
dname_str(xfr->name, zname);
- verbose(VERB_ALGO, "cannot tcp connect() for"
- "xfr %s to %s", zname, master->host);
- return 0;
- }
-
- xfr->task_transfer->cp = comm_point_create_tcp_out(
- env->worker_base, 65552,
- auth_xfer_transfer_tcp_callback, xfr);
- if(!xfr->task_transfer->cp) {
- close(fd);
- log_err("malloc failure");
+ verbose(VERB_ALGO, "cannot create http cp "
+ "connection for %s to %s", zname,
+ master->host);
return 0;
}
- xfr->task_transfer->cp->repinfo.addrlen = addrlen;
- memcpy(&xfr->task_transfer->cp->repinfo.addr, &addr, addrlen);
- /* set timeout on TCP connection */
- comm_point_start_listening(xfr->task_transfer->cp, fd,
- AUTH_TRANSFER_TIMEOUT);
+ return 1;
}
+ /* perform AXFR/IXFR */
/* set the packet to be written */
/* create new ID */
xfr->task_transfer->id = (uint16_t)(ub_random(env->rnd)&0xffff);
- xfr_create_probe_packet(xfr, xfr->task_transfer->cp->buffer, 0,
- xfr->task_transfer->id);
+ xfr_create_ixfr_packet(xfr, env->scratch_buffer,
+ xfr->task_transfer->id, master);
+ /* connect on fd */
+ xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
+ auth_xfer_transfer_tcp_callback, xfr, &addr, addrlen,
+ env->scratch_buffer, AUTH_TRANSFER_TIMEOUT);
+ if(!xfr->task_transfer->cp) {
+ char zname[255+1];
+ dname_str(xfr->name, zname);
+ verbose(VERB_ALGO, "cannot create tcp cp connection for "
+ "xfr %s to %s", zname, master->host);
+ return 0;
+ }
return 1;
}
@@ -3383,6 +4656,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
* and we may then get an instant cache response,
* and that calls the callback just like a full
* lookup and lookup failures also call callback */
+ lock_basic_unlock(&xfr->lock);
return;
}
xfr_transfer_move_to_next_lookup(xfr, env);
@@ -3394,15 +4668,13 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
xfr->task_transfer->master = xfr_transfer_current_master(xfr);
if(xfr_transfer_init_fetch(xfr, env)) {
/* successfully started, wait for callback */
+ lock_basic_unlock(&xfr->lock);
return;
}
/* failed to fetch, next master */
- if(!xfr_transfer_nextmaster(xfr)) {
- break;
- }
+ xfr_transfer_nextmaster(xfr);
}
- lock_basic_lock(&xfr->lock);
/* we failed to fetch the zone, move to wait task
* use the shorter retry timeout */
xfr_transfer_disown(xfr);
@@ -3451,6 +4723,12 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
sa->sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa->sin6_addr, rdata, INET6_SIZE);
}
+ if(verbosity >= VERB_ALGO) {
+ char s[64];
+ addr_to_str(&a->addr, a->addrlen, s, sizeof(s));
+ verbose(VERB_ALGO, "auth host %s lookup %s",
+ m->host, s);
+ }
/* append to list */
a->next = m->list;
m->list = a;
@@ -3464,7 +4742,12 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
struct auth_xfer* xfr = (struct auth_xfer*)arg;
struct module_env* env;
log_assert(xfr->task_transfer);
+ lock_basic_lock(&xfr->lock);
env = xfr->task_transfer->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return; /* stop on quit */
+ }
/* process result */
if(rcode == LDNS_RCODE_NOERROR) {
@@ -3487,6 +4770,9 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
}
}
}
+ if(xfr->task_transfer->lookup_target->list &&
+ xfr->task_transfer->lookup_target == xfr_transfer_current_master(xfr))
+ xfr->task_transfer->scan_addr = xfr->task_transfer->lookup_target->list;
/* move to lookup AAAA after A lookup, move to next hostname lookup,
* or move to fetch the zone, or, if nothing to do, end task_transfer */
@@ -3494,15 +4780,371 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
xfr_transfer_nexttarget_or_end(xfr, env);
}
+/** check if xfer (AXFR or IXFR) packet is OK.
+ * return false if we lost connection (SERVFAIL, or unreadable).
+ * return false if we need to move from IXFR to AXFR, with gonextonfail
+ * set to false, so the same master is tried again, but with AXFR.
+ * return true if fine to link into data.
+ * return true with transferdone=true when the transfer has ended.
+ */
+static int
+check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
+ int* gonextonfail, int* transferdone)
+{
+ uint8_t* wire = sldns_buffer_begin(pkt);
+ int i;
+ if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet too small",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(!LDNS_QR_WIRE(wire)) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet has no QR flag",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(LDNS_TC_WIRE(wire)) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet has TC flag",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ /* check ID */
+ if(LDNS_ID_WIRE(wire) != xfr->task_transfer->id) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet wrong ID",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(LDNS_RCODE_WIRE(wire) != LDNS_RCODE_NOERROR) {
+ char rcode[32];
+ sldns_wire2str_rcode_buf((int)LDNS_RCODE_WIRE(wire), rcode,
+ sizeof(rcode));
+ /* if we are doing IXFR, check for fallback */
+ if(xfr->task_transfer->on_ixfr) {
+ if(LDNS_RCODE_WIRE(wire) == LDNS_RCODE_NOTIMPL ||
+ LDNS_RCODE_WIRE(wire) == LDNS_RCODE_SERVFAIL ||
+ LDNS_RCODE_WIRE(wire) == LDNS_RCODE_REFUSED ||
+ LDNS_RCODE_WIRE(wire) == LDNS_RCODE_FORMERR) {
+ verbose(VERB_ALGO, "xfr to %s, fallback "
+ "from IXFR to AXFR (with rcode %s)",
+ xfr->task_transfer->master->host,
+ rcode);
+ xfr->task_transfer->ixfr_fail = 1;
+ *gonextonfail = 0;
+ return 0;
+ }
+ }
+ verbose(VERB_ALGO, "xfr to %s failed, packet with rcode %s",
+ xfr->task_transfer->master->host, rcode);
+ return 0;
+ }
+ if(LDNS_OPCODE_WIRE(wire) != LDNS_PACKET_QUERY) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with bad opcode",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(LDNS_QDCOUNT(wire) > 1) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet has qdcount %d",
+ xfr->task_transfer->master->host,
+ (int)LDNS_QDCOUNT(wire));
+ return 0;
+ }
+
+ /* check qname */
+ sldns_buffer_set_position(pkt, LDNS_HEADER_SIZE);
+ for(i=0; i<(int)LDNS_QDCOUNT(wire); i++) {
+ size_t pos = sldns_buffer_position(pkt);
+ uint16_t qtype, qclass;
+ if(pkt_dname_len(pkt) == 0) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "malformed dname",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(dname_pkt_compare(pkt, sldns_buffer_at(pkt, pos),
+ xfr->name) != 0) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "wrong qname",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(sldns_buffer_remaining(pkt) < 4) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated query RR",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ qtype = sldns_buffer_read_u16(pkt);
+ qclass = sldns_buffer_read_u16(pkt);
+ if(qclass != xfr->dclass) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "wrong qclass",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(xfr->task_transfer->on_ixfr) {
+ if(qtype != LDNS_RR_TYPE_IXFR) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet "
+ "with wrong qtype, expected IXFR",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ } else {
+ if(qtype != LDNS_RR_TYPE_AXFR) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet "
+ "with wrong qtype, expected AXFR",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ }
+ }
+
+ /* check parse of RRs in packet, store first SOA serial
+ * to be able to detect last SOA (with that serial) to see if done */
+ /* also check for IXFR 'zone up to date' reply */
+ for(i=0; i<(int)LDNS_ANCOUNT(wire); i++) {
+ size_t pos = sldns_buffer_position(pkt);
+ uint16_t tp, rdlen;
+ if(pkt_dname_len(pkt) == 0) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "malformed dname in answer section",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(sldns_buffer_remaining(pkt) < 10) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated RR",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ tp = sldns_buffer_read_u16(pkt);
+ (void)sldns_buffer_read_u16(pkt); /* class */
+ (void)sldns_buffer_read_u32(pkt); /* ttl */
+ rdlen = sldns_buffer_read_u16(pkt);
+ if(sldns_buffer_remaining(pkt) < rdlen) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated RR rdata",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+
+ /* RR parses (haven't checked rdata itself), now look at
+ * SOA records to see serial number */
+ if(xfr->task_transfer->rr_scan_num == 0 &&
+ tp != LDNS_RR_TYPE_SOA) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "malformed zone transfer, no start SOA",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(xfr->task_transfer->rr_scan_num == 1 &&
+ tp != LDNS_RR_TYPE_SOA) {
+ /* second RR is not a SOA record, this is not an IXFR
+ * the master is replying with an AXFR */
+ xfr->task_transfer->on_ixfr_is_axfr = 1;
+ }
+ if(tp == LDNS_RR_TYPE_SOA) {
+ uint32_t serial;
+ if(rdlen < 22) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet "
+ "with SOA with malformed rdata",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(dname_pkt_compare(pkt, sldns_buffer_at(pkt, pos),
+ xfr->name) != 0) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet "
+ "with SOA with wrong dname",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+
+ /* read serial number of SOA */
+ serial = sldns_buffer_read_u32_at(pkt,
+ sldns_buffer_position(pkt)+rdlen-20);
+
+ /* check for IXFR 'zone has SOA x' reply */
+ if(xfr->task_transfer->on_ixfr &&
+ xfr->task_transfer->rr_scan_num == 0 &&
+ LDNS_ANCOUNT(wire)==1) {
+ verbose(VERB_ALGO, "xfr to %s ended, "
+ "IXFR reply that zone has serial %u",
+ xfr->task_transfer->master->host,
+ (unsigned)serial);
+ return 0;
+ }
+
+ /* if first SOA, store serial number */
+ if(xfr->task_transfer->got_xfr_serial == 0) {
+ xfr->task_transfer->got_xfr_serial = 1;
+ xfr->task_transfer->incoming_xfr_serial =
+ serial;
+ verbose(VERB_ALGO, "xfr %s: contains "
+ "SOA serial %u",
+ xfr->task_transfer->master->host,
+ (unsigned)serial);
+ /* see if end of AXFR */
+ } else if(!xfr->task_transfer->on_ixfr ||
+ xfr->task_transfer->on_ixfr_is_axfr) {
+ /* second SOA with serial is the end
+ * for AXFR */
+ *transferdone = 1;
+ verbose(VERB_ALGO, "xfr %s: last AXFR packet",
+ xfr->task_transfer->master->host);
+ /* for IXFR, count SOA records with that serial */
+ } else if(xfr->task_transfer->incoming_xfr_serial ==
+ serial && xfr->task_transfer->got_xfr_serial
+ == 1) {
+ xfr->task_transfer->got_xfr_serial++;
+ /* if not first soa, if serial==firstserial, the
+ * third time we are at the end, for IXFR */
+ } else if(xfr->task_transfer->incoming_xfr_serial ==
+ serial && xfr->task_transfer->got_xfr_serial
+ == 2) {
+ verbose(VERB_ALGO, "xfr %s: last IXFR packet",
+ xfr->task_transfer->master->host);
+ *transferdone = 1;
+ /* continue parse check, if that succeeds,
+ * transfer is done */
+ }
+ }
+ xfr->task_transfer->rr_scan_num++;
+
+ /* skip over RR rdata to go to the next RR */
+ sldns_buffer_skip(pkt, (ssize_t)rdlen);
+ }
+
+ /* check authority section */
+ /* we skip over the RRs checking packet format */
+ for(i=0; i<(int)LDNS_NSCOUNT(wire); i++) {
+ uint16_t rdlen;
+ if(pkt_dname_len(pkt) == 0) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "malformed dname in authority section",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(sldns_buffer_remaining(pkt) < 10) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated RR",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ (void)sldns_buffer_read_u16(pkt); /* type */
+ (void)sldns_buffer_read_u16(pkt); /* class */
+ (void)sldns_buffer_read_u32(pkt); /* ttl */
+ rdlen = sldns_buffer_read_u16(pkt);
+ if(sldns_buffer_remaining(pkt) < rdlen) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated RR rdata",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ /* skip over RR rdata to go to the next RR */
+ sldns_buffer_skip(pkt, (ssize_t)rdlen);
+ }
+
+ /* check additional section */
+ for(i=0; i<(int)LDNS_ARCOUNT(wire); i++) {
+ uint16_t rdlen;
+ if(pkt_dname_len(pkt) == 0) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "malformed dname in additional section",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ if(sldns_buffer_remaining(pkt) < 10) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated RR",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ (void)sldns_buffer_read_u16(pkt); /* type */
+ (void)sldns_buffer_read_u16(pkt); /* class */
+ (void)sldns_buffer_read_u32(pkt); /* ttl */
+ rdlen = sldns_buffer_read_u16(pkt);
+ if(sldns_buffer_remaining(pkt) < rdlen) {
+ verbose(VERB_ALGO, "xfr to %s failed, packet with "
+ "truncated RR rdata",
+ xfr->task_transfer->master->host);
+ return 0;
+ }
+ /* skip over RR rdata to go to the next RR */
+ sldns_buffer_skip(pkt, (ssize_t)rdlen);
+ }
+
+ return 1;
+}
+
+/** Link the data from this packet into the worklist of transferred data */
+static int
+xfer_link_data(sldns_buffer* pkt, struct auth_xfer* xfr)
+{
+ /* alloc it */
+ struct auth_chunk* e;
+ e = (struct auth_chunk*)calloc(1, sizeof(*e));
+ if(!e) return 0;
+ e->next = NULL;
+ e->len = sldns_buffer_limit(pkt);
+ e->data = memdup(sldns_buffer_begin(pkt), e->len);
+ if(!e->data) {
+ free(e);
+ return 0;
+ }
+
+ /* alloc succeeded, link into list */
+ if(!xfr->task_transfer->chunks_first)
+ xfr->task_transfer->chunks_first = e;
+ if(xfr->task_transfer->chunks_last)
+ xfr->task_transfer->chunks_last->next = e;
+ xfr->task_transfer->chunks_last = e;
+ return 1;
+}
+
+/** task transfer. the list of data is complete. process it and if failed
+ * move to next master, if succeeded, end the task transfer */
+static void
+process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
+{
+ int ixfr_fail = 0;
+ if(xfr_process_chunk_list(xfr, env, &ixfr_fail)) {
+ /* it worked! */
+ auth_chunks_delete(xfr->task_transfer);
+
+ /* we fetched the zone, move to wait task */
+ xfr_transfer_disown(xfr);
+
+ /* pick up the nextprobe task and wait (normail wait time) */
+ xfr_set_timeout(xfr, env, 0);
+ lock_basic_unlock(&xfr->lock);
+ return;
+ }
+ /* processing failed */
+ /* when done, delete data from list */
+ auth_chunks_delete(xfr->task_transfer);
+ if(ixfr_fail) {
+ xfr->task_transfer->ixfr_fail = 1;
+ } else {
+ xfr_transfer_nextmaster(xfr);
+ }
+ xfr_transfer_nexttarget_or_end(xfr, env);
+}
+
/** callback for task_transfer tcp connections */
int
auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
- struct comm_reply* ATTR_UNUSED(repinfo))
+ struct comm_reply* ATTR_UNUSED(repinfo))
{
struct auth_xfer* xfr = (struct auth_xfer*)arg;
struct module_env* env;
- log_assert(xfr->task_probe);
- env = xfr->task_probe->env;
+ int gonextonfail = 1;
+ int transferdone = 0;
+ log_assert(xfr->task_transfer);
+ lock_basic_lock(&xfr->lock);
+ env = xfr->task_transfer->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return 0; /* stop on quit */
+ }
if(err != NETEVENT_NOERROR) {
/* connection failed, closed, or timeout */
@@ -3510,6 +5152,9 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
* and continue task_transfer*/
verbose(VERB_ALGO, "xfr stopped, connection lost to %s",
xfr->task_transfer->master->host);
+ failed:
+ /* delete transferred data from list */
+ auth_chunks_delete(xfr->task_transfer);
comm_point_delete(xfr->task_transfer->cp);
xfr->task_transfer->cp = NULL;
xfr_transfer_nextmaster(xfr);
@@ -3517,14 +5162,96 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
return 0;
}
- /* TODO: handle returned packet */
+ /* handle returned packet */
/* if it fails, cleanup and end this transfer */
/* if it needs to fallback from IXFR to AXFR, do that */
+ if(!check_xfer_packet(c->buffer, xfr, &gonextonfail, &transferdone)) {
+ goto failed;
+ }
/* if it is good, link it into the list of data */
+ /* if the link into list of data fails (malloc fail) cleanup and end */
+ if(!xfer_link_data(c->buffer, xfr)) {
+ verbose(VERB_ALGO, "xfr stopped to %s, malloc failed",
+ xfr->task_transfer->master->host);
+ goto failed;
+ }
+ /* if the transfer is done now, disconnect and process the list */
+ if(transferdone) {
+ comm_point_delete(xfr->task_transfer->cp);
+ xfr->task_transfer->cp = NULL;
+ process_list_end_transfer(xfr, env);
+ return 0;
+ }
/* if we want to read more messages, setup the commpoint to read
* a DNS packet, and the timeout */
+ lock_basic_unlock(&xfr->lock);
c->tcp_is_reading = 1;
+ sldns_buffer_clear(c->buffer);
+ comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT);
+ return 0;
+}
+
+/** callback for task_transfer http connections */
+int
+auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
+ struct comm_reply* repinfo)
+{
+ struct auth_xfer* xfr = (struct auth_xfer*)arg;
+ struct module_env* env;
+ log_assert(xfr->task_transfer);
+ lock_basic_lock(&xfr->lock);
+ env = xfr->task_transfer->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return 0; /* stop on quit */
+ }
+ verbose(VERB_ALGO, "auth zone transfer http callback");
+
+ if(err != NETEVENT_NOERROR && err != NETEVENT_DONE) {
+ /* connection failed, closed, or timeout */
+ /* stop this transfer, cleanup
+ * and continue task_transfer*/
+ verbose(VERB_ALGO, "http stopped, connection lost to %s",
+ xfr->task_transfer->master->host);
+ failed:
+ /* delete transferred data from list */
+ auth_chunks_delete(xfr->task_transfer);
+ if(repinfo) repinfo->c = NULL; /* signal cp deleted to
+ the routine calling this callback */
+ comm_point_delete(xfr->task_transfer->cp);
+ xfr->task_transfer->cp = NULL;
+ xfr_transfer_nextmaster(xfr);
+ xfr_transfer_nexttarget_or_end(xfr, env);
+ return 0;
+ }
+
+ /* if it is good, link it into the list of data */
+ /* if the link into list of data fails (malloc fail) cleanup and end */
+ if(sldns_buffer_limit(c->buffer) > 0) {
+ verbose(VERB_ALGO, "auth zone http queued up %d bytes",
+ (int)sldns_buffer_limit(c->buffer));
+ if(!xfer_link_data(c->buffer, xfr)) {
+ verbose(VERB_ALGO, "http stopped to %s, malloc failed",
+ xfr->task_transfer->master->host);
+ goto failed;
+ }
+ }
+ /* if the transfer is done now, disconnect and process the list */
+ if(err == NETEVENT_DONE) {
+ if(repinfo) repinfo->c = NULL; /* signal cp deleted to
+ the routine calling this callback */
+ comm_point_delete(xfr->task_transfer->cp);
+ xfr->task_transfer->cp = NULL;
+ process_list_end_transfer(xfr, env);
+ return 0;
+ }
+
+ /* if we want to read more messages, setup the commpoint to read
+ * a DNS packet, and the timeout */
+ lock_basic_unlock(&xfr->lock);
+ c->tcp_is_reading = 1;
+ sldns_buffer_clear(c->buffer);
comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT);
return 0;
}
@@ -3541,7 +5268,6 @@ xfr_start_transfer(struct auth_xfer* xfr, struct module_env* env,
log_assert(xfr->task_transfer->chunks_last == NULL);
xfr->task_transfer->worker = env->worker;
xfr->task_transfer->env = env;
- lock_basic_unlock(&xfr->lock);
/* init transfer process */
/* find that master in the transfer's list of masters? */
@@ -3586,10 +5312,13 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
memmove(&addr, &xfr->task_probe->scan_addr->addr, addrlen);
} else {
if(!extstrtoaddr(master->host, &addr, &addrlen)) {
+ /* the ones that are not in addr format are supposed
+ * to be looked up. The lookup has failed however,
+ * so skip them */
char zname[255+1];
dname_str(xfr->name, zname);
- log_err("%s: cannot parse master %s", zname,
- master->host);
+ log_err("%s: failed lookup, cannot probe to master %s",
+ zname, master->host);
return 0;
}
}
@@ -3599,25 +5328,18 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
* 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_create_probe_packet(xfr, env->scratch_buffer, 1,
+ xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
xfr->task_probe->id);
if(!xfr->task_probe->cp) {
- int fd = xfr_fd_for_master(env, &addr, addrlen, master->host);
- if(fd == -1) {
+ xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
+ auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
+ if(!xfr->task_probe->cp) {
char zname[255+1];
dname_str(xfr->name, zname);
- verbose(VERB_ALGO, "cannot create fd for "
+ verbose(VERB_ALGO, "cannot create udp cp for "
"probe %s to %s", zname, master->host);
return 0;
}
- xfr->task_probe->cp = comm_point_create_udp(env->worker_base,
- fd, env->outnet->udp_buff, auth_xfer_probe_udp_callback,
- xfr);
- if(!xfr->task_probe->cp) {
- close(fd);
- log_err("malloc failure");
- return 0;
- }
}
if(!xfr->task_probe->timer) {
xfr->task_probe->timer = comm_timer_create(env->worker_base,
@@ -3654,11 +5376,17 @@ auth_xfer_probe_timer_callback(void* arg)
struct auth_xfer* xfr = (struct auth_xfer*)arg;
struct module_env* env;
log_assert(xfr->task_probe);
+ lock_basic_lock(&xfr->lock);
env = xfr->task_probe->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return; /* stop on quit */
+ }
if(xfr->task_probe->timeout <= AUTH_PROBE_TIMEOUT_STOP) {
/* try again with bigger timeout */
if(xfr_probe_send_probe(xfr, env, xfr->task_probe->timeout*2)) {
+ lock_basic_unlock(&xfr->lock);
return;
}
}
@@ -3674,12 +5402,17 @@ auth_xfer_probe_timer_callback(void* arg)
/** callback for task_probe udp packets */
int
auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
- struct comm_reply* repinfo)
+ struct comm_reply* repinfo)
{
struct auth_xfer* xfr = (struct auth_xfer*)arg;
struct module_env* env;
log_assert(xfr->task_probe);
+ lock_basic_lock(&xfr->lock);
env = xfr->task_probe->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return 0; /* stop on quit */
+ }
/* the comm_point_udp_callback is in a for loop for NUM_UDP_PER_SELECT
* and we set rep.c=NULL to stop if from looking inside the commpoint*/
@@ -3693,20 +5426,36 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr,
&serial)) {
/* successful lookup */
+ if(verbosity >= VERB_ALGO) {
+ char buf[256];
+ dname_str(xfr->name, buf);
+ verbose(VERB_ALGO, "auth zone %s: soa probe "
+ "serial is %u", buf, (unsigned)serial);
+ }
/* see if this serial indicates that the zone has
* to be updated */
- lock_basic_lock(&xfr->lock);
if(xfr_serial_means_update(xfr, serial)) {
/* if updated, start the transfer task, if needed */
+ verbose(VERB_ALGO, "auth_zone updated, start transfer");
if(xfr->task_transfer->worker == NULL) {
+ struct auth_master* master =
+ xfr_probe_current_master(xfr);
+ /* if we have download URLs use them
+ * in preference to this master we
+ * just probed the SOA from */
+ if(xfr->task_transfer->masters &&
+ xfr->task_transfer->masters->http)
+ master = NULL;
xfr_probe_disown(xfr);
- xfr_start_transfer(xfr, env,
- xfr_probe_current_master(xfr));
+ xfr_start_transfer(xfr, env, master);
return 0;
}
} else {
/* if zone not updated, start the wait timer again */
+ verbose(VERB_ALGO, "auth_zone unchanged, new lease, wait");
+ if(xfr->have_zone)
+ xfr->lease_time = *env->now;
if(xfr->task_nextprobe->worker == NULL)
xfr_set_timeout(xfr, env, 0);
}
@@ -3718,6 +5467,11 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
return 0;
}
}
+ if(verbosity >= VERB_ALGO) {
+ char buf[256];
+ dname_str(xfr->name, buf);
+ verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf);
+ }
/* failed lookup */
/* delete commpoint so a new one is created, with a fresh port nr */
@@ -3776,17 +5530,20 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
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;
+ if(sldns_buffer_capacity(buf) < 65535)
+ edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
+ else edns.udp_size = 65535;
+ /* unlock xfr during mesh_new_callback() because the callback can be
+ * called straight away */
+ lock_basic_unlock(&xfr->lock);
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
&auth_xfer_probe_lookup_callback, xfr)) {
+ lock_basic_lock(&xfr->lock);
log_err("out of memory lookup up master %s", master->host);
- free(qinfo.qname);
return 0;
}
- free(qinfo.qname);
+ lock_basic_lock(&xfr->lock);
return 1;
}
@@ -3802,6 +5559,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
* and we may then get an instant cache response,
* and that calls the callback just like a full
* lookup and lookup failures also call callback */
+ lock_basic_unlock(&xfr->lock);
return;
}
xfr_probe_move_to_next_lookup(xfr, env);
@@ -3811,15 +5569,13 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
while(!xfr_probe_end_of_list(xfr)) {
if(xfr_probe_send_probe(xfr, env, AUTH_PROBE_TIMEOUT)) {
/* successfully sent probe, wait for callback */
+ lock_basic_unlock(&xfr->lock);
return;
}
/* failed to send probe, next master */
- if(!xfr_probe_nextmaster(xfr)) {
- break;
- }
+ xfr_probe_nextmaster(xfr);
}
- lock_basic_lock(&xfr->lock);
/* we failed to send this as well, move to the wait task,
* use the shorter retry timeout */
xfr_probe_disown(xfr);
@@ -3836,7 +5592,12 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
struct auth_xfer* xfr = (struct auth_xfer*)arg;
struct module_env* env;
log_assert(xfr->task_probe);
+ lock_basic_lock(&xfr->lock);
env = xfr->task_probe->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return; /* stop on quit */
+ }
/* process result */
if(rcode == LDNS_RCODE_NOERROR) {
@@ -3859,6 +5620,9 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
}
}
}
+ if(xfr->task_probe->lookup_target->list &&
+ xfr->task_probe->lookup_target == xfr_probe_current_master(xfr))
+ xfr->task_probe->scan_addr = xfr->task_probe->lookup_target->list;
/* move to lookup AAAA after A lookup, move to next hostname lookup,
* or move to send the probes, or, if nothing to do, end task_probe */
@@ -3866,6 +5630,20 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
xfr_probe_send_or_end(xfr, env);
}
+/** disown task_nextprobe. caller must hold xfr.lock */
+static void
+xfr_nextprobe_disown(struct auth_xfer* xfr)
+{
+ /* delete the timer, because the next worker to pick this up may
+ * not have the same event base */
+ comm_timer_delete(xfr->task_nextprobe->timer);
+ xfr->task_nextprobe->timer = NULL;
+ xfr->task_nextprobe->next_probe = 0;
+ /* we don't own this item anymore */
+ xfr->task_nextprobe->worker = NULL;
+ xfr->task_nextprobe->env = NULL;
+}
+
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
void
auth_xfer_timer(void* arg)
@@ -3875,31 +5653,39 @@ auth_xfer_timer(void* arg)
log_assert(xfr->task_nextprobe);
lock_basic_lock(&xfr->lock);
env = xfr->task_nextprobe->env;
+ if(env->outnet->want_to_quit) {
+ lock_basic_unlock(&xfr->lock);
+ return; /* stop on quit */
+ }
/* see if zone has expired, and if so, also set auth_zone expired */
if(xfr->have_zone && !xfr->zone_expired &&
- *env->now >= xfr->task_nextprobe->lease_time + xfr->expiry) {
+ *env->now >= xfr->lease_time + xfr->expiry) {
lock_basic_unlock(&xfr->lock);
auth_xfer_set_expired(xfr, env, 1);
lock_basic_lock(&xfr->lock);
}
- /* delete the timer, because the next worker to pick this up may
- * not have the same event base */
- comm_timer_delete(xfr->task_nextprobe->timer);
- xfr->task_nextprobe->timer = NULL;
- xfr->task_nextprobe->next_probe = 0;
- /* we don't own this item anymore */
- xfr->task_nextprobe->worker = NULL;
- xfr->task_nextprobe->env = NULL;
+ xfr_nextprobe_disown(xfr);
/* see if we need to start a probe (or maybe it is already in
* progress (due to notify)) */
if(xfr->task_probe->worker == NULL) {
+ if(xfr->task_probe->masters == NULL) {
+ /* useless to pick up task_probe, no masters to
+ * probe. Instead attempt to pick up task transfer */
+ if(xfr->task_transfer->worker == NULL) {
+ xfr_start_transfer(xfr, env, NULL);
+ } else {
+ /* task transfer already in progress */
+ lock_basic_unlock(&xfr->lock);
+ }
+ return;
+ }
+
/* pick up the probe task ourselves */
xfr->task_probe->worker = env->worker;
xfr->task_probe->env = env;
- lock_basic_unlock(&xfr->lock);
xfr->task_probe->cp = NULL;
/* start the task */
@@ -3932,15 +5718,32 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
* but if expiry is sooner, use that one.
* after a failure, use the retry timer instead. */
xfr->task_nextprobe->next_probe = *env->now;
- if(xfr->task_nextprobe->lease_time)
- xfr->task_nextprobe->next_probe =
- xfr->task_nextprobe->lease_time;
+ if(xfr->lease_time)
+ xfr->task_nextprobe->next_probe = xfr->lease_time;
+
+ if(!failure) {
+ xfr->task_nextprobe->backoff = 0;
+ } else {
+ if(xfr->task_nextprobe->backoff == 0)
+ xfr->task_nextprobe->backoff = 3;
+ else xfr->task_nextprobe->backoff *= 2;
+ if(xfr->task_nextprobe->backoff > AUTH_TRANSFER_MAX_BACKOFF)
+ xfr->task_nextprobe->backoff =
+ AUTH_TRANSFER_MAX_BACKOFF;
+ }
+
if(xfr->have_zone) {
time_t wait = xfr->refresh;
if(failure) wait = xfr->retry;
if(xfr->expiry < wait)
xfr->task_nextprobe->next_probe += xfr->expiry;
else xfr->task_nextprobe->next_probe += wait;
+ if(failure)
+ xfr->task_nextprobe->next_probe +=
+ xfr->task_nextprobe->backoff;
+ } else {
+ xfr->task_nextprobe->next_probe +=
+ xfr->task_nextprobe->backoff;
}
if(!xfr->task_nextprobe->timer) {
@@ -3962,6 +5765,12 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
tv.tv_sec = xfr->task_nextprobe->next_probe -
*(xfr->task_nextprobe->env->now);
else tv.tv_sec = 0;
+ if(verbosity >= VERB_ALGO) {
+ char zname[255+1];
+ dname_str(xfr->name, zname);
+ verbose(VERB_ALGO, "auth zone %s timeout in %d seconds",
+ zname, (int)tv.tv_sec);
+ }
tv.tv_usec = 0;
comm_timer_set(xfr->task_nextprobe->timer, &tv);
}
@@ -3970,11 +5779,15 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
void
auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
{
- /* TODO: call this from worker0 at start of unbound */
struct auth_xfer* x;
lock_rw_wrlock(&az->lock);
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
lock_basic_lock(&x->lock);
+ /* set lease_time, because we now have timestamp in env,
+ * (not earlier during startup and apply_cfg), and this
+ * notes the start time when the data was acquired */
+ if(x->have_zone)
+ x->lease_time = *env->now;
if(x->task_nextprobe && x->task_nextprobe->worker == NULL)
xfr_set_timeout(x, env, 0);
lock_basic_unlock(&x->lock);
@@ -3982,6 +5795,27 @@ auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
lock_rw_unlock(&az->lock);
}
+void auth_zones_cleanup(struct auth_zones* az)
+{
+ struct auth_xfer* x;
+ lock_rw_wrlock(&az->lock);
+ RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
+ lock_basic_lock(&x->lock);
+ if(x->task_nextprobe && x->task_nextprobe->worker != NULL) {
+ xfr_nextprobe_disown(x);
+ }
+ if(x->task_probe && x->task_probe->worker != NULL) {
+ xfr_probe_disown(x);
+ }
+ if(x->task_transfer && x->task_transfer->worker != NULL) {
+ auth_chunks_delete(x->task_transfer);
+ xfr_transfer_disown(x);
+ }
+ lock_basic_unlock(&x->lock);
+ }
+ lock_rw_unlock(&az->lock);
+}
+
/**
* malloc the xfer and tasks
* @param z: auth_zone with name of zone.
@@ -4028,18 +5862,32 @@ auth_xfer_new(struct auth_zone* z)
}
lock_basic_init(&xfr->lock);
- lock_protect(&xfr->lock, xfr, sizeof(*xfr));
+ lock_protect(&xfr->lock, &xfr->name, sizeof(xfr->name));
+ lock_protect(&xfr->lock, &xfr->namelen, sizeof(xfr->namelen));
+ lock_protect(&xfr->lock, xfr->name, xfr->namelen);
+ lock_protect(&xfr->lock, &xfr->namelabs, sizeof(xfr->namelabs));
+ lock_protect(&xfr->lock, &xfr->dclass, sizeof(xfr->dclass));
+ lock_protect(&xfr->lock, &xfr->notify_received, sizeof(xfr->notify_received));
+ lock_protect(&xfr->lock, &xfr->notify_serial, sizeof(xfr->notify_serial));
+ lock_protect(&xfr->lock, &xfr->zone_expired, sizeof(xfr->zone_expired));
+ lock_protect(&xfr->lock, &xfr->have_zone, sizeof(xfr->have_zone));
+ lock_protect(&xfr->lock, &xfr->serial, sizeof(xfr->serial));
+ lock_protect(&xfr->lock, &xfr->retry, sizeof(xfr->retry));
+ lock_protect(&xfr->lock, &xfr->refresh, sizeof(xfr->refresh));
+ lock_protect(&xfr->lock, &xfr->expiry, sizeof(xfr->expiry));
+ lock_protect(&xfr->lock, &xfr->lease_time, sizeof(xfr->lease_time));
lock_protect(&xfr->lock, &xfr->task_nextprobe->worker,
sizeof(xfr->task_nextprobe->worker));
lock_protect(&xfr->lock, &xfr->task_probe->worker,
sizeof(xfr->task_probe->worker));
lock_protect(&xfr->lock, &xfr->task_transfer->worker,
sizeof(xfr->task_transfer->worker));
+ lock_basic_lock(&xfr->lock);
return xfr;
}
/** Create auth_xfer structure.
- * This populates the have_zone, soa values, next_probe and so on times.
+ * This populates the have_zone, soa values, and so on times.
* and sets the timeout, if a zone transfer is needed a short timeout is set.
* For that the auth_zone itself must exist (and read in zonefile)
* returns false on alloc failure. */
@@ -4076,8 +5924,122 @@ auth_master_new(struct auth_master*** list)
return m;
}
+/** dup_prefix : create string from initial part of other string, malloced */
+static char*
+dup_prefix(char* str, size_t num)
+{
+ char* result;
+ size_t len = strlen(str);
+ if(len < num) num = len; /* not more than strlen */
+ result = (char*)malloc(num+1);
+ if(!result) {
+ log_err("malloc failure");
+ return result;
+ }
+ memmove(result, str, num);
+ result[num] = 0;
+ return result;
+}
+
+/** dup string and print error on error */
+static char*
+dup_all(char* str)
+{
+ char* result = strdup(str);
+ if(!str) {
+ log_err("malloc failure");
+ return NULL;
+ }
+ return result;
+}
+
+/** find first of two characters */
+static char*
+str_find_first_of_chars(char* s, char a, char b)
+{
+ char* ra = strchr(s, a);
+ char* rb = strchr(s, b);
+ if(!ra) return rb;
+ if(!rb) return ra;
+ if(ra < rb) return ra;
+ return rb;
+}
+
+/** parse URL into host and file parts, false on malloc or parse error */
+static int
+parse_url(char* url, char** host, char** file, int* port, int* ssl)
+{
+ char* p = url;
+ /* parse http://www.example.com/file.htm
+ * or http://127.0.0.1 (index.html)
+ * or https://[::1@1234]/a/b/c/d */
+ *ssl = 1;
+ *port = AUTH_HTTPS_PORT;
+
+ /* parse http:// or https:// */
+ if(strncmp(p, "http://", 7) == 0) {
+ p += 7;
+ *ssl = 0;
+ *port = AUTH_HTTP_PORT;
+ } else if(strncmp(p, "https://", 8) == 0) {
+ p += 8;
+ } else if(strstr(p, "://") && strchr(p, '/') > strstr(p, "://") &&
+ strchr(p, ':') >= strstr(p, "://")) {
+ char* uri = dup_prefix(p, (size_t)(strstr(p, "://")-p));
+ log_err("protocol %s:// not supported (for url %s)",
+ uri?uri:"", p);
+ free(uri);
+ return 0;
+ }
+
+ /* parse hostname part */
+ if(p[0] == '[') {
+ char* end = strchr(p, ']');
+ p++; /* skip over [ */
+ if(end) {
+ *host = dup_prefix(p, (size_t)(end-p));
+ if(!*host) return 0;
+ p = end+1; /* skip over ] */
+ } else {
+ *host = dup_all(p);
+ if(!*host) return 0;
+ p = end;
+ }
+ } else {
+ char* end = str_find_first_of_chars(p, ':', '/');
+ if(end) {
+ *host = dup_prefix(p, (size_t)(end-p));
+ if(!*host) return 0;
+ } else {
+ *host = dup_all(p);
+ if(!*host) return 0;
+ }
+ p = end; /* at next : or / or NULL */
+ }
+
+ /* parse port number */
+ if(p && p[0] == ':') {
+ char* end = NULL;
+ *port = strtol(p+1, &end, 10);
+ p = end;
+ }
+
+ /* parse filename part */
+ while(p && *p == '/')
+ p++;
+ if(!p || p[0] == 0)
+ *file = strdup("index.html");
+ else *file = strdup(p);
+ if(!*file) {
+ log_err("malloc failure");
+ return 0;
+ }
+ return 1;
+}
+
int
-xfer_set_masters(struct auth_master** list, struct config_auth* c)
+xfer_set_masters(struct auth_master** list, struct config_auth* c,
+ int with_http)
{
struct auth_master* m;
struct config_strlist* p;
@@ -4085,19 +6047,16 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c)
while(*list) {
list = &( (*list)->next );
}
- for(p = c->masters; p; p = p->next) {
+ if(with_http)
+ for(p = c->urls; p; p = p->next) {
m = auth_master_new(&list);
- m->ixfr = 1;
- m->host = strdup(p->str);
- if(!m->host) {
- log_err("malloc failure");
+ m->http = 1;
+ if(!parse_url(p->str, &m->host, &m->file, &m->port, &m->ssl))
return 0;
- }
}
- for(p = c->urls; p; p = p->next) {
+ for(p = c->masters; p; p = p->next) {
m = auth_master_new(&list);
- m->http = 1;
- /* TODO parse url, get host, file */
+ m->ixfr = 1; /* this flag is not configurable */
m->host = strdup(p->str);
if(!m->host) {
log_err("malloc failure");
@@ -4107,17 +6066,17 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c)
return 1;
}
-#define SERIAL_BITS 32
+#define SERIAL_BITS 32
int
compare_serial(uint32_t a, uint32_t b)
{
- const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1));
+ const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1));
- if (a == b) {
- return 0;
- } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) {
- return -1;
- } else {
- return 1;
- }
+ if (a == b) {
+ return 0;
+ } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) {
+ return -1;
+ } else {
+ return 1;
+ }
}
diff --git a/usr.sbin/unbound/services/authzone.h b/usr.sbin/unbound/services/authzone.h
index 2ebc5f97e40..d54ef4b96e4 100644
--- a/usr.sbin/unbound/services/authzone.h
+++ b/usr.sbin/unbound/services/authzone.h
@@ -237,6 +237,11 @@ struct auth_xfer {
* valid any more, if no master responds within this time, either
* with the current zone or a new zone. */
time_t expiry;
+
+ /** zone lease start time (start+expiry is expiration time).
+ * this is renewed every SOA probe and transfer. On zone load
+ * from zonefile it is also set (with probe set soon to check) */
+ time_t lease_time;
};
/**
@@ -254,12 +259,10 @@ struct auth_nextprobe {
/* module env for this task */
struct module_env* env;
+ /** increasing backoff for failures */
+ time_t backoff;
/** Timeout for next probe (for SOA) */
time_t next_probe;
- /** zone lease start time (start+expiry is expiration time).
- * this is renewed every SOA probe and transfer. On zone load
- * from zonefile it is also set (with probe set soon to check) */
- time_t lease_time;
/** timeout callback for next_probe or expiry(if that is sooner).
* it is on the worker's event_base */
struct comm_timer* timer;
@@ -355,6 +358,18 @@ struct auth_transfer {
* data or add of duplicate data). Flag is cleared once the retry
* with axfr is done. */
int ixfr_fail;
+ /** we are doing IXFR right now */
+ int on_ixfr;
+ /** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
+ * 1 we saw the first, 2 we saw the second, 3 must be last SOA in xfr*/
+ int got_xfr_serial;
+ /** number of RRs scanned for AXFR/IXFR detection */
+ size_t rr_scan_num;
+ /** we are doing an IXFR but we detected an AXFR contents */
+ int on_ixfr_is_axfr;
+ /** the serial number for the current AXFR/IXFR incoming reply,
+ * for IXFR, the outermost SOA records serial */
+ uint32_t incoming_xfr_serial;
/** dns id of AXFR query */
uint16_t id;
@@ -387,6 +402,8 @@ struct auth_master {
int ixfr;
/** use ssl for channel */
int ssl;
+ /** the port number (for urls) */
+ int port;
/** if the host is a hostname, the list of resolved addrs, if any*/
struct auth_addr* list;
};
@@ -413,11 +430,24 @@ struct auth_zones* auth_zones_create(void);
* @param az: auth zones structure
* @param cfg: config to apply.
* @param setup: if true, also sets up values in the auth zones structure
- * @param env: for setup, with current time.
* @return false on failure.
*/
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
- int setup, struct module_env* env);
+ int setup);
+
+/** initial pick up of worker timeouts, ties events to worker event loop
+ * @param az: auth zones structure
+ * @param env: worker env, of first worker that receives the events (if any)
+ * in its eventloop.
+ */
+void auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env);
+
+/**
+ * Cleanup auth zones. This removes all events from event bases.
+ * Stops the xfr tasks. But leaves zone data.
+ * @param az: auth zones structure.
+ */
+void auth_zones_cleanup(struct auth_zones* az);
/**
* Delete auth zones structure
@@ -471,11 +501,13 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
* Return NULL when there is no auth_zone above the give name, otherwise
* returns the closest auth_zone above the qname that pertains to it.
* @param az: auth zones structure.
- * @param qinfo: query info to lookup.
+ * @param name: query to look up for.
+ * @param name_len: length of name.
+ * @param dclass: class of zone to find.
* @return NULL or auth_zone that pertains to the query.
*/
struct auth_zone* auth_zones_find_zone(struct auth_zones* az,
- struct query_info* qinfo);
+ uint8_t* name, size_t name_len, uint16_t dclass);
/** find an auth zone by name (exact match by name or NULL returned) */
struct auth_zone* auth_zone_find(struct auth_zones* az, uint8_t* nm,
@@ -485,7 +517,6 @@ struct auth_zone* auth_zone_find(struct auth_zones* az, uint8_t* nm,
struct auth_xfer* auth_xfer_find(struct auth_zones* az, uint8_t* nm,
size_t nmlen, uint16_t dclass);
-
/** create an auth zone. returns wrlocked zone. caller must have wrlock
* on az. returns NULL on malloc failure */
struct auth_zone* auth_zone_create(struct auth_zones* az, uint8_t* nm,
@@ -498,6 +529,18 @@ int auth_zone_set_zonefile(struct auth_zone* z, char* zonefile);
* fallbackstr is "yes" or "no". false on parse failure. */
int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
+/** see if the auth zone for the name can fallback
+ * @param az: auth zones
+ * @param nm: name of delegation point.
+ * @param nmlen: length of nm.
+ * @param dclass: class of zone to look for.
+ * @return true if fallback_enabled is true. false if not.
+ * if the zone does not exist, fallback is true (more lenient)
+ * also true if zone does not do upstream requests.
+ */
+int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
+ uint16_t dclass);
+
/** read auth zone from zonefile. caller must lock zone. false on failure */
int auth_zone_read_zonefile(struct auth_zone* z);
@@ -522,10 +565,11 @@ struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
* Set masters in auth xfer structure from config.
* @param list: pointer to start of list. The malloced list is returned here.
* @param c: the config items to copy over.
+ * @param with_http: if true, http urls are also included, before the masters.
* @return false on failure.
*/
-int xfer_set_masters(struct auth_master** list, struct config_auth* c);
-
+int xfer_set_masters(struct auth_master** list, struct config_auth* c,
+ int with_http);
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
void auth_xfer_timer(void* arg);
@@ -536,6 +580,9 @@ int auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
/** callback for task_transfer tcp connections */
int auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
struct comm_reply* repinfo);
+/** callback for task_transfer http connections */
+int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
+ struct comm_reply* repinfo);
/** xfer probe timeout callback, part of task_probe */
void auth_xfer_probe_timer_callback(void* arg);
/** mesh callback for task_probe on lookup of host names */
diff --git a/usr.sbin/unbound/services/cache/dns.c b/usr.sbin/unbound/services/cache/dns.c
index f9dc5922f68..35adc35b57e 100644
--- a/usr.sbin/unbound/services/cache/dns.c
+++ b/usr.sbin/unbound/services/cache/dns.c
@@ -108,6 +108,48 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
}
}
+/** delete message from message cache */
+static void
+msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
+ uint16_t qtype, uint16_t qclass, uint16_t flags)
+{
+ struct query_info k;
+ hashvalue_type h;
+
+ k.qname = qname;
+ k.qname_len = qnamelen;
+ k.qtype = qtype;
+ k.qclass = qclass;
+ k.local_alias = NULL;
+ h = query_info_hash(&k, flags);
+ slabhash_remove(env->msg_cache, h, &k);
+}
+
+/** remove servfail msg cache entry */
+static void
+msg_del_servfail(struct module_env* env, struct query_info* qinfo,
+ uint32_t flags)
+{
+ struct msgreply_entry* e;
+ /* see if the entry is servfail, and then remove it, so that
+ * lookups move from the cacheresponse stage to the recursionresponse
+ * stage */
+ e = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
+ qinfo->qtype, qinfo->qclass, flags, 0, 0);
+ if(!e) return;
+ /* we don't check for the ttl here, also expired servfail entries
+ * are removed. If the user uses serve-expired, they would still be
+ * used to answer from cache */
+ if(FLAGS_GET_RCODE(((struct reply_info*)e->entry.data)->flags)
+ != LDNS_RCODE_SERVFAIL) {
+ lock_rw_unlock(&e->entry.lock);
+ return;
+ }
+ lock_rw_unlock(&e->entry.lock);
+ msg_cache_remove(env, qinfo->qname, qinfo->qname_len, qinfo->qtype,
+ qinfo->qclass, flags);
+}
+
void
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
@@ -132,6 +174,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
* which could be useful for delegation information */
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
free(rep);
+ /* if the message is SERVFAIL in cache, remove that SERVFAIL,
+ * so that the TTL 0 response can be returned for future
+ * responses (i.e. don't get answered by the servfail from
+ * cache, but instead go to recursion to get this TTL0
+ * response). */
+ msg_del_servfail(env, qinfo, flags);
return;
}
@@ -395,8 +443,7 @@ dns_msg_authadd(struct dns_msg* msg, struct regional* region,
return 1;
}
-/** add rrset to answer section */
-static int
+int
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
struct ub_packed_rrset_key* rrset, time_t now)
{
@@ -568,7 +615,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
/** synthesize DNAME+CNAME response from cached DNAME item */
static struct dns_msg*
synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
- time_t now, struct query_info* q)
+ time_t now, struct query_info* q, enum sec_status* sec_status)
{
struct dns_msg* msg;
struct ub_packed_rrset_key* ck;
@@ -580,8 +627,9 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
return NULL;
/* only allow validated (with DNSSEC) DNAMEs used from cache
* for insecure DNAMEs, query again. */
- if(d->security != sec_status_secure)
- return NULL;
+ *sec_status = d->security;
+ /* return sec status, so the status of the CNAME can be checked
+ * by the calling routine. */
msg = gen_dns_msg(region, q, 2); /* DNAME + CNAME RRset */
if(!msg)
return NULL;
@@ -711,7 +759,8 @@ fill_any(struct module_env* env,
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)
+ uint16_t flags, struct regional* region, struct regional* scratch,
+ int no_partial)
{
struct lruhash_entry* e;
struct query_info k;
@@ -743,27 +792,54 @@ dns_cache_lookup(struct module_env* env,
/* see if a DNAME exists. Checked for first, to enforce that DNAMEs
* are more important, the CNAME is resynthesized and thus
* consistent with the DNAME */
- if( (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
+ if(!no_partial &&
+ (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
LDNS_RR_TYPE_DNAME, 1))) {
/* synthesize a DNAME+CNAME message based on this */
- struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k);
+ enum sec_status sec_status = sec_status_unchecked;
+ struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k,
+ &sec_status);
if(msg) {
+ struct ub_packed_rrset_key* cname_rrset;
+ lock_rw_unlock(&rrset->entry.lock);
+ /* now, after unlocking the DNAME rrset lock,
+ * check the sec_status, and see if we need to look
+ * up the CNAME record associated before it can
+ * be used */
+ /* normally, only secure DNAMEs allowed from cache*/
+ if(sec_status == sec_status_secure)
+ return msg;
+ /* but if we have a CNAME cached with this name, then we
+ * have previously already allowed this name to pass.
+ * the next cache lookup is going to fetch that CNAME itself,
+ * but it is better to have the (unsigned)DNAME + CNAME in
+ * that case */
+ cname_rrset = rrset_cache_lookup(
+ env->rrset_cache, qname, qnamelen,
+ LDNS_RR_TYPE_CNAME, qclass, 0, now, 0);
+ if(cname_rrset) {
+ /* CNAME already synthesized by
+ * synth_dname_msg routine, so we can
+ * straight up return the msg */
+ lock_rw_unlock(&cname_rrset->entry.lock);
+ return msg;
+ }
+ } else {
lock_rw_unlock(&rrset->entry.lock);
- return msg;
}
- lock_rw_unlock(&rrset->entry.lock);
}
/* see if we have CNAME for this domain,
* but not for DS records (which are part of the parent) */
- if( qtype != LDNS_RR_TYPE_DS &&
+ if(!no_partial && qtype != LDNS_RR_TYPE_DS &&
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) {
uint8_t* wc = NULL;
+ size_t wl;
/* if the rrset is not a wildcard expansion, with wcname */
/* because, if we return that CNAME rrset on its own, it is
* missing the NSEC or NSEC3 proof */
- if(!(val_rrset_wildcard(rrset, &wc) && wc != NULL)) {
+ if(!(val_rrset_wildcard(rrset, &wc, &wl) && wc != NULL)) {
struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
if(msg) {
lock_rw_unlock(&rrset->entry.lock);
@@ -842,7 +918,7 @@ dns_cache_lookup(struct module_env* env,
return NULL;
}
-int
+int
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region, uint32_t flags)
@@ -852,7 +928,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep)
return 0;
- /* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
+ /* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
* the env->now is added to message and RRsets in this routine. */
/* the leeway is used to invalidate other rrsets earlier */
diff --git a/usr.sbin/unbound/services/cache/dns.h b/usr.sbin/unbound/services/cache/dns.h
index 9e10f437f1b..78f81e79952 100644
--- a/usr.sbin/unbound/services/cache/dns.h
+++ b/usr.sbin/unbound/services/cache/dns.h
@@ -159,13 +159,16 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* @param region: where to allocate result.
* @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).
* @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);
+ uint16_t flags, struct regional* region, struct regional* scratch,
+ int no_partial);
/**
* find and add A and AAAA records for missing nameservers in delegpt
@@ -205,6 +208,18 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region,
struct ub_packed_rrset_key* rrset, time_t now);
/**
+ * Add rrset to authority section in unpacked dns_msg message. Must have enough
+ * space left, does not grow the array.
+ * @param msg: msg to put it in.
+ * @param region: region to alloc in
+ * @param rrset: to add in authority section
+ * @param now: now.
+ * @return true if worked, false on fail
+ */
+int dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
+ struct ub_packed_rrset_key* rrset, time_t now);
+
+/**
* Adjust the prefetch_ttl for a cached message. This adds a value to the
* prefetch ttl - postponing the time when it will be prefetched for future
* incoming queries.
diff --git a/usr.sbin/unbound/services/cache/rrset.c b/usr.sbin/unbound/services/cache/rrset.c
index 7e5732b760f..0b41fcd7dc3 100644
--- a/usr.sbin/unbound/services/cache/rrset.c
+++ b/usr.sbin/unbound/services/cache/rrset.c
@@ -47,6 +47,7 @@
#include "util/data/msgreply.h"
#include "util/regional.h"
#include "util/alloc.h"
+#include "util/net_help.h"
void
rrset_markdel(void* key)
@@ -237,6 +238,37 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
return 0;
}
+void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
+ struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
+ struct alloc_cache* alloc, time_t timenow)
+{
+ struct rrset_ref ref;
+ uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
+ rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
+ if(!rrset) {
+ log_err("malloc failure in rrset_cache_update_wildcard");
+ return;
+ }
+ /* ce has at least one label less then qname, we can therefore safely
+ * add the wildcard label. */
+ wc_dname[0] = 1;
+ wc_dname[1] = (uint8_t)'*';
+ memmove(wc_dname+2, ce, ce_len);
+
+ rrset->rk.dname_len = ce_len + 2;
+ rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len);
+ if(!rrset->rk.dname) {
+ log_err("memdup failure in rrset_cache_update_wildcard");
+ return;
+ }
+
+ rrset->entry.hash = rrset_key_hash(&rrset->rk);
+ ref.key = rrset;
+ ref.id = rrset->id;
+ /* ignore ret: if it was in the cache, ref updated */
+ (void)rrset_cache_update(rrset_cache, &ref, alloc, timenow);
+}
+
struct ub_packed_rrset_key*
rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, uint32_t flags, time_t timenow,
diff --git a/usr.sbin/unbound/services/cache/rrset.h b/usr.sbin/unbound/services/cache/rrset.h
index d5439ef085b..35a0d732b04 100644
--- a/usr.sbin/unbound/services/cache/rrset.h
+++ b/usr.sbin/unbound/services/cache/rrset.h
@@ -134,6 +134,24 @@ int rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
struct alloc_cache* alloc, time_t timenow);
/**
+ * Update or add an rrset in the rrset cache using a wildcard dname.
+ * Generates wildcard dname by prepending the wildcard label to the closest
+ * encloser. Will lookup if the rrset is in the cache and perform an update if
+ * necessary.
+ *
+ * @param rrset_cache: the rrset cache.
+ * @param rrset: which rrset to cache as wildcard. This rrset is left
+ * untouched.
+ * @param ce: the closest encloser, will be uses to generate the wildcard dname.
+ * @param ce_len: the closest encloser lenght.
+ * @param alloc: how to allocate (and deallocate) the special rrset key.
+ * @param timenow: current time (to see if ttl in cache is expired).
+ */
+void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
+ struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
+ struct alloc_cache* alloc, time_t timenow);
+
+/**
* Lookup rrset. You obtain read/write lock. You must unlock before lookup
* anything of else.
* @param r: the rrset cache.
diff --git a/usr.sbin/unbound/services/localzone.c b/usr.sbin/unbound/services/localzone.c
index 90106d5c809..0f608170c85 100644
--- a/usr.sbin/unbound/services/localzone.c
+++ b/usr.sbin/unbound/services/localzone.c
@@ -1132,57 +1132,11 @@ void local_zones_print(struct local_zones* zones)
lock_rw_rdlock(&zones->lock);
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
+ char buf[64];
lock_rw_rdlock(&z->lock);
- switch(z->type) {
- case local_zone_deny:
- log_nametypeclass(0, "deny zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_refuse:
- log_nametypeclass(0, "refuse zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_redirect:
- log_nametypeclass(0, "redirect zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_transparent:
- log_nametypeclass(0, "transparent zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_typetransparent:
- log_nametypeclass(0, "typetransparent zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_static:
- log_nametypeclass(0, "static zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_inform:
- log_nametypeclass(0, "inform zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_inform_deny:
- log_nametypeclass(0, "inform_deny zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_always_transparent:
- log_nametypeclass(0, "always_transparent zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_always_refuse:
- log_nametypeclass(0, "always_refuse zone",
- z->name, 0, z->dclass);
- break;
- case local_zone_always_nxdomain:
- log_nametypeclass(0, "always_nxdomain zone",
- z->name, 0, z->dclass);
- break;
- default:
- log_nametypeclass(0, "badtyped zone",
- z->name, 0, z->dclass);
- break;
- }
+ snprintf(buf, sizeof(buf), "%s zone",
+ local_zone_type2str(z->type));
+ log_nametypeclass(0, buf, z->name, 0, z->dclass);
local_zone_out(z);
lock_rw_unlock(&z->lock);
}
@@ -1589,12 +1543,17 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
(z = local_zones_lookup(view->local_zones,
qinfo->qname, qinfo->qname_len, labs,
qinfo->qclass, qinfo->qtype))) {
- verbose(VERB_ALGO,
- "using localzone from view: %s",
- view->name);
+ if(z->type != local_zone_noview)
+ verbose(VERB_ALGO,
+ "using localzone from view: %s",
+ view->name);
lock_rw_rdlock(&z->lock);
lzt = z->type;
}
+ if(lzt == local_zone_noview) {
+ lock_rw_unlock(&z->lock);
+ z = NULL;
+ }
if(view->local_zones && !z && !view->isfirst){
lock_rw_unlock(&view->lock);
return 0;
@@ -1652,6 +1611,7 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_always_transparent: return "always_transparent";
case local_zone_always_refuse: return "always_refuse";
case local_zone_always_nxdomain: return "always_nxdomain";
+ case local_zone_noview: return "noview";
}
return "badtyped";
}
@@ -1680,6 +1640,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_always_refuse;
else if(strcmp(type, "always_nxdomain") == 0)
*t = local_zone_always_nxdomain;
+ else if(strcmp(type, "noview") == 0)
+ *t = local_zone_noview;
else if(strcmp(type, "nodefault") == 0)
*t = local_zone_nodefault;
else return 0;
diff --git a/usr.sbin/unbound/services/localzone.h b/usr.sbin/unbound/services/localzone.h
index 0a8759268bb..dd7aa584c46 100644
--- a/usr.sbin/unbound/services/localzone.h
+++ b/usr.sbin/unbound/services/localzone.h
@@ -88,7 +88,9 @@ enum localzone_type {
/** answer with error, even when there is local data */
local_zone_always_refuse,
/** answer with nxdomain, even when there is local data */
- local_zone_always_nxdomain
+ local_zone_always_nxdomain,
+ /** answer not from the view, but global or no-answer */
+ local_zone_noview
};
/**
diff --git a/usr.sbin/unbound/services/outside_network.c b/usr.sbin/unbound/services/outside_network.c
index 1e4059888b9..92212be02f0 100644
--- a/usr.sbin/unbound/services/outside_network.c
+++ b/usr.sbin/unbound/services/outside_network.c
@@ -262,6 +262,7 @@ outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen)
log_err_addr("outgoing tcp: connect",
strerror(errno), addr, addrlen);
close(s);
+ return 0;
#ifdef EINPROGRESS
}
#endif
@@ -269,9 +270,9 @@ outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen)
if(WSAGetLastError() != WSAEINPROGRESS &&
WSAGetLastError() != WSAEWOULDBLOCK) {
closesocket(s);
+ return 0;
}
#endif
- return 0;
}
return 1;
}
@@ -2140,6 +2141,215 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
}
}
+/** create fd to send to this destination */
+static int
+fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
+ socklen_t to_addrlen)
+{
+ struct sockaddr_storage* addr;
+ socklen_t addrlen;
+ int i;
+ int try;
+
+ /* select interface */
+ if(addr_is_ip6(to_addr, to_addrlen)) {
+ if(outnet->num_ip6 == 0) {
+ char to[64];
+ addr_to_str(to_addr, to_addrlen, to, sizeof(to));
+ verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
+ return -1;
+ }
+ i = ub_random_max(outnet->rnd, outnet->num_ip6);
+ addr = &outnet->ip6_ifs[i].addr;
+ addrlen = outnet->ip6_ifs[i].addrlen;
+ } else {
+ if(outnet->num_ip4 == 0) {
+ char to[64];
+ addr_to_str(to_addr, to_addrlen, to, sizeof(to));
+ verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
+ return -1;
+ }
+ i = ub_random_max(outnet->rnd, outnet->num_ip4);
+ addr = &outnet->ip4_ifs[i].addr;
+ addrlen = outnet->ip4_ifs[i].addrlen;
+ }
+
+ /* create fd */
+ for(try = 0; try<1000; try++) {
+ int freebind = 0;
+ int noproto = 0;
+ int inuse = 0;
+ int port = ub_random(outnet->rnd)&0xffff;
+ int fd = -1;
+ if(addr_is_ip6(to_addr, to_addrlen)) {
+ struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
+ sa.sin6_port = (in_port_t)htons((uint16_t)port);
+ fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
+ (struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
+ 0, 0, 0, NULL, 0, freebind, 0);
+ } else {
+ struct sockaddr_in* sa = (struct sockaddr_in*)addr;
+ sa->sin_port = (in_port_t)htons((uint16_t)port);
+ fd = create_udp_sock(AF_INET, SOCK_DGRAM,
+ (struct sockaddr*)addr, addrlen, 1, &inuse, &noproto,
+ 0, 0, 0, NULL, 0, freebind, 0);
+ }
+ if(fd != -1) {
+ return fd;
+ }
+ if(!inuse) {
+ return -1;
+ }
+ }
+ /* too many tries */
+ log_err("cannot send probe, ports are in use");
+ return -1;
+}
+
+struct comm_point*
+outnet_comm_point_for_udp(struct outside_network* outnet,
+ comm_point_callback_type* cb, void* cb_arg,
+ struct sockaddr_storage* to_addr, socklen_t to_addrlen)
+{
+ struct comm_point* cp;
+ int fd = fd_for_dest(outnet, to_addr, to_addrlen);
+ if(fd == -1) {
+ return NULL;
+ }
+ cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
+ cb, cb_arg);
+ if(!cp) {
+ log_err("malloc failure");
+ close(fd);
+ return NULL;
+ }
+ return cp;
+}
+
+struct comm_point*
+outnet_comm_point_for_tcp(struct outside_network* outnet,
+ comm_point_callback_type* cb, void* cb_arg,
+ struct sockaddr_storage* to_addr, socklen_t to_addrlen,
+ sldns_buffer* query, int timeout)
+{
+ struct comm_point* cp;
+ int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
+ if(fd == -1) {
+ return 0;
+ }
+ fd_set_nonblock(fd);
+ if(!outnet_tcp_connect(fd, to_addr, to_addrlen)) {
+ /* outnet_tcp_connect has closed fd on error for us */
+ return 0;
+ }
+ cp = comm_point_create_tcp_out(outnet->base, 65552, cb, cb_arg);
+ if(!cp) {
+ log_err("malloc failure");
+ close(fd);
+ return 0;
+ }
+ cp->repinfo.addrlen = to_addrlen;
+ memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
+ /* set timeout on TCP connection */
+ comm_point_start_listening(cp, fd, timeout);
+ /* copy scratch buffer to cp->buffer */
+ sldns_buffer_copy(cp->buffer, query);
+ return cp;
+}
+
+/** setup http request headers in buffer for sending query to destination */
+static int
+setup_http_request(sldns_buffer* buf, char* host, char* path)
+{
+ 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);
+ /* 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") */
+ sldns_buffer_printf(buf, "\r\n");
+ if(sldns_buffer_position(buf)+10 > sldns_buffer_capacity(buf))
+ return 0; /* somehow buffer too short, but it is about 60K
+ and the request is only a couple bytes long. */
+ sldns_buffer_flip(buf);
+ return 1;
+}
+
+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)
+{
+ /* cp calls cb with err=NETEVENT_DONE when transfer is done */
+ struct comm_point* cp;
+ int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
+ if(fd == -1) {
+ return 0;
+ }
+ fd_set_nonblock(fd);
+ if(!outnet_tcp_connect(fd, to_addr, to_addrlen)) {
+ /* outnet_tcp_connect has closed fd on error for us */
+ return 0;
+ }
+ cp = comm_point_create_http_out(outnet->base, 65552, cb, cb_arg,
+ outnet->udp_buff);
+ if(!cp) {
+ log_err("malloc failure");
+ close(fd);
+ return 0;
+ }
+ cp->repinfo.addrlen = to_addrlen;
+ memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
+
+ /* setup for SSL (if needed) */
+ if(ssl) {
+ cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
+ if(!cp->ssl) {
+ log_err("cannot setup https");
+ comm_point_delete(cp);
+ return NULL;
+ }
+#ifdef USE_WINSOCK
+ comm_point_tcp_win_bio_cb(cp, cp->ssl);
+#endif
+ cp->ssl_shake_state = comm_ssl_shake_write;
+ /* https verification */
+#ifdef HAVE_SSL_SET1_HOST
+ if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
+ /* because we set SSL_VERIFY_PEER, in netevent in
+ * ssl_handshake, it'll check if the certificate
+ * verification has succeeded */
+ /* SSL_VERIFY_PEER is set on the sslctx */
+ /* and the certificates to verify with are loaded into
+ * it with SSL_load_verify_locations or
+ * SSL_CTX_set_default_verify_paths */
+ /* setting the hostname makes openssl verify the
+ * host name in the x509 certificate in the
+ * SSL connection*/
+ if(!SSL_set1_host(cp->ssl, host)) {
+ log_err("SSL_set1_host failed");
+ comm_point_delete(cp);
+ return NULL;
+ }
+ }
+#endif /* HAVE_SSL_SET1_HOST */
+ }
+
+ /* set timeout on TCP connection */
+ comm_point_start_listening(cp, fd, timeout);
+
+ /* setup http request in cp->buffer */
+ if(!setup_http_request(cp->buffer, host, path)) {
+ log_err("error setting up http request");
+ comm_point_delete(cp);
+ return NULL;
+ }
+ return cp;
+}
+
/** get memory used by waiting tcp entry (in use or not) */
static size_t
waiting_tcp_get_mem(struct waiting_tcp* w)
diff --git a/usr.sbin/unbound/services/outside_network.h b/usr.sbin/unbound/services/outside_network.h
index 04e89a0b7fe..09b2e6cedff 100644
--- a/usr.sbin/unbound/services/outside_network.h
+++ b/usr.sbin/unbound/services/outside_network.h
@@ -537,6 +537,63 @@ size_t serviced_get_mem(struct serviced_query* sq);
* 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);
+/**
+ * Create udp commpoint suitable for sending packets to the destination.
+ * @param outnet: outside_network with the comm_base it is attached to,
+ * with the outgoing interfaces chosen from, and rnd gen for random.
+ * @param cb: callback function for the commpoint.
+ * @param cb_arg: callback argument for cb.
+ * @param to_addr: intended destination.
+ * @param to_addrlen: length of to_addr.
+ * @return commpoint that you can comm_point_send_udp_msg with, or NULL.
+ */
+struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
+ comm_point_callback_type* cb, void* cb_arg,
+ struct sockaddr_storage* to_addr, socklen_t to_addrlen);
+
+/**
+ * Create tcp commpoint suitable for communication to the destination.
+ * It also performs connect() to the to_addr.
+ * @param outnet: outside_network with the comm_base it is attached to,
+ * and the tcp_mss.
+ * @param cb: callback function for the commpoint.
+ * @param cb_arg: callback argument for cb.
+ * @param to_addr: intended destination.
+ * @param to_addrlen: length of to_addr.
+ * @param query: initial packet to send writing, in buffer. It is copied
+ * to the commpoint buffer that is created.
+ * @param timeout: timeout for the TCP connection.
+ * timeout in milliseconds, or -1 for no (change to the) timeout.
+ * So seconds*1000.
+ * @return tcp_out commpoint, or NULL.
+ */
+struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
+ comm_point_callback_type* cb, void* cb_arg,
+ struct sockaddr_storage* to_addr, socklen_t to_addrlen,
+ struct sldns_buffer* query, int timeout);
+
+/**
+ * Create http commpoint suitable for communication to the destination.
+ * Creates the http request buffer. It also performs connect() to the to_addr.
+ * @param outnet: outside_network with the comm_base it is attached to,
+ * and the tcp_mss.
+ * @param cb: callback function for the commpoint.
+ * @param cb_arg: callback argument for cb.
+ * @param to_addr: intended destination.
+ * @param to_addrlen: length of to_addr.
+ * @param timeout: timeout for the TCP connection.
+ * timeout in milliseconds, or -1 for no (change to the) timeout.
+ * So seconds*1000.
+ * @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.
+ * @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);
+
/** connect tcp connection to addr, 0 on failure */
int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
diff --git a/usr.sbin/unbound/sldns/str2wire.c b/usr.sbin/unbound/sldns/str2wire.c
index 6759944e4a7..fdb35575402 100644
--- a/usr.sbin/unbound/sldns/str2wire.c
+++ b/usr.sbin/unbound/sldns/str2wire.c
@@ -836,7 +836,7 @@ const char* sldns_get_errorstr_parse(int e)
}
/* Strip whitespace from the start and the end of <line>. */
-static char *
+char *
sldns_strip_ws(char *line)
{
char *s = line, *e;
@@ -906,7 +906,7 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
*dname_len = 0;
return LDNS_WIREPARSE_ERR_INCLUDE;
} else {
- return sldns_str2wire_rr_buf(line, rr, len, dname_len,
+ int r = sldns_str2wire_rr_buf(line, rr, len, dname_len,
parse_state?parse_state->default_ttl:0,
(parse_state&&parse_state->origin_len)?
parse_state->origin:NULL,
@@ -914,6 +914,13 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
(parse_state&&parse_state->prev_rr_len)?
parse_state->prev_rr:NULL,
parse_state?parse_state->prev_rr_len:0);
+ if(r == LDNS_WIREPARSE_ERR_OK && (*dname_len) != 0 &&
+ parse_state &&
+ (*dname_len) <= sizeof(parse_state->prev_rr)) {
+ memmove(parse_state->prev_rr, rr, *dname_len);
+ parse_state->prev_rr_len = (*dname_len);
+ }
+ return r;
}
return LDNS_WIREPARSE_ERR_OK;
}
diff --git a/usr.sbin/unbound/sldns/str2wire.h b/usr.sbin/unbound/sldns/str2wire.h
index a0d6f55b03e..70070e4f575 100644
--- a/usr.sbin/unbound/sldns/str2wire.h
+++ b/usr.sbin/unbound/sldns/str2wire.h
@@ -554,6 +554,12 @@ int sldns_str2wire_hip_buf(const char* str, uint8_t* rd, size_t* len);
*/
int sldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len);
+/**
+ * Strip whitespace from the start and the end of line.
+ * @param line: modified with 0 to shorten it.
+ * @return new start with spaces skipped.
+ */
+char * sldns_strip_ws(char *line);
#ifdef __cplusplus
}
#endif
diff --git a/usr.sbin/unbound/sldns/wire2str.c b/usr.sbin/unbound/sldns/wire2str.c
index 861b7648ade..832239f9b76 100644
--- a/usr.sbin/unbound/sldns/wire2str.c
+++ b/usr.sbin/unbound/sldns/wire2str.c
@@ -255,6 +255,12 @@ int sldns_wire2str_rr_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
return sldns_wire2str_rr_scan(&d, &dlen, &s, &slen, NULL, 0);
}
+int sldns_wire2str_rrquestion_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
+{
+ /* use arguments as temporary variables */
+ return sldns_wire2str_rrquestion_scan(&d, &dlen, &s, &slen, NULL, 0);
+}
+
int sldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str,
size_t str_len, uint16_t rrtype)
{
diff --git a/usr.sbin/unbound/sldns/wire2str.h b/usr.sbin/unbound/sldns/wire2str.h
index aac13c548ac..a64f5807269 100644
--- a/usr.sbin/unbound/sldns/wire2str.h
+++ b/usr.sbin/unbound/sldns/wire2str.h
@@ -359,6 +359,22 @@ int sldns_wire2str_rr_buf(uint8_t* rr, size_t rr_len, char* str,
size_t str_len);
/**
+ * Convert question RR to string presentation format, on one line. User buffer.
+ * @param rr: wireformat RR data
+ * @param rr_len: length of the rr wire data.
+ * @param str: the string buffer to write to.
+ * If you pass NULL as the str, the return value of the function is
+ * the str_len you need for the entire packet. It does not include
+ * the 0 byte at the end.
+ * @param str_len: the size of the string buffer. If more is needed, it'll
+ * silently truncate the output to fit in the buffer.
+ * @return the number of characters for this element, excluding zerobyte.
+ * Is larger or equal than str_len if output was truncated.
+ */
+int sldns_wire2str_rrquestion_buf(uint8_t* rr, size_t rr_len, char* str,
+ size_t str_len);
+
+/**
* 3597 printout of an RR in unknown rr format.
* There are more format and comment options available for printout
* with the function: TBD(TODO)
diff --git a/usr.sbin/unbound/smallapp/unbound-checkconf.c b/usr.sbin/unbound/smallapp/unbound-checkconf.c
index 2b84aad12ab..e205c3e9c49 100644
--- a/usr.sbin/unbound/smallapp/unbound-checkconf.c
+++ b/usr.sbin/unbound/smallapp/unbound-checkconf.c
@@ -109,6 +109,16 @@ print_option(struct config_file* cfg, const char* opt, int final)
free(p);
return;
}
+ if(strcmp(opt, "auto-trust-anchor-file") == 0 && final) {
+ struct config_strlist* s = cfg->auto_trust_anchor_file_list;
+ for(; s; s=s->next) {
+ char *p = fname_after_chroot(s->str, cfg, 1);
+ if(!p) fatal_exit("out of memory");
+ printf("%s\n", p);
+ free(p);
+ }
+ return;
+ }
if(!config_get_option(cfg, opt, config_print_func, stdout))
fatal_exit("cannot print option '%s'", opt);
}
@@ -579,7 +589,7 @@ static void
check_auth(struct config_file* cfg)
{
struct auth_zones* az = auth_zones_create();
- if(!az || !auth_zones_apply_cfg(az, cfg, 0, NULL)) {
+ if(!az || !auth_zones_apply_cfg(az, cfg, 0)) {
fatal_exit("Could not setup authority zones");
}
auth_zones_delete(az);
diff --git a/usr.sbin/unbound/util/config_file.c b/usr.sbin/unbound/util/config_file.c
index 073bc02ce48..02c9d1534e2 100644
--- a/usr.sbin/unbound/util/config_file.c
+++ b/usr.sbin/unbound/util/config_file.c
@@ -108,6 +108,7 @@ config_create(void)
cfg->ssl_service_pem = NULL;
cfg->ssl_port = 853;
cfg->ssl_upstream = 0;
+ cfg->tls_cert_bundle = NULL;
cfg->use_syslog = 1;
cfg->log_identity = NULL; /* changed later with argv[0] */
cfg->log_time_ascii = 0;
@@ -220,6 +221,7 @@ config_create(void)
cfg->val_log_level = 0;
cfg->val_log_squelch = 0;
cfg->val_permissive_mode = 0;
+ cfg->aggressive_nsec = 0;
cfg->ignore_cd = 0;
cfg->serve_expired = 0;
cfg->add_holddown = 30*24*3600;
@@ -443,6 +445,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STR("ssl-service-key:", ssl_service_key)
else S_STR("ssl-service-pem:", ssl_service_pem)
else S_NUMBER_NONZERO("ssl-port:", ssl_port)
+ else S_STR("tls-cert-bundle:", tls_cert_bundle)
else S_YNO("interface-automatic:", if_automatic)
else S_YNO("use-systemd:", use_systemd)
else S_YNO("do-daemonize:", do_daemonize)
@@ -519,6 +522,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("log-queries:", log_queries)
else S_YNO("log-replies:", log_replies)
else S_YNO("val-permissive-mode:", val_permissive_mode)
+ else S_YNO("aggressive-nsec:", aggressive_nsec)
else S_YNO("ignore-cd-flag:", ignore_cd)
else S_YNO("serve-expired:", serve_expired)
else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations)
@@ -851,6 +855,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "ssl-service-key", ssl_service_key)
else O_STR(opt, "ssl-service-pem", ssl_service_pem)
else O_DEC(opt, "ssl-port", ssl_port)
+ else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
else O_YNO(opt, "use-systemd", use_systemd)
else O_YNO(opt, "do-daemonize", do_daemonize)
else O_STR(opt, "chroot", chrootdir)
@@ -883,6 +888,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "val-clean-additional", val_clean_additional)
else O_DEC(opt, "val-log-level", val_log_level)
else O_YNO(opt, "val-permissive-mode", val_permissive_mode)
+ else O_YNO(opt, "aggressive-nsec:", aggressive_nsec)
else O_YNO(opt, "ignore-cd-flag", ignore_cd)
else O_YNO(opt, "serve-expired", serve_expired)
else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations)
@@ -1267,6 +1273,7 @@ config_delete(struct config_file* cfg)
free(cfg->target_fetch_policy);
free(cfg->ssl_service_key);
free(cfg->ssl_service_pem);
+ free(cfg->tls_cert_bundle);
free(cfg->log_identity);
config_del_strarray(cfg->ifs, cfg->num_ifs);
config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
diff --git a/usr.sbin/unbound/util/config_file.h b/usr.sbin/unbound/util/config_file.h
index 2fc6fdfb4cd..2e1c53ee073 100644
--- a/usr.sbin/unbound/util/config_file.h
+++ b/usr.sbin/unbound/util/config_file.h
@@ -100,6 +100,8 @@ struct config_file {
int ssl_port;
/** if outgoing tcp connections use SSL */
int ssl_upstream;
+ /** cert bundle for outgoing connections */
+ char* tls_cert_bundle;
/** outgoing port range number of ports (per thread) */
int outgoing_num_ports;
@@ -300,6 +302,8 @@ struct config_file {
int val_log_squelch;
/** should validator allow bogus messages to go through */
int val_permissive_mode;
+ /** use cached NSEC records to synthesise (negative) answers */
+ int aggressive_nsec;
/** ignore the CD flag in incoming queries and refuse them bogus data */
int ignore_cd;
/** serve expired entries and prefetch them */
@@ -551,6 +555,9 @@ struct config_auth {
int for_downstream;
/** provide upstream answers */
int for_upstream;
+ /** fallback to recursion to authorities if zone expired and other
+ * reasons perhaps (like, query bogus) */
+ int fallback_enabled;
};
/**
diff --git a/usr.sbin/unbound/util/configlexer.lex b/usr.sbin/unbound/util/configlexer.lex
index 793c70bcb8a..0e158d1610a 100644
--- a/usr.sbin/unbound/util/configlexer.lex
+++ b/usr.sbin/unbound/util/configlexer.lex
@@ -229,9 +229,15 @@ tcp-upstream{COLON} { YDVAR(1, VAR_TCP_UPSTREAM) }
tcp-mss{COLON} { YDVAR(1, VAR_TCP_MSS) }
outgoing-tcp-mss{COLON} { YDVAR(1, VAR_OUTGOING_TCP_MSS) }
ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
+tls-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
ssl-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) }
+tls-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) }
ssl-service-pem{COLON} { YDVAR(1, VAR_SSL_SERVICE_PEM) }
+tls-service-pem{COLON} { YDVAR(1, VAR_SSL_SERVICE_PEM) }
ssl-port{COLON} { YDVAR(1, VAR_SSL_PORT) }
+tls-port{COLON} { YDVAR(1, VAR_SSL_PORT) }
+ssl-cert-bundle{COLON} { YDVAR(1, VAR_TLS_CERT_BUNDLE) }
+tls-cert-bundle{COLON} { YDVAR(1, VAR_TLS_CERT_BUNDLE) }
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
@@ -289,17 +295,20 @@ stub-host{COLON} { YDVAR(1, VAR_STUB_HOST) }
stub-prime{COLON} { YDVAR(1, VAR_STUB_PRIME) }
stub-first{COLON} { YDVAR(1, VAR_STUB_FIRST) }
stub-ssl-upstream{COLON} { YDVAR(1, VAR_STUB_SSL_UPSTREAM) }
+stub-tls-upstream{COLON} { YDVAR(1, VAR_STUB_SSL_UPSTREAM) }
forward-zone{COLON} { YDVAR(0, VAR_FORWARD_ZONE) }
forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) }
forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) }
forward-first{COLON} { YDVAR(1, VAR_FORWARD_FIRST) }
forward-ssl-upstream{COLON} { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) }
+forward-tls-upstream{COLON} { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) }
auth-zone{COLON} { YDVAR(0, VAR_AUTH_ZONE) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) }
url{COLON} { YDVAR(1, VAR_URL) }
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
for-upstream{COLON} { YDVAR(1, VAR_FOR_UPSTREAM) }
+fallback-enabled{COLON} { YDVAR(1, VAR_FALLBACK_ENABLED) }
view{COLON} { YDVAR(0, VAR_VIEW) }
view-first{COLON} { YDVAR(1, VAR_VIEW_FIRST) }
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
@@ -330,6 +339,7 @@ val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }
val-bogus-ttl{COLON} { YDVAR(1, VAR_BOGUS_TTL) }
val-clean-additional{COLON} { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) }
val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) }
+aggressive-nsec{COLON} { YDVAR(1, VAR_AGGRESSIVE_NSEC) }
ignore-cd-flag{COLON} { YDVAR(1, VAR_IGNORE_CD_FLAG) }
serve-expired{COLON} { YDVAR(1, VAR_SERVE_EXPIRED) }
fake-dsa{COLON} { YDVAR(1, VAR_FAKE_DSA) }
diff --git a/usr.sbin/unbound/util/configparser.y b/usr.sbin/unbound/util/configparser.y
index f0069599479..7e23fca1682 100644
--- a/usr.sbin/unbound/util/configparser.y
+++ b/usr.sbin/unbound/util/configparser.y
@@ -109,7 +109,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES
%token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
-%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM
+%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
@@ -141,7 +141,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
-%token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
+%token VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
%token VAR_DNSCRYPT_PROVIDER_CERT_ROTATED
@@ -154,6 +154,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
+%token VAR_FALLBACK_ENABLED
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -242,7 +243,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ipsecmod_enabled | server_ipsecmod_hook |
server_ipsecmod_ignore_bogus | server_ipsecmod_max_ttl |
server_ipsecmod_whitelist | server_ipsecmod_strict |
- server_udp_upstream_without_downstream
+ server_udp_upstream_without_downstream | server_aggressive_nsec |
+ server_tls_cert_bundle
;
stubstart: VAR_STUB_ZONE
{
@@ -308,6 +310,7 @@ authstart: VAR_AUTH_ZONE
/* defaults for auth zone */
s->for_downstream = 1;
s->for_upstream = 1;
+ s->fallback_enabled = 0;
} else
yyerror("out of memory");
}
@@ -315,7 +318,7 @@ authstart: VAR_AUTH_ZONE
contents_auth: contents_auth content_auth
| ;
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
- auth_for_downstream | auth_for_upstream
+ auth_for_downstream | auth_for_upstream | auth_fallback_enabled
;
server_num_threads: VAR_NUM_THREADS STRING_ARG
{
@@ -672,6 +675,13 @@ server_ssl_port: VAR_SSL_PORT STRING_ARG
free($2);
}
;
+server_tls_cert_bundle: VAR_TLS_CERT_BUNDLE STRING_ARG
+ {
+ OUTYY(("P(server_tls_cert_bundle:%s)\n", $2));
+ free(cfg_parser->cfg->tls_cert_bundle);
+ cfg_parser->cfg->tls_cert_bundle = $2;
+ }
+ ;
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
{
OUTYY(("P(server_use_systemd:%s)\n", $2));
@@ -1388,6 +1398,17 @@ server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG
free($2);
}
;
+server_aggressive_nsec: VAR_AGGRESSIVE_NSEC STRING_ARG
+ {
+ OUTYY(("P(server_aggressive_nsec:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else
+ cfg_parser->cfg->aggressive_nsec =
+ (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG
{
OUTYY(("P(server_ignore_cd_flag:%s)\n", $2));
@@ -1523,12 +1544,13 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
&& strcmp($3, "always_transparent")!=0
&& strcmp($3, "always_refuse")!=0
&& strcmp($3, "always_nxdomain")!=0
+ && strcmp($3, "noview")!=0
&& strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
"always_transparent, always_refuse, "
- "always_nxdomain or nodefault");
+ "always_nxdomain, noview or nodefault");
else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->
local_zones_nodefault, $2))
@@ -2070,6 +2092,16 @@ auth_for_upstream: VAR_FOR_UPSTREAM STRING_ARG
free($2);
}
;
+auth_fallback_enabled: VAR_FALLBACK_ENABLED STRING_ARG
+ {
+ OUTYY(("P(fallback-enabled:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->auths->fallback_enabled =
+ (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
view_name: VAR_NAME STRING_ARG
{
OUTYY(("P(name:%s)\n", $2));
@@ -2090,12 +2122,13 @@ view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
&& strcmp($3, "always_transparent")!=0
&& strcmp($3, "always_refuse")!=0
&& strcmp($3, "always_nxdomain")!=0
+ && strcmp($3, "noview")!=0
&& strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
"always_transparent, always_refuse, "
- "always_nxdomain or nodefault");
+ "always_nxdomain, noview or nodefault");
else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->views->
local_zones_nodefault, $2))
diff --git a/usr.sbin/unbound/util/data/msgreply.c b/usr.sbin/unbound/util/data/msgreply.c
index 15361769250..e25b42cc257 100644
--- a/usr.sbin/unbound/util/data/msgreply.c
+++ b/usr.sbin/unbound/util/data/msgreply.c
@@ -631,9 +631,14 @@ query_info_entrysetup(struct query_info* q, struct reply_info* r,
e->entry.key = e;
e->entry.data = r;
lock_rw_init(&e->entry.lock);
- lock_protect(&e->entry.lock, &e->key, sizeof(e->key));
- lock_protect(&e->entry.lock, &e->entry.hash, sizeof(e->entry.hash) +
- sizeof(e->entry.key) + sizeof(e->entry.data));
+ lock_protect(&e->entry.lock, &e->key.qname, sizeof(e->key.qname));
+ lock_protect(&e->entry.lock, &e->key.qname_len, sizeof(e->key.qname_len));
+ lock_protect(&e->entry.lock, &e->key.qtype, sizeof(e->key.qtype));
+ lock_protect(&e->entry.lock, &e->key.qclass, sizeof(e->key.qclass));
+ lock_protect(&e->entry.lock, &e->key.local_alias, sizeof(e->key.local_alias));
+ lock_protect(&e->entry.lock, &e->entry.hash, sizeof(e->entry.hash));
+ lock_protect(&e->entry.lock, &e->entry.key, sizeof(e->entry.key));
+ lock_protect(&e->entry.lock, &e->entry.data, sizeof(e->entry.data));
lock_protect(&e->entry.lock, e->key.qname, e->key.qname_len);
q->qname = NULL;
return e;
diff --git a/usr.sbin/unbound/util/fptr_wlist.c b/usr.sbin/unbound/util/fptr_wlist.c
index 32a6ba02e28..400a15de2eb 100644
--- a/usr.sbin/unbound/util/fptr_wlist.c
+++ b/usr.sbin/unbound/util/fptr_wlist.c
@@ -100,6 +100,7 @@ fptr_whitelist_comm_point(comm_point_callback_type *fptr)
else if(fptr == &tube_handle_listen) return 1;
else if(fptr == &auth_xfer_probe_udp_callback) return 1;
else if(fptr == &auth_xfer_transfer_tcp_callback) return 1;
+ else if(fptr == &auth_xfer_transfer_http_callback) return 1;
return 0;
}
@@ -161,6 +162,7 @@ fptr_whitelist_event(void (*fptr)(int, short, void *))
else if(fptr == &comm_point_raw_handle_callback) return 1;
else if(fptr == &tube_handle_signal) return 1;
else if(fptr == &comm_base_handle_slow_accept) return 1;
+ else if(fptr == &comm_point_http_handle_callback) return 1;
#ifdef UB_ON_WINDOWS
else if(fptr == &worker_win_stop_cb) return 1;
#endif
diff --git a/usr.sbin/unbound/util/iana_ports.inc b/usr.sbin/unbound/util/iana_ports.inc
index 2307f6a02f8..5afec2f886f 100644
--- a/usr.sbin/unbound/util/iana_ports.inc
+++ b/usr.sbin/unbound/util/iana_ports.inc
@@ -4584,6 +4584,7 @@
7040,
7070,
7071,
+7072,
7080,
7088,
7095,
@@ -4670,6 +4671,7 @@
7629,
7633,
7648,
+7663,
7674,
7675,
7676,
@@ -5433,6 +5435,7 @@
43189,
43190,
43210,
+43438,
43439,
43440,
43441,
diff --git a/usr.sbin/unbound/util/log.c b/usr.sbin/unbound/util/log.c
index c14b45834ad..75a58f9de3d 100644
--- a/usr.sbin/unbound/util/log.c
+++ b/usr.sbin/unbound/util/log.c
@@ -191,6 +191,17 @@ void log_set_time_asc(int use_asc)
log_time_asc = use_asc;
}
+void* log_get_lock(void)
+{
+ if(!key_created)
+ return NULL;
+#ifndef THREADS_DISABLED
+ return (void*)&log_lock;
+#else
+ return NULL;
+#endif
+}
+
void
log_vmsg(int pri, const char* type,
const char *format, va_list args)
diff --git a/usr.sbin/unbound/util/log.h b/usr.sbin/unbound/util/log.h
index 8e85ee620b1..7bc3d9e7615 100644
--- a/usr.sbin/unbound/util/log.h
+++ b/usr.sbin/unbound/util/log.h
@@ -127,6 +127,9 @@ void log_set_time(time_t* t);
*/
void log_set_time_asc(int use_asc);
+/** get log lock */
+void* log_get_lock(void);
+
/**
* Log informational message.
* Pass printf formatted arguments. No trailing newline is needed.
@@ -186,11 +189,17 @@ void log_vmsg(int pri, const char* type, const char* format, va_list args);
* an assertion that is thrown to the logfile.
*/
#ifdef UNBOUND_DEBUG
+#ifdef __clang_analyzer__
+/* clang analyzer needs to know that log_assert is an assertion, otherwise
+ * it could complain about the nullptr the assert is guarding against. */
+#define log_assert(x) assert(x)
+#else
# define log_assert(x) \
do { if(!(x)) \
fatal_exit("%s:%d: %s: assertion %s failed", \
__FILE__, __LINE__, __func__, #x); \
} while(0);
+#endif
#else
# define log_assert(x) /*nothing*/
#endif
diff --git a/usr.sbin/unbound/util/net_help.c b/usr.sbin/unbound/util/net_help.c
index d99a2f974bc..fdc8b0558af 100644
--- a/usr.sbin/unbound/util/net_help.c
+++ b/usr.sbin/unbound/util/net_help.c
@@ -271,6 +271,19 @@ int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
return 1;
}
+/** store port number into sockaddr structure */
+void
+sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port)
+{
+ if(addr_is_ip6(addr, addrlen)) {
+ struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
+ sa->sin6_port = (in_port_t)htons((uint16_t)port);
+ } else {
+ struct sockaddr_in* sa = (struct sockaddr_in*)addr;
+ sa->sin_port = (in_port_t)htons((uint16_t)port);
+ }
+}
+
void
log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
uint16_t type, uint16_t dclass)
diff --git a/usr.sbin/unbound/util/net_help.h b/usr.sbin/unbound/util/net_help.h
index f0236e5335d..2d6fce91db6 100644
--- a/usr.sbin/unbound/util/net_help.h
+++ b/usr.sbin/unbound/util/net_help.h
@@ -202,6 +202,15 @@ int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net);
/**
+ * Store port number into sockaddr structure
+ * @param addr: sockaddr structure, ip4 or ip6.
+ * @param addrlen: length of addr.
+ * @param port: port number to put into the addr.
+ */
+void sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen,
+ int port);
+
+/**
* Print string with neat domain name, type and class.
* @param v: at what verbosity level to print this.
* @param str: string of message.
diff --git a/usr.sbin/unbound/util/netevent.c b/usr.sbin/unbound/util/netevent.c
index 7c0ced83b74..fc6f6a9ea8b 100644
--- a/usr.sbin/unbound/util/netevent.c
+++ b/usr.sbin/unbound/util/netevent.c
@@ -299,6 +299,12 @@ udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
# endif
) && verbosity < VERB_DETAIL)
return 0;
+# ifdef EADDRINUSE
+ /* If SO_REUSEADDR is set, we could try to connect to the same server
+ * from the same source port twice. */
+ if(errno == EADDRINUSE && verbosity < VERB_DETAIL)
+ return 0;
+# endif
/* squelch errors where people deploy AAAA ::ffff:bla for
* authority servers, which we try for intranets. */
if(errno == EINVAL && addr_is_ip4mapped(
@@ -964,6 +970,32 @@ tcp_callback_reader(struct comm_point* c)
}
}
+#ifdef HAVE_SSL
+/** log certificate details */
+static void
+log_cert(unsigned level, const char* str, X509* cert)
+{
+ BIO* bio;
+ char nul = 0;
+ char* pp = NULL;
+ long len;
+ if(verbosity < level) return;
+ bio = BIO_new(BIO_s_mem());
+ if(!bio) return;
+ X509_print_ex(bio, cert, 0, (unsigned long)-1
+ ^(X509_FLAG_NO_SUBJECT
+ |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY
+ |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX
+ |X509_FLAG_NO_ATTRIBUTES));
+ BIO_write(bio, &nul, (int)sizeof(nul));
+ len = BIO_get_mem_data(bio, &pp);
+ if(len != 0 && pp) {
+ verbose(level, "%s: \n%s", str, pp);
+ }
+ BIO_free(bio);
+}
+#endif /* HAVE_SSL */
+
/** continue ssl handshake */
#ifdef HAVE_SSL
static int
@@ -1015,8 +1047,51 @@ ssl_handshake(struct comm_point* c)
}
}
/* this is where peer verification could take place */
- log_addr(VERB_ALGO, "SSL DNS connection", &c->repinfo.addr,
- c->repinfo.addrlen);
+ if((SSL_get_verify_mode(c->ssl)&SSL_VERIFY_PEER)) {
+ /* verification */
+ if(SSL_get_verify_result(c->ssl) == X509_V_OK) {
+ X509* x = SSL_get_peer_certificate(c->ssl);
+ if(!x) {
+ log_addr(VERB_ALGO, "SSL connection failed: "
+ "no certificate",
+ &c->repinfo.addr, c->repinfo.addrlen);
+ return 0;
+ }
+ log_cert(VERB_ALGO, "peer certificate", x);
+#ifdef HAVE_SSL_GET0_PEERNAME
+ if(SSL_get0_peername(c->ssl)) {
+ char buf[255];
+ snprintf(buf, sizeof(buf), "SSL connection "
+ "to %s authenticated",
+ SSL_get0_peername(c->ssl));
+ log_addr(VERB_ALGO, buf, &c->repinfo.addr,
+ c->repinfo.addrlen);
+ } else {
+#endif
+ log_addr(VERB_ALGO, "SSL connection "
+ "authenticated", &c->repinfo.addr,
+ c->repinfo.addrlen);
+#ifdef HAVE_SSL_GET0_PEERNAME
+ }
+#endif
+ X509_free(x);
+ } else {
+ X509* x = SSL_get_peer_certificate(c->ssl);
+ if(x) {
+ log_cert(VERB_ALGO, "peer certificate", x);
+ X509_free(x);
+ }
+ log_addr(VERB_ALGO, "SSL connection failed: "
+ "failed to authenticate",
+ &c->repinfo.addr, c->repinfo.addrlen);
+ return 0;
+ }
+ } else {
+ /* unauthenticated, the verify peer flag was not set
+ * in c->ssl when the ssl object was created from ssl_ctx */
+ log_addr(VERB_ALGO, "SSL connection", &c->repinfo.addr,
+ c->repinfo.addrlen);
+ }
/* setup listen rw correctly */
if(c->tcp_is_reading) {
@@ -1600,6 +1675,644 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
log_err("Ignored event %d for tcphdl.", event);
}
+/** Make http handler free for next assignment */
+static void
+reclaim_http_handler(struct comm_point* c)
+{
+ log_assert(c->type == comm_http);
+ if(c->ssl) {
+#ifdef HAVE_SSL
+ SSL_shutdown(c->ssl);
+ SSL_free(c->ssl);
+ c->ssl = NULL;
+#endif
+ }
+ comm_point_close(c);
+ if(c->tcp_parent) {
+ c->tcp_parent->cur_tcp_count--;
+ c->tcp_free = c->tcp_parent->tcp_free;
+ c->tcp_parent->tcp_free = c;
+ if(!c->tcp_free) {
+ /* re-enable listening on accept socket */
+ comm_point_start_listening(c->tcp_parent, -1, -1);
+ }
+ }
+}
+
+/** read more data for http (with ssl) */
+static int
+ssl_http_read_more(struct comm_point* c)
+{
+#ifdef HAVE_SSL
+ int r;
+ log_assert(sldns_buffer_remaining(c->buffer) > 0);
+ ERR_clear_error();
+ r = SSL_read(c->ssl, (void*)sldns_buffer_current(c->buffer),
+ (int)sldns_buffer_remaining(c->buffer));
+ if(r <= 0) {
+ int want = SSL_get_error(c->ssl, r);
+ if(want == SSL_ERROR_ZERO_RETURN) {
+ return 0; /* shutdown, closed */
+ } else if(want == SSL_ERROR_WANT_READ) {
+ 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, 0, 1);
+ return 1;
+ } else if(want == SSL_ERROR_SYSCALL) {
+ if(errno != 0)
+ log_err("SSL_read syscall: %s",
+ strerror(errno));
+ return 0;
+ }
+ log_crypto_err("could not SSL_read");
+ return 0;
+ }
+ sldns_buffer_skip(c->buffer, (ssize_t)r);
+ return 1;
+#else
+ (void)c;
+ return 0;
+#endif /* HAVE_SSL */
+}
+
+/** read more data for http */
+static int
+http_read_more(int fd, struct comm_point* c)
+{
+ ssize_t r;
+ log_assert(sldns_buffer_remaining(c->buffer) > 0);
+ r = recv(fd, (void*)sldns_buffer_current(c->buffer),
+ sldns_buffer_remaining(c->buffer), 0);
+ if(r == 0) {
+ return 0;
+ } else if(r == -1) {
+#ifndef USE_WINSOCK
+ if(errno == EINTR || errno == EAGAIN)
+ return 1;
+ log_err_addr("read (in http r)", strerror(errno),
+ &c->repinfo.addr, c->repinfo.addrlen);
+#else /* USE_WINSOCK */
+ if(WSAGetLastError() == WSAECONNRESET)
+ return 0;
+ if(WSAGetLastError() == WSAEINPROGRESS)
+ return 1;
+ if(WSAGetLastError() == WSAEWOULDBLOCK) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
+ return 1;
+ }
+ log_err_addr("read (in http r)",
+ wsa_strerror(WSAGetLastError()),
+ &c->repinfo.addr, c->repinfo.addrlen);
+#endif
+ return 0;
+ }
+ sldns_buffer_skip(c->buffer, r);
+ return 1;
+}
+
+/** return true if http header has been read (one line complete) */
+static int
+http_header_done(sldns_buffer* buf)
+{
+ size_t i;
+ for(i=sldns_buffer_position(buf); i<sldns_buffer_limit(buf); i++) {
+ /* there was a \r before the \n, but we ignore that */
+ if((char)sldns_buffer_read_u8_at(buf, i) == '\n')
+ return 1;
+ }
+ return 0;
+}
+
+/** return character string into buffer for header line, moves buffer
+ * past that line and puts zero terminator into linefeed-newline */
+static char*
+http_header_line(sldns_buffer* buf)
+{
+ char* result = (char*)sldns_buffer_current(buf);
+ size_t i;
+ for(i=sldns_buffer_position(buf); i<sldns_buffer_limit(buf); i++) {
+ /* terminate the string on the \r */
+ if((char)sldns_buffer_read_u8_at(buf, i) == '\r')
+ sldns_buffer_write_u8_at(buf, i, 0);
+ /* terminate on the \n and skip past the it and done */
+ if((char)sldns_buffer_read_u8_at(buf, i) == '\n') {
+ sldns_buffer_write_u8_at(buf, i, 0);
+ sldns_buffer_set_position(buf, i+1);
+ return result;
+ }
+ }
+ return NULL;
+}
+
+/** move unread buffer to start and clear rest for putting the rest into it */
+static void
+http_moveover_buffer(sldns_buffer* buf)
+{
+ size_t pos = sldns_buffer_position(buf);
+ size_t len = sldns_buffer_remaining(buf);
+ sldns_buffer_clear(buf);
+ memmove(sldns_buffer_begin(buf), sldns_buffer_at(buf, pos), len);
+ sldns_buffer_set_position(buf, len);
+}
+
+/** a http header is complete, process it */
+static int
+http_process_initial_header(struct comm_point* c)
+{
+ char* line = http_header_line(c->buffer);
+ if(!line) return 1;
+ verbose(VERB_ALGO, "http header: %s", line);
+ if(strncasecmp(line, "HTTP/1.1 ", 9) == 0) {
+ /* check returncode */
+ if(line[9] != '2') {
+ verbose(VERB_ALGO, "http bad status %s", line+9);
+ return 0;
+ }
+ } else if(strncasecmp(line, "Content-Length: ", 16) == 0) {
+ if(!c->http_is_chunked)
+ c->tcp_byte_count = (size_t)atoi(line+16);
+ } else if(strncasecmp(line, "Transfer-Encoding: chunked", 19+7) == 0) {
+ c->tcp_byte_count = 0;
+ c->http_is_chunked = 1;
+ } else if(line[0] == 0) {
+ /* end of initial headers */
+ c->http_in_headers = 0;
+ if(c->http_is_chunked)
+ c->http_in_chunk_headers = 1;
+ /* remove header text from front of buffer
+ * the buffer is going to be used to return the data segment
+ * itself and we don't want the header to get returned
+ * prepended with it */
+ http_moveover_buffer(c->buffer);
+ sldns_buffer_flip(c->buffer);
+ return 1;
+ }
+ /* ignore other headers */
+ return 1;
+}
+
+/** a chunk header is complete, process it, return 0=fail, 1=continue next
+ * header line, 2=done with chunked transfer*/
+static int
+http_process_chunk_header(struct comm_point* c)
+{
+ char* line = http_header_line(c->buffer);
+ if(!line) return 1;
+ if(c->http_in_chunk_headers == 3) {
+ verbose(VERB_ALGO, "http chunk trailer: %s", line);
+ /* are we done ? */
+ if(line[0] == 0 && c->tcp_byte_count == 0) {
+ /* callback of http reader when NETEVENT_DONE,
+ * end of data, with no data in buffer */
+ sldns_buffer_set_position(c->buffer, 0);
+ sldns_buffer_set_limit(c->buffer, 0);
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg, NETEVENT_DONE, NULL);
+ /* return that we are done */
+ return 2;
+ }
+ if(line[0] == 0) {
+ /* continue with header of the next chunk */
+ c->http_in_chunk_headers = 1;
+ /* remove header text from front of buffer */
+ http_moveover_buffer(c->buffer);
+ sldns_buffer_flip(c->buffer);
+ return 1;
+ }
+ /* ignore further trail headers */
+ return 1;
+ }
+ verbose(VERB_ALGO, "http chunk header: %s", line);
+ if(c->http_in_chunk_headers == 1) {
+ /* read chunked start line */
+ char* end = NULL;
+ c->tcp_byte_count = (size_t)strtol(line, &end, 16);
+ if(end == line)
+ return 0;
+ c->http_in_chunk_headers = 0;
+ /* remove header text from front of buffer */
+ http_moveover_buffer(c->buffer);
+ sldns_buffer_flip(c->buffer);
+ if(c->tcp_byte_count == 0) {
+ /* done with chunks, process chunk_trailer lines */
+ c->http_in_chunk_headers = 3;
+ }
+ return 1;
+ }
+ /* ignore other headers */
+ return 1;
+}
+
+/** handle nonchunked data segment */
+static int
+http_nonchunk_segment(struct comm_point* c)
+{
+ /* c->buffer at position..limit has new data we read in.
+ * the buffer itself is full of nonchunked data.
+ * 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;
+ if(c->tcp_byte_count <= got_now) {
+ /* done, this is the last data fragment */
+ c->http_stored = 0;
+ sldns_buffer_set_position(c->buffer, 0);
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (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) {
+ size_t total = sldns_buffer_limit(c->buffer);
+ sldns_buffer_clear(c->buffer);
+ sldns_buffer_set_position(c->buffer, total);
+ c->http_stored = total;
+ /* return and wait to read more */
+ return 1;
+ }
+ /* call callback with this data amount, then
+ * wait for more */
+ c->http_stored = 0;
+ sldns_buffer_set_position(c->buffer, 0);
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, NULL);
+ /* c->callback has to buffer_clear(c->buffer). */
+ /* return and wait to read more */
+ return 1;
+}
+
+/** handle nonchunked data segment, return 0=fail, 1=wait, 2=process more */
+static int
+http_chunked_segment(struct comm_point* c)
+{
+ /* the c->buffer has from position..limit new data we read. */
+ /* the current chunk has length tcp_byte_count.
+ * once we read that read more chunk headers.
+ */
+ size_t remainbufferlen;
+ size_t got_now = sldns_buffer_limit(c->buffer) - c->http_stored;
+ if(c->tcp_byte_count <= got_now) {
+ /* the chunk has completed (with perhaps some extra data
+ * from next chunk header and next chunk) */
+ /* save too much info into temp buffer */
+ size_t fraglen;
+ struct comm_reply repinfo;
+ c->http_stored = 0;
+ sldns_buffer_skip(c->buffer, (ssize_t)c->tcp_byte_count);
+ sldns_buffer_clear(c->http_temp);
+ sldns_buffer_write(c->http_temp,
+ sldns_buffer_current(c->buffer),
+ sldns_buffer_remaining(c->buffer));
+ sldns_buffer_flip(c->http_temp);
+
+ /* callback with this fragment */
+ fraglen = sldns_buffer_position(c->buffer);
+ sldns_buffer_set_position(c->buffer, 0);
+ sldns_buffer_set_limit(c->buffer, fraglen);
+ repinfo = c->repinfo;
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &repinfo);
+ /* c->callback has to buffer_clear(). */
+
+ /* is commpoint deleted? */
+ if(!repinfo.c) {
+ return 1;
+ }
+ /* copy waiting info */
+ sldns_buffer_clear(c->buffer);
+ sldns_buffer_write(c->buffer,
+ sldns_buffer_begin(c->http_temp),
+ sldns_buffer_remaining(c->http_temp));
+ sldns_buffer_flip(c->buffer);
+ /* process end of chunk trailer header lines, until
+ * an empty line */
+ c->http_in_chunk_headers = 3;
+ /* process more data in buffer (if any) */
+ return 2;
+ }
+ 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) {
+ size_t total = sldns_buffer_limit(c->buffer);
+ sldns_buffer_clear(c->buffer);
+ sldns_buffer_set_position(c->buffer, total);
+ c->http_stored = total;
+ /* return and wait to read more */
+ return 1;
+ }
+
+ /* callback of http reader for a new part of the data */
+ c->http_stored = 0;
+ sldns_buffer_set_position(c->buffer, 0);
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, NULL);
+ /* c->callback has to buffer_clear(c->buffer). */
+ /* return and wait to read more */
+ return 1;
+}
+
+/**
+ * Handle http reading callback.
+ * @param fd: file descriptor of socket.
+ * @param c: comm point to read from into buffer.
+ * @return: 0 on error
+ */
+static int
+comm_point_http_handle_read(int fd, struct comm_point* c)
+{
+ log_assert(c->type == comm_http);
+ log_assert(fd != -1);
+
+ /* if we are in ssl handshake, handle SSL handshake */
+#ifdef HAVE_SSL
+ if(c->ssl && c->ssl_shake_state != comm_ssl_shake_none) {
+ if(!ssl_handshake(c))
+ return 0;
+ if(c->ssl_shake_state != comm_ssl_shake_none)
+ return 1;
+ }
+#endif /* HAVE_SSL */
+
+ if(!c->tcp_is_reading)
+ return 1;
+ /* read more data */
+ if(c->ssl) {
+ if(!ssl_http_read_more(c))
+ return 0;
+ } else {
+ if(!http_read_more(fd, c))
+ return 0;
+ }
+
+ sldns_buffer_flip(c->buffer);
+ while(sldns_buffer_remaining(c->buffer) > 0) {
+ /* if we are reading headers, read more headers */
+ if(c->http_in_headers || c->http_in_chunk_headers) {
+ /* if header is done, process the header */
+ if(!http_header_done(c->buffer)) {
+ /* copy remaining data to front of buffer
+ * and set rest for writing into it */
+ http_moveover_buffer(c->buffer);
+ /* return and wait to read more */
+ return 1;
+ }
+ if(!c->http_in_chunk_headers) {
+ /* process initial headers */
+ if(!http_process_initial_header(c))
+ return 0;
+ } else {
+ /* process chunk headers */
+ int r = http_process_chunk_header(c);
+ if(r == 0) return 0;
+ if(r == 2) return 1; /* done */
+ /* r == 1, continue */
+ }
+ /* see if we have more to process */
+ continue;
+ }
+
+ if(!c->http_is_chunked) {
+ /* if we are reading nonchunks, process that*/
+ return http_nonchunk_segment(c);
+ } else {
+ /* if we are reading chunks, read the chunk */
+ int r = http_chunked_segment(c);
+ if(r == 0) return 0;
+ if(r == 1) return 1;
+ continue;
+ }
+ }
+ /* broke out of the loop; could not process header instead need
+ * to read more */
+ /* moveover any remaining data and read more data */
+ http_moveover_buffer(c->buffer);
+ /* return and wait to read more */
+ return 1;
+}
+
+/** check pending connect for http */
+static int
+http_check_connect(int fd, struct comm_point* c)
+{
+ /* check for pending error from nonblocking connect */
+ /* from Stevens, unix network programming, vol1, 3rd ed, p450*/
+ int error = 0;
+ socklen_t len = (socklen_t)sizeof(error);
+ if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error,
+ &len) < 0){
+#ifndef USE_WINSOCK
+ error = errno; /* on solaris errno is error */
+#else /* USE_WINSOCK */
+ error = WSAGetLastError();
+#endif
+ }
+#ifndef USE_WINSOCK
+#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
+ if(error == EINPROGRESS || error == EWOULDBLOCK)
+ return 1; /* try again later */
+ else
+#endif
+ if(error != 0 && verbosity < 2)
+ return 0; /* silence lots of chatter in the logs */
+ else if(error != 0) {
+ log_err_addr("http connect", strerror(error),
+ &c->repinfo.addr, c->repinfo.addrlen);
+#else /* USE_WINSOCK */
+ /* examine error */
+ if(error == WSAEINPROGRESS)
+ return 1;
+ else if(error == WSAEWOULDBLOCK) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
+ return 1;
+ } else if(error != 0 && verbosity < 2)
+ return 0;
+ else if(error != 0) {
+ log_err_addr("http connect", wsa_strerror(error),
+ &c->repinfo.addr, c->repinfo.addrlen);
+#endif /* USE_WINSOCK */
+ return 0;
+ }
+ /* keep on processing this socket */
+ return 2;
+}
+
+/** write more data for http (with ssl) */
+static int
+ssl_http_write_more(struct comm_point* c)
+{
+#ifdef HAVE_SSL
+ int r;
+ log_assert(sldns_buffer_remaining(c->buffer) > 0);
+ ERR_clear_error();
+ r = SSL_write(c->ssl, (void*)sldns_buffer_current(c->buffer),
+ (int)sldns_buffer_remaining(c->buffer));
+ if(r <= 0) {
+ int want = SSL_get_error(c->ssl, r);
+ if(want == SSL_ERROR_ZERO_RETURN) {
+ return 0; /* closed */
+ } else if(want == SSL_ERROR_WANT_READ) {
+ c->ssl_shake_state = comm_ssl_shake_read;
+ comm_point_listen_for_rw(c, 1, 0);
+ return 1; /* wait for read condition */
+ } else if(want == SSL_ERROR_WANT_WRITE) {
+ return 1; /* write more later */
+ } else if(want == SSL_ERROR_SYSCALL) {
+ if(errno != 0)
+ log_err("SSL_write syscall: %s",
+ strerror(errno));
+ return 0;
+ }
+ log_crypto_err("could not SSL_write");
+ return 0;
+ }
+ sldns_buffer_skip(c->buffer, (ssize_t)r);
+ return 1;
+#else
+ (void)c;
+ return 0;
+#endif /* HAVE_SSL */
+}
+
+/** write more data for http */
+static int
+http_write_more(int fd, struct comm_point* c)
+{
+ ssize_t r;
+ log_assert(sldns_buffer_remaining(c->buffer) > 0);
+ r = send(fd, (void*)sldns_buffer_current(c->buffer),
+ sldns_buffer_remaining(c->buffer), 0);
+ if(r == -1) {
+#ifndef USE_WINSOCK
+ if(errno == EINTR || errno == EAGAIN)
+ return 1;
+ log_err_addr("http send r", strerror(errno),
+ &c->repinfo.addr, c->repinfo.addrlen);
+#else
+ if(WSAGetLastError() == WSAEINPROGRESS)
+ return 1;
+ if(WSAGetLastError() == WSAEWOULDBLOCK) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
+ return 1;
+ }
+ log_err_addr("http send r", wsa_strerror(WSAGetLastError()),
+ &c->repinfo.addr, c->repinfo.addrlen);
+#endif
+ return 0;
+ }
+ sldns_buffer_skip(c->buffer, r);
+ return 1;
+}
+
+/**
+ * Handle http writing callback.
+ * @param fd: file descriptor of socket.
+ * @param c: comm point to write buffer out of.
+ * @return: 0 on error
+ */
+static int
+comm_point_http_handle_write(int fd, struct comm_point* c)
+{
+ log_assert(c->type == comm_http);
+ log_assert(fd != -1);
+
+ /* check pending connect errors, if that fails, we wait for more,
+ * or we can continue to write contents */
+ if(c->tcp_check_nb_connect) {
+ int r = http_check_connect(fd, c);
+ if(r == 0) return 0;
+ if(r == 1) return 1;
+ c->tcp_check_nb_connect = 0;
+ }
+ /* if we are in ssl handshake, handle SSL handshake */
+#ifdef HAVE_SSL
+ if(c->ssl && c->ssl_shake_state != comm_ssl_shake_none) {
+ if(!ssl_handshake(c))
+ return 0;
+ if(c->ssl_shake_state != comm_ssl_shake_none)
+ return 1;
+ }
+#endif /* HAVE_SSL */
+ if(c->tcp_is_reading)
+ return 1;
+ /* if we are writing, write more */
+ if(c->ssl) {
+ if(!ssl_http_write_more(c))
+ return 0;
+ } else {
+ if(!http_write_more(fd, c))
+ return 0;
+ }
+
+ /* we write a single buffer contents, that can contain
+ * the http request, and then flip to read the results */
+ /* see if write is done */
+ if(sldns_buffer_remaining(c->buffer) == 0) {
+ sldns_buffer_clear(c->buffer);
+ if(c->tcp_do_toggle_rw)
+ c->tcp_is_reading = 1;
+ c->tcp_byte_count = 0;
+ /* switch from listening(write) to listening(read) */
+ comm_point_stop_listening(c);
+ comm_point_start_listening(c, -1, -1);
+ }
+ return 1;
+}
+
+void
+comm_point_http_handle_callback(int fd, short event, void* arg)
+{
+ struct comm_point* c = (struct comm_point*)arg;
+ log_assert(c->type == comm_http);
+ ub_comm_base_now(c->ev->base);
+
+ if(event&UB_EV_READ) {
+ if(!comm_point_http_handle_read(fd, c)) {
+ reclaim_http_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(
+ c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_CLOSED, NULL);
+ }
+ }
+ return;
+ }
+ if(event&UB_EV_WRITE) {
+ if(!comm_point_http_handle_write(fd, c)) {
+ reclaim_http_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(
+ c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_CLOSED, NULL);
+ }
+ }
+ return;
+ }
+ if(event&UB_EV_TIMEOUT) {
+ verbose(VERB_QUERY, "http took too long, dropped");
+ reclaim_http_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_TIMEOUT, NULL);
+ }
+ return;
+ }
+ log_err("Ignored event %d for httphdl.", event);
+}
+
void comm_point_local_handle_callback(int fd, short event, void* arg)
{
struct comm_point* c = (struct comm_point*)arg;
@@ -1958,6 +2671,75 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
}
struct comm_point*
+comm_point_create_http_out(struct comm_base *base, size_t bufsize,
+ comm_point_callback_type* callback, void* callback_arg,
+ sldns_buffer* temp)
+{
+ struct comm_point* c = (struct comm_point*)calloc(1,
+ sizeof(struct comm_point));
+ short evbits;
+ if(!c)
+ return NULL;
+ c->ev = (struct internal_event*)calloc(1,
+ sizeof(struct internal_event));
+ if(!c->ev) {
+ free(c);
+ return NULL;
+ }
+ c->ev->base = base;
+ c->fd = -1;
+ c->buffer = sldns_buffer_new(bufsize);
+ if(!c->buffer) {
+ free(c->ev);
+ free(c);
+ return NULL;
+ }
+ c->timeout = NULL;
+ c->tcp_is_reading = 0;
+ c->tcp_byte_count = 0;
+ c->tcp_parent = NULL;
+ c->max_tcp_count = 0;
+ c->cur_tcp_count = 0;
+ c->tcp_handlers = NULL;
+ c->tcp_free = NULL;
+ c->type = comm_http;
+ c->tcp_do_close = 0;
+ c->do_not_close = 0;
+ c->tcp_do_toggle_rw = 1;
+ c->tcp_check_nb_connect = 1;
+ c->http_in_headers = 1;
+ c->http_in_chunk_headers = 0;
+ c->http_is_chunked = 0;
+ c->http_temp = temp;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 1;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = c->buffer;
+#endif
+ c->repinfo.c = c;
+ c->callback = callback;
+ c->cb_arg = callback_arg;
+ evbits = UB_EV_PERSIST | UB_EV_WRITE;
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_http_handle_callback, c);
+ if(c->ev->ev == NULL)
+ {
+ log_err("could not baseset tcpout event");
+#ifdef HAVE_SSL
+ SSL_free(c->ssl);
+#endif
+ sldns_buffer_free(c->buffer);
+ free(c->ev);
+ free(c);
+ return NULL;
+ }
+
+ return c;
+}
+
+struct comm_point*
comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
comm_point_callback_type* callback, void* callback_arg)
{
@@ -2110,7 +2892,7 @@ comm_point_delete(struct comm_point* c)
{
if(!c)
return;
- if(c->type == comm_tcp && c->ssl) {
+ if((c->type == comm_tcp || c->type == comm_http) && c->ssl) {
#ifdef HAVE_SSL
SSL_shutdown(c->ssl);
SSL_free(c->ssl);
@@ -2124,7 +2906,7 @@ comm_point_delete(struct comm_point* c)
free(c->tcp_handlers);
}
free(c->timeout);
- if(c->type == comm_tcp || c->type == comm_local) {
+ if(c->type == comm_tcp || c->type == comm_local || c->type == comm_http) {
sldns_buffer_free(c->buffer);
#ifdef USE_DNSCRYPT
if(c->dnscrypt && c->dnscrypt_buffer != c->buffer) {
@@ -2221,7 +3003,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
c->timeout->tv_usec = (msec%1000)*1000;
#endif /* S_SPLINT_S */
}
- if(c->type == comm_tcp) {
+ if(c->type == comm_tcp || c->type == comm_http) {
ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
if(c->tcp_is_reading)
ub_event_add_bits(c->ev->ev, UB_EV_READ);
diff --git a/usr.sbin/unbound/util/netevent.h b/usr.sbin/unbound/util/netevent.h
index 54740266d0a..6819f57f8d9 100644
--- a/usr.sbin/unbound/util/netevent.h
+++ b/usr.sbin/unbound/util/netevent.h
@@ -84,6 +84,8 @@ typedef int comm_point_callback_type(struct comm_point*, void*, int,
#define NETEVENT_TIMEOUT -2
/** to pass fallback from capsforID to callback function; 0x20 failed */
#define NETEVENT_CAPSFAIL -3
+/** to pass done transfer to callback function; http file is complete */
+#define NETEVENT_DONE -4
/** timeout to slow accept calls when not possible, in msec. */
#define NETEVENT_SLOW_ACCEPT_TIME 2000
@@ -201,6 +203,19 @@ struct comm_point {
comm_ssl_shake_hs_write
} ssl_shake_state;
+ /* -------- HTTP ------- */
+ /** Currently reading in http headers */
+ int http_in_headers;
+ /** Currently reading in chunk headers, 0=not, 1=firstline, 2=unused
+ * (more lines), 3=trailer headers after chunk */
+ int http_in_chunk_headers;
+ /** chunked transfer */
+ int http_is_chunked;
+ /** http temp buffer (shared buffer for temporary work) */
+ struct sldns_buffer* http_temp;
+ /** http stored content in buffer */
+ size_t http_stored;
+
/* -------- dnstap ------- */
/** the dnstap environment */
struct dt_env* dtenv;
@@ -213,6 +228,8 @@ struct comm_point {
comm_tcp_accept,
/** TCP handler socket - handle byteperbyte readwrite. */
comm_tcp,
+ /** HTTP handler socket */
+ comm_http,
/** AF_UNIX socket - for internal commands. */
comm_local,
/** raw - not DNS format - for pipe readers and writers */
@@ -450,6 +467,20 @@ struct comm_point* comm_point_create_tcp_out(struct comm_base* base,
size_t bufsize, comm_point_callback_type* callback, void* callback_arg);
/**
+ * Create an outgoing HTTP commpoint. No file descriptor is opened, left at -1.
+ * @param base: in which base to alloc the commpoint.
+ * @param bufsize: size of buffer to create for handlers.
+ * @param callback: callback function pointer for the handler.
+ * @param callback_arg: will be passed to your callback function.
+ * @param temp: sldns buffer, shared between other http_out commpoints, for
+ * temporary data when performing callbacks.
+ * @return: the commpoint or NULL on error.
+ */
+struct comm_point* comm_point_create_http_out(struct comm_base* base,
+ size_t bufsize, comm_point_callback_type* callback,
+ void* callback_arg, struct sldns_buffer* temp);
+
+/**
* Create commpoint to listen to a local domain file descriptor.
* @param base: in which base to alloc the commpoint.
* @param fd: file descriptor of open AF_UNIX socket set to listen nonblocking.
@@ -667,6 +698,16 @@ void comm_point_tcp_handle_callback(int fd, short event, void* arg);
/**
* This routine is published for checks and tests, and is only used internally.
+ * handle libevent callback for tcp data comm point
+ * @param fd: file descriptor.
+ * @param event: event bits from libevent:
+ * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
+ * @param arg: the comm_point structure.
+ */
+void comm_point_http_handle_callback(int fd, short event, void* arg);
+
+/**
+ * This routine is published for checks and tests, and is only used internally.
* handle libevent callback for timer comm.
* @param fd: file descriptor (always -1).
* @param event: event bits from libevent:
diff --git a/usr.sbin/unbound/validator/val_neg.c b/usr.sbin/unbound/validator/val_neg.c
index fe57ac2c442..54123814830 100644
--- a/usr.sbin/unbound/validator/val_neg.c
+++ b/usr.sbin/unbound/validator/val_neg.c
@@ -847,34 +847,71 @@ void neg_insert_data(struct val_neg_cache* neg,
wipeout(neg, zone, el, nsec);
}
+/** see if the reply has signed NSEC records and return the signer */
+static uint8_t* reply_nsec_signer(struct reply_info* rep, size_t* signer_len,
+ uint16_t* dclass)
+{
+ size_t i;
+ struct packed_rrset_data* d;
+ uint8_t* s;
+ for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){
+ if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC ||
+ ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC3) {
+ d = (struct packed_rrset_data*)rep->rrsets[i]->
+ entry.data;
+ /* return first signer name of first NSEC */
+ if(d->rrsig_count != 0) {
+ val_find_rrset_signer(rep->rrsets[i],
+ &s, signer_len);
+ if(s && *signer_len) {
+ *dclass = ntohs(rep->rrsets[i]->
+ rk.rrset_class);
+ return s;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
void val_neg_addreply(struct val_neg_cache* neg, struct reply_info* rep)
{
size_t i, need;
struct ub_packed_rrset_key* soa;
+ uint8_t* dname = NULL;
+ size_t dname_len;
+ uint16_t rrset_class;
struct val_neg_zone* zone;
/* see if secure nsecs inside */
if(!reply_has_nsec(rep))
return;
/* find the zone name in message */
- soa = reply_find_soa(rep);
- if(!soa)
- return;
+ if((soa = reply_find_soa(rep))) {
+ dname = soa->rk.dname;
+ dname_len = soa->rk.dname_len;
+ rrset_class = ntohs(soa->rk.rrset_class);
+ }
+ else {
+ /* No SOA in positive (wildcard) answer. Use signer from the
+ * validated answer RRsets' signature. */
+ if(!(dname = reply_nsec_signer(rep, &dname_len, &rrset_class)))
+ return;
+ }
log_nametypeclass(VERB_ALGO, "negcache insert for zone",
- soa->rk.dname, LDNS_RR_TYPE_SOA, ntohs(soa->rk.rrset_class));
+ dname, LDNS_RR_TYPE_SOA, rrset_class);
/* ask for enough space to store all of it */
need = calc_data_need(rep) +
- calc_zone_need(soa->rk.dname, soa->rk.dname_len);
+ calc_zone_need(dname, dname_len);
lock_basic_lock(&neg->lock);
neg_make_space(neg, need);
/* find or create the zone entry */
- zone = neg_find_zone(neg, soa->rk.dname, soa->rk.dname_len,
- ntohs(soa->rk.rrset_class));
+ zone = neg_find_zone(neg, dname, dname_len, rrset_class);
if(!zone) {
- if(!(zone = neg_create_zone(neg, soa->rk.dname,
- soa->rk.dname_len, ntohs(soa->rk.rrset_class)))) {
+ if(!(zone = neg_create_zone(neg, dname, dname_len,
+ rrset_class))) {
lock_basic_unlock(&neg->lock);
log_err("out of memory adding negative zone");
return;
@@ -1029,33 +1066,6 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
return 1;
}
-/** see if the reply has signed NSEC records and return the signer */
-static uint8_t* reply_nsec_signer(struct reply_info* rep, size_t* signer_len,
- uint16_t* dclass)
-{
- size_t i;
- struct packed_rrset_data* d;
- uint8_t* s;
- for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){
- if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC ||
- ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC3) {
- d = (struct packed_rrset_data*)rep->rrsets[i]->
- entry.data;
- /* return first signer name of first NSEC */
- if(d->rrsig_count != 0) {
- val_find_rrset_signer(rep->rrsets[i],
- &s, signer_len);
- if(s && *signer_len) {
- *dclass = ntohs(rep->rrsets[i]->
- rk.rrset_class);
- return s;
- }
- }
- }
- }
- return 0;
-}
-
void val_neg_addreferral(struct val_neg_cache* neg, struct reply_info* rep,
uint8_t* zone_name)
{
@@ -1183,6 +1193,73 @@ grab_nsec(struct rrset_cache* rrset_cache, uint8_t* qname, size_t qname_len,
return r;
}
+/**
+ * Get best NSEC record for qname. Might be matching, covering or totally
+ * useless.
+ * @param neg_cache: neg cache
+ * @param qname: to lookup rrset name
+ * @param qname_len: length of qname.
+ * @param qclass: class of rrset to lookup, host order
+ * @param rrset_cache: rrset cache
+ * @param now: to check ttl against
+ * @param region: where to alloc result
+ * @return rrset or NULL
+ */
+static struct ub_packed_rrset_key*
+neg_find_nsec(struct val_neg_cache* neg_cache, uint8_t* qname, size_t qname_len,
+ uint16_t qclass, struct rrset_cache* rrset_cache, time_t now,
+ struct regional* region)
+{
+ int labs;
+ uint32_t flags;
+ struct val_neg_zone* zone;
+ struct val_neg_data* data;
+ struct ub_packed_rrset_key* nsec;
+
+ labs = dname_count_labels(qname);
+ lock_basic_lock(&neg_cache->lock);
+ zone = neg_closest_zone_parent(neg_cache, qname, qname_len, labs,
+ qclass);
+ while(zone && !zone->in_use)
+ zone = zone->parent;
+ if(!zone) {
+ lock_basic_unlock(&neg_cache->lock);
+ return NULL;
+ }
+
+ /* NSEC only for now */
+ if(zone->nsec3_hash) {
+ lock_basic_unlock(&neg_cache->lock);
+ return NULL;
+ }
+
+ /* ignore return value, don't care if it is an exact or smaller match */
+ (void)neg_closest_data(zone, qname, qname_len, labs, &data);
+ if(!data) {
+ lock_basic_unlock(&neg_cache->lock);
+ return NULL;
+ }
+
+ /* ENT nodes are not in use, try the previous node. If the previous node
+ * is not in use, we don't have an useful NSEC and give up. */
+ if(!data->in_use) {
+ data = (struct val_neg_data*)rbtree_previous((rbnode_type*)data);
+ if((rbnode_type*)data == RBTREE_NULL || !data->in_use) {
+ lock_basic_unlock(&neg_cache->lock);
+ return NULL;
+ }
+ }
+
+ flags = 0;
+ if(query_dname_compare(data->name, zone->name) == 0)
+ flags = PACKED_RRSET_NSEC_AT_APEX;
+
+ nsec = grab_nsec(rrset_cache, data->name, data->len, LDNS_RR_TYPE_NSEC,
+ zone->dclass, flags, region, 0, 0, now);
+ lock_basic_unlock(&neg_cache->lock);
+ return nsec;
+}
+
/** find nsec3 closest encloser in neg cache */
static struct val_neg_data*
neg_find_nsec3_ce(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len,
@@ -1400,41 +1477,132 @@ static int add_soa(struct rrset_cache* rrset_cache, time_t now,
struct dns_msg*
val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
struct regional* region, struct rrset_cache* rrset_cache,
- sldns_buffer* buf, time_t now, int addsoa, uint8_t* topname)
+ sldns_buffer* buf, time_t now, int addsoa, uint8_t* topname,
+ struct config_file* cfg)
{
struct dns_msg* msg;
- struct ub_packed_rrset_key* rrset;
+ struct ub_packed_rrset_key* nsec; /* qname matching/covering nsec */
+ struct ub_packed_rrset_key* wcrr; /* wildcard record or nsec */
+ uint8_t* nodata_wc = NULL;
+ uint8_t* ce = NULL;
+ size_t ce_len;
+ uint8_t wc_ce[LDNS_MAX_DOMAINLEN+3];
+ struct query_info wc_qinfo;
+ struct ub_packed_rrset_key* cache_wc;
+ struct packed_rrset_data* wcrr_data;
+ int rcode = LDNS_RCODE_NOERROR;
uint8_t* zname;
size_t zname_len;
int zname_labs;
struct val_neg_zone* zone;
- /* only for DS queries */
- if(qinfo->qtype != LDNS_RR_TYPE_DS)
+ /* only for DS queries when aggressive use of NSEC is disabled */
+ if(qinfo->qtype != LDNS_RR_TYPE_DS && !cfg->aggressive_nsec)
return NULL;
log_assert(!topname || dname_subdomain_c(qinfo->qname, topname));
- /* see if info from neg cache is available
- * For NSECs, because there is no optout; a DS next to a delegation
- * always has exactly an NSEC for it itself; check its DS bit.
- * flags=0 (not the zone apex).
- */
- rrset = grab_nsec(rrset_cache, qinfo->qname, qinfo->qname_len,
- LDNS_RR_TYPE_NSEC, qinfo->qclass, 0, region, 1,
- qinfo->qtype, now);
- if(rrset) {
- /* return msg with that rrset */
+ /* Get best available NSEC for qname */
+ nsec = neg_find_nsec(neg, qinfo->qname, qinfo->qname_len, qinfo->qclass,
+ rrset_cache, now, region);
+
+ /* Matching NSEC, use to generate No Data answer. Not creating answers
+ * yet for No Data proven using wildcard. */
+ if(nsec && nsec_proves_nodata(nsec, qinfo, &nodata_wc) && !nodata_wc) {
if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
qinfo->qtype, qinfo->qclass, region, 2)))
return NULL;
- /* TTL already subtracted in grab_nsec */
- if(!dns_msg_authadd(msg, region, rrset, 0))
+ if(!dns_msg_authadd(msg, region, nsec, 0))
return NULL;
if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
return NULL;
return msg;
+ } else if(nsec && val_nsec_proves_name_error(nsec, qinfo->qname)) {
+ if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
+ qinfo->qtype, qinfo->qclass, region, 3)))
+ return NULL;
+ if(!(ce = nsec_closest_encloser(qinfo->qname, nsec)))
+ return NULL;
+ dname_count_size_labels(ce, &ce_len);
+
+ /* No extra extra NSEC required if both nameerror qname and
+ * nodata *.ce. are proven already. */
+ if(!nodata_wc || query_dname_compare(nodata_wc, ce) != 0) {
+ /* Qname proven non existing, get wildcard record for
+ * QTYPE or NSEC covering or matching wildcard. */
+
+ /* Num labels in ce is always smaller than in qname,
+ * therefore adding the wildcard label cannot overflow
+ * buffer. */
+ wc_ce[0] = 1;
+ wc_ce[1] = (uint8_t)'*';
+ memmove(wc_ce+2, ce, ce_len);
+ wc_qinfo.qname = wc_ce;
+ wc_qinfo.qname_len = ce_len + 2;
+ wc_qinfo.qtype = qinfo->qtype;
+
+
+ if((cache_wc = rrset_cache_lookup(rrset_cache, wc_qinfo.qname,
+ wc_qinfo.qname_len, wc_qinfo.qtype,
+ qinfo->qclass, 0/*flags*/, now, 0/*read only*/))) {
+ /* Synthesize wildcard answer */
+ wcrr_data = (struct packed_rrset_data*)cache_wc->entry.data;
+ if(!(wcrr_data->security == sec_status_secure ||
+ (wcrr_data->security == sec_status_unchecked &&
+ wcrr_data->rrsig_count > 0))) {
+ lock_rw_unlock(&cache_wc->entry.lock);
+ return NULL;
+ }
+ if(!(wcrr = packed_rrset_copy_region(cache_wc,
+ region, now))) {
+ lock_rw_unlock(&cache_wc->entry.lock);
+ return NULL;
+ };
+ lock_rw_unlock(&cache_wc->entry.lock);
+ wcrr->rk.dname = qinfo->qname;
+ wcrr->rk.dname_len = qinfo->qname_len;
+ if(!dns_msg_ansadd(msg, region, wcrr, 0))
+ return NULL;
+ /* No SOA needed for wildcard synthesised
+ * answer. */
+ addsoa = 0;
+ } else {
+ /* Get wildcard NSEC for possible non existence
+ * proof */
+ if(!(wcrr = neg_find_nsec(neg, wc_qinfo.qname,
+ wc_qinfo.qname_len, qinfo->qclass,
+ rrset_cache, now, region)))
+ return NULL;
+
+ nodata_wc = NULL;
+ if(val_nsec_proves_name_error(wcrr, wc_ce))
+ rcode = LDNS_RCODE_NXDOMAIN;
+ else if(!nsec_proves_nodata(wcrr, &wc_qinfo,
+ &nodata_wc) || nodata_wc)
+ /* &nodata_wc shoudn't be set, wc_qinfo
+ * already contains wildcard domain. */
+ /* NSEC doesn't prove anything for
+ * wildcard. */
+ return NULL;
+ if(query_dname_compare(wcrr->rk.dname,
+ nsec->rk.dname) != 0)
+ if(!dns_msg_authadd(msg, region, wcrr, 0))
+ return NULL;
+ }
+ }
+
+ if(!dns_msg_authadd(msg, region, nsec, 0))
+ return NULL;
+ if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
+ return NULL;
+
+ FLAGS_SET_RCODE(msg->rep->flags, rcode);
+ return msg;
}
+ /* No aggressive use of NSEC3 for now, only proceed for DS types. */
+ if(qinfo->qtype != LDNS_RR_TYPE_DS){
+ return NULL;
+ }
/* check NSEC3 neg cache for type DS */
/* need to look one zone higher for DS type */
zname = qinfo->qname;
diff --git a/usr.sbin/unbound/validator/val_neg.h b/usr.sbin/unbound/validator/val_neg.h
index 6ae71306c37..00dad6df1f5 100644
--- a/usr.sbin/unbound/validator/val_neg.h
+++ b/usr.sbin/unbound/validator/val_neg.h
@@ -250,6 +250,7 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
* more conservative, especially for opt-out zones, since the receiver
* may have a trust-anchor below the optout and thus the optout cannot
* be used to create a proof from the negative cache.
+ * @param cfg: config options.
* @return a reply message if something was found.
* This reply may still need validation.
* NULL if nothing found (or out of memory).
@@ -257,7 +258,7 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
struct dns_msg* val_neg_getmsg(struct val_neg_cache* neg,
struct query_info* qinfo, struct regional* region,
struct rrset_cache* rrset_cache, struct sldns_buffer* buf, time_t now,
- int addsoa, uint8_t* topname);
+ int addsoa, uint8_t* topname, struct config_file* cfg);
/**** functions exposed for unit test ****/
diff --git a/usr.sbin/unbound/validator/val_nsec.c b/usr.sbin/unbound/validator/val_nsec.c
index 4604f3d6d42..a795e77339d 100644
--- a/usr.sbin/unbound/validator/val_nsec.c
+++ b/usr.sbin/unbound/validator/val_nsec.c
@@ -513,7 +513,6 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname,
/* Determine if a NSEC record proves the non-existence of a
* wildcard that could have produced qname. */
int labs;
- int i;
uint8_t* ce = nsec_closest_encloser(qname, nsec);
uint8_t* strip;
size_t striplen;
@@ -526,13 +525,13 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname,
* and next names. */
labs = dname_count_labels(qname) - dname_count_labels(ce);
- for(i=labs; i>0; i--) {
+ if(labs > 0) {
/* i is number of labels to strip off qname, prepend * wild */
strip = qname;
striplen = qnamelen;
- dname_remove_labels(&strip, &striplen, i);
+ dname_remove_labels(&strip, &striplen, labs);
if(striplen > LDNS_MAX_DOMAINLEN-2)
- continue; /* too long to prepend wildcard */
+ return 0; /* too long to prepend wildcard */
buf[0] = 1;
buf[1] = (uint8_t)'*';
memmove(buf+2, strip, striplen);
diff --git a/usr.sbin/unbound/validator/val_utils.c b/usr.sbin/unbound/validator/val_utils.c
index 0eabb7f33ba..2f36fccfd4f 100644
--- a/usr.sbin/unbound/validator/val_utils.c
+++ b/usr.sbin/unbound/validator/val_utils.c
@@ -767,7 +767,8 @@ rrsig_get_labcount(struct packed_rrset_data* d, size_t sig)
}
int
-val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc)
+val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc,
+ size_t* wc_len)
{
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
entry.data;
@@ -800,6 +801,7 @@ val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc)
if(labdiff > 0) {
*wc = wn;
dname_remove_labels(wc, &wl, labdiff);
+ *wc_len = wl;
return 1;
}
return 1;
@@ -1161,6 +1163,6 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
qinfo.local_alias = NULL;
/* do not add SOA to reply message, it is going to be used internal */
msg = val_neg_getmsg(env->neg_cache, &qinfo, region, env->rrset_cache,
- env->scratch_buffer, *env->now, 0, topname);
+ env->scratch_buffer, *env->now, 0, topname, env->cfg);
return msg;
}
diff --git a/usr.sbin/unbound/validator/val_utils.h b/usr.sbin/unbound/validator/val_utils.h
index b582472f8fa..6e9867f6e3c 100644
--- a/usr.sbin/unbound/validator/val_utils.h
+++ b/usr.sbin/unbound/validator/val_utils.h
@@ -271,6 +271,7 @@ int val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset);
* @param wc: the wildcard name, if the rrset was synthesized from a wildcard.
* unchanged if not. The wildcard name, without "*." in front, is
* returned. This is a pointer into the rrset owner name.
+ * @param wc_len: the length of the returned wildcard name.
* @return false if the signatures are inconsistent in indicating the
* wildcard status; possible spoofing of wildcard response for other
* responses is being tried. We lost the status which rrsig was verified
@@ -279,7 +280,8 @@ int val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset);
* of service; but in that you could also have removed the real
* signature anyway.
*/
-int val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc);
+int val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc,
+ size_t* wc_len);
/**
* Chase the cname to the next query name.
diff --git a/usr.sbin/unbound/validator/validator.c b/usr.sbin/unbound/validator/validator.c
index 456bffd005f..5ed45e9bdef 100644
--- a/usr.sbin/unbound/validator/validator.c
+++ b/usr.sbin/unbound/validator/validator.c
@@ -51,6 +51,7 @@
#include "validator/val_sigcrypt.h"
#include "validator/autotrust.h"
#include "services/cache/dns.h"
+#include "services/cache/rrset.h"
#include "util/data/dname.h"
#include "util/module.h"
#include "util/log.h"
@@ -461,7 +462,7 @@ generate_keytag_query(struct module_qstate* qstate, int id,
return 0;
}
- log_nametypeclass(VERB_ALGO, "keytag query", keytagdname,
+ log_nametypeclass(VERB_OPS, "generate keytag query", keytagdname,
LDNS_RR_TYPE_NULL, ta->dclass);
if(!generate_request(qstate, id, keytagdname, dnamebuf_len,
LDNS_RR_TYPE_NULL, ta->dclass, 0, &newq, 1)) {
@@ -745,6 +746,8 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
struct key_entry_key* kkey)
{
uint8_t* wc = NULL;
+ size_t wl;
+ int wc_cached = 0;
int wc_NSEC_ok = 0;
int nsec3s_seen = 0;
size_t i;
@@ -757,13 +760,19 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
/* Check to see if the rrset is the result of a wildcard
* expansion. If so, an additional check will need to be
* made in the authority section. */
- if(!val_rrset_wildcard(s, &wc)) {
+ if(!val_rrset_wildcard(s, &wc, &wl)) {
log_nametypeclass(VERB_QUERY, "Positive response has "
"inconsistent wildcard sigs:", s->rk.dname,
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
chase_reply->security = sec_status_bogus;
return;
}
+ if(wc && !wc_cached && env->cfg->aggressive_nsec) {
+ rrset_cache_update_wildcard(env->rrset_cache, s, wc, wl,
+ env->alloc, *env->now);
+ wc_cached = 1;
+ }
+
}
/* validate the AUTHORITY section as well - this will generally be
@@ -944,6 +953,9 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
int nsec3s_seen = 0;
struct ub_packed_rrset_key* s;
size_t i;
+ uint8_t* ce;
+ int ce_labs = 0;
+ int prev_ce_labs = 0;
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
chase_reply->ns_numrrsets; i++) {
@@ -951,9 +963,19 @@ validate_nameerror_response(struct module_env* env, struct val_env* ve,
if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) {
if(val_nsec_proves_name_error(s, qchase->qname))
has_valid_nsec = 1;
- if(val_nsec_proves_no_wc(s, qchase->qname,
- qchase->qname_len))
- has_valid_wnsec = 1;
+ ce = nsec_closest_encloser(qchase->qname, s);
+ ce_labs = dname_count_labels(ce);
+ /* Use longest closest encloser to prove wildcard. */
+ if(ce_labs > prev_ce_labs ||
+ (ce_labs == prev_ce_labs &&
+ has_valid_wnsec == 0)) {
+ if(val_nsec_proves_no_wc(s, qchase->qname,
+ qchase->qname_len))
+ has_valid_wnsec = 1;
+ else
+ has_valid_wnsec = 0;
+ }
+ prev_ce_labs = ce_labs;
if(val_nsec_proves_insecuredelegation(s, qchase)) {
verbose(VERB_ALGO, "delegation is insecure");
chase_reply->security = sec_status_insecure;
@@ -1068,6 +1090,7 @@ validate_any_response(struct module_env* env, struct val_env* ve,
/* but check if a wildcard response is given, then check NSEC/NSEC3
* for qname denial to see if wildcard is applicable */
uint8_t* wc = NULL;
+ size_t wl;
int wc_NSEC_ok = 0;
int nsec3s_seen = 0;
size_t i;
@@ -1086,7 +1109,7 @@ validate_any_response(struct module_env* env, struct val_env* ve,
/* Check to see if the rrset is the result of a wildcard
* expansion. If so, an additional check will need to be
* made in the authority section. */
- if(!val_rrset_wildcard(s, &wc)) {
+ if(!val_rrset_wildcard(s, &wc, &wl)) {
log_nametypeclass(VERB_QUERY, "Positive ANY response"
" has inconsistent wildcard sigs:",
s->rk.dname, ntohs(s->rk.type),
@@ -1175,6 +1198,7 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
struct key_entry_key* kkey)
{
uint8_t* wc = NULL;
+ size_t wl;
int wc_NSEC_ok = 0;
int nsec3s_seen = 0;
size_t i;
@@ -1187,7 +1211,7 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
/* Check to see if the rrset is the result of a wildcard
* expansion. If so, an additional check will need to be
* made in the authority section. */
- if(!val_rrset_wildcard(s, &wc)) {
+ if(!val_rrset_wildcard(s, &wc, &wl)) {
log_nametypeclass(VERB_QUERY, "Cname response has "
"inconsistent wildcard sigs:", s->rk.dname,
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
@@ -1296,6 +1320,9 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
int nsec3s_seen = 0; /* nsec3s seen */
struct ub_packed_rrset_key* s;
size_t i;
+ uint8_t* nsec_ce; /* Used to find the NSEC with the longest ce */
+ int ce_labs = 0;
+ int prev_ce_labs = 0;
/* the AUTHORITY section */
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
@@ -1314,9 +1341,19 @@ validate_cname_noanswer_response(struct module_env* env, struct val_env* ve,
ce = nsec_closest_encloser(qchase->qname, s);
nxdomain_valid_nsec = 1;
}
- if(val_nsec_proves_no_wc(s, qchase->qname,
- qchase->qname_len))
- nxdomain_valid_wnsec = 1;
+ nsec_ce = nsec_closest_encloser(qchase->qname, s);
+ ce_labs = dname_count_labels(nsec_ce);
+ /* Use longest closest encloser to prove wildcard. */
+ if(ce_labs > prev_ce_labs ||
+ (ce_labs == prev_ce_labs &&
+ nxdomain_valid_wnsec == 0)) {
+ if(val_nsec_proves_no_wc(s, qchase->qname,
+ qchase->qname_len))
+ nxdomain_valid_wnsec = 1;
+ else
+ nxdomain_valid_wnsec = 0;
+ }
+ prev_ce_labs = ce_labs;
if(val_nsec_proves_insecuredelegation(s, qchase)) {
verbose(VERB_ALGO, "delegation is insecure");
chase_reply->security = sec_status_insecure;
@@ -2134,6 +2171,10 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
if(vq->orig_msg->rep->security == sec_status_secure) {
log_query_info(VERB_DETAIL, "validation success",
&qstate->qinfo);
+ if(!qstate->no_cache_store) {
+ val_neg_addreply(qstate->env->neg_cache,
+ vq->orig_msg->rep);
+ }
}
}