services/localzone.c services/mesh.c services/modstack.c services/view.c \
services/outbound_list.c services/outside_network.c util/alloc.c \
util/config_file.c util/configlexer.c util/configparser.c \
-util/shm_side/shm_main.c services/authzone.c\
+util/shm_side/shm_main.c services/authzone.c \
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
util/rtt.c util/storage/dnstree.c util/storage/lookup3.c \
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
-cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
+cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
-val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo authzone.lo\
+val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
- $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
+ $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
- $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) $(LIBS) -L. -L.libs -lunbound
+ $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
# 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)/sldns/pkthdr.h \
+ $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/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/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/config_file.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/net_help.h
as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/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)/testcode/checklocks.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/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/testcode/checklocks.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 \
iter_fwd.lo iter_fwd.o: $(srcdir)/iterator/iter_fwd.c config.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
iter_hints.lo iter_hints.o: $(srcdir)/iterator/iter_hints.c config.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/testcode/checklocks.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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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 \
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)/testcode/checklocks.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 \
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)/testcode/checklocks.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/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/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)/testcode/checklocks.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/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/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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 $(srcdir)/testcode/checklocks.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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/testcode/checklocks.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 \
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)/testcode/checklocks.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/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)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/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/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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
+ $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.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 \
+ $(srcdir)/testcode/checklocks.h
+log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.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)/testcode/checklocks.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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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 \
rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h
dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/util/net_help.h
+ $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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 \
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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \
- $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h \
+ $(srcdir)/testcode/checklocks.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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/sldns/pkthdr.h \
+ $(srcdir)/testcode/checklocks.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)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/sldns/pkthdr.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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 \
val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h \
+ $(srcdir)/testcode/checklocks.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)/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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/testcode/checklocks.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)/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)/testcode/checklocks.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
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/testcode/checklocks.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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/cachedb/redis.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
+redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h $(srcdir)/cachedb/cachedb.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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 \
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/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/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/log.h $(srcdir)/testcode/checklocks.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)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/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/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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
+ $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/testcode/checklocks.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)/sldns/pkthdr.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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 \
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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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/log.h $(srcdir)/testcode/checklocks.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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/testcode/checklocks.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)/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)/services/view.h $(srcdir)/services/authzone.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)/testcode/checklocks.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)/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/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
+ $(srcdir)/validator/val_neg.h
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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 \
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)/testcode/checklocks.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)/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)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/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)/testcode/checklocks.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 \
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)/testcode/checklocks.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)/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)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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 \
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)/testcode/checklocks.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)/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/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
+ $(srcdir)/validator/val_neg.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/testcode/checklocks.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)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
readhex.lo readhex.o: $(srcdir)/testcode/readhex.c config.h $(srcdir)/testcode/readhex.h $(srcdir)/util/log.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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)/testcode/checklocks.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)/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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/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)/services/authzone.h \
- $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/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)/util/log.h $(srcdir)/testcode/checklocks.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)/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/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h \
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
+
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/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)/testcode/checklocks.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h \
+
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)/testcode/checklocks.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)/testcode/checklocks.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/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.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 \
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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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)/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)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.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/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h
+ $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
$(srcdir)/winrc/w_inst.h
rrdef.lo rrdef.o: $(srcdir)/sldns/rrdef.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
str2wire.lo str2wire.o: $(srcdir)/sldns/str2wire.c config.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h
-ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
+ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/testcode/checklocks.h
fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h
inet_aton.lo inet_aton.o: $(srcdir)/compat/inet_aton.c config.h
#include "config.h"
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
+#include "cachedb/redis.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "sldns/wire2str.h"
#include "sldns/sbuffer.h"
-#define CACHEDB_HASHSIZE 256 /* bit hash */
+/* header file for htobe64 */
+#ifdef HAVE_ENDIAN_H
+# include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+# include <sys/endian.h>
+#endif
+#ifdef HAVE_LIBKERN_OSBYTEORDER_H
+/* In practice this is specific to MacOS X. We assume it doesn't have
+* htobe64/be64toh but has alternatives with a different name. */
+# include <libkern/OSByteOrder.h>
+# define htobe64(x) OSSwapHostToBigInt64(x)
+# define be64toh(x) OSSwapBigToHostInt64(x)
+#endif
/** the unit test testframe for cachedb, its module state contains
* a cache for a couple queries (in memory). */
static struct cachedb_backend*
cachedb_find_backend(const char* str)
{
+#ifdef USE_REDIS
+ if(strcmp(str, redis_backend.name) == 0)
+ return &redis_backend;
+#endif
if(strcmp(str, testframe_backend.name) == 0)
return &testframe_backend;
/* TODO add more backends here */
qstate->region, qstate->env->scratch,
1 /* no partial messages with only a CNAME */
);
- if(!msg && qstate->env->neg_cache) {
+ if(!msg && qstate->env->neg_cache &&
+ iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
/* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
uint8_t*, size_t);
};
+#define CACHEDB_HASHSIZE 256 /* bit hash */
+
/** Init the cachedb module */
int cachedb_init(struct module_env* env, int id);
/** Deinit the cachedb module */
internal symbols */
#undef EXPORT_ALL_SYMBOLS
+/* Define to 1 if you have the `accept4' function. */
+#undef HAVE_ACCEPT4
+
/* Define to 1 if you have the `arc4random' function. */
#undef HAVE_ARC4RANDOM
don't. */
#undef HAVE_DECL_NID_ED25519
+/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
+ don't. */
+#undef HAVE_DECL_NID_ED448
+
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
don't. */
#undef HAVE_DECL_NID_SECP384R1
don't. */
#undef HAVE_DECL_REALLOCARRAY
+/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
+ don't. */
+#undef HAVE_DECL_REDISCONNECT
+
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
if you don't. */
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
/* Define to 1 if you have the <grp.h> header file. */
#undef HAVE_GRP_H
+/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
+#undef HAVE_HIREDIS_HIREDIS_H
+
/* If you have HMAC_Update */
#undef HAVE_HMAC_UPDATE
/* Define to 1 if you have the `kill' function. */
#undef HAVE_KILL
+/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
+#undef HAVE_LIBKERN_OSBYTEORDER_H
+
/* Define if we have LibreSSL */
#undef HAVE_LIBRESSL
/* Define to 1 if systemd should be used */
#undef HAVE_SYSTEMD
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#undef HAVE_SYS_ENDIAN_H
+
/* Define to 1 if you have the <sys/ipc.h> header file. */
#undef HAVE_SYS_IPC_H
/* Define this to enable ED25519 support. */
#undef USE_ED25519
+/* Define this to enable ED448 support. */
+#undef USE_ED448
+
/* Define this to enable GOST support. */
#undef USE_GOST
/* Define this to enable client TCP Fast Open. */
#undef USE_OSX_MSG_FASTOPEN
+/* Define this to use hiredis client. */
+#undef USE_REDIS
+
/* Define this to enable SHA1 support. */
#undef USE_SHA1
/** default port for DNS traffic. */
#define UNBOUND_DNS_PORT 53
+/** default port for DNS over TLS traffic. */
+#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.7.0.
+# Generated by GNU Autoconf 2.69 for unbound 1.7.3.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
#
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.7.0'
-PACKAGE_STRING='unbound 1.7.0'
+PACKAGE_VERSION='1.7.3'
+PACKAGE_STRING='unbound 1.7.3'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
PACKAGE_URL=''
enable_ecdsa
enable_dsa
enable_ed25519
+enable_ed448
enable_event_api
enable_tfo_client
enable_tfo_server
with_libevent
with_libexpat
+with_libhiredis
enable_static_exe
enable_systemd
enable_lock_checks
# 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.7.0 to adapt to many kinds of systems.
+\`configure' configures unbound 1.7.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of unbound 1.7.0:";;
+ short | recursive ) echo "Configuration of unbound 1.7.3:";;
esac
cat <<\_ACEOF
--disable-ecdsa Disable ECDSA support
--disable-dsa Disable DSA support
--disable-ed25519 Disable ED25519 support
+ --disable-ed448 Disable ED448 support
--enable-event-api Enable (experimental) pluggable event base
libunbound API installed to unbound-event.h
--enable-tfo-client Enable TCP Fast Open for client mode
an explicit path). Slower, but allows use of large
outgoing port ranges.
--with-libexpat=path specify explicit path for libexpat.
+ --with-libhiredis=path specify explicit path for libhiredis.
--with-dnstap-socket-path=pathname
set default dnstap socket path
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-unbound configure 1.7.0
+unbound configure 1.7.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by unbound $as_me 1.7.0, which was
+It was created by unbound $as_me 1.7.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
UNBOUND_VERSION_MINOR=7
-UNBOUND_VERSION_MICRO=0
+UNBOUND_VERSION_MICRO=3
LIBUNBOUND_CURRENT=7
-LIBUNBOUND_REVISION=7
+LIBUNBOUND_REVISION=11
LIBUNBOUND_AGE=5
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.6.7 had 7:6:5
# 1.6.8 had 7:7:5
# 1.7.0 had 7:8:5
+# 1.7.1 had 7:9:5
+# 1.7.2 had 7:10:5
+# 1.7.3 had 7:11:5
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
# Checks for header files.
-for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h
+for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
;;
esac
+# Check whether --enable-ed448 was given.
+if test "${enable_ed448+set}" = set; then :
+ enableval=$enable_ed448;
+fi
+
+use_ed448="no"
+case "$enable_ed448" in
+ no)
+ ;;
+ *)
+ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
+ ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default
+#include <openssl/evp.h>
+
+"
+if test "x$ac_cv_have_decl_NID_ED448" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_NID_ED448 $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+ use_ed448="yes"
+
+else
+ if test "x$enable_ed448" = "xyes"; then as_fn_error $? "OpenSSL does not support ED448 and you used --enable-ed448." "$LINENO" 5
+ fi
+fi
+
+ fi
+ if test $use_ed448 = "yes"; then
+
+cat >>confdefs.h <<_ACEOF
+#define USE_ED448 1
+_ACEOF
+
+ fi
+ ;;
+esac
+
# Check whether --enable-event-api was given.
if test "${enable_event_api+set}" = set; then :
enableval=$enable_event_api;
_ACEOF
+# hiredis (redis C client for cachedb)
+
+# Check whether --with-libhiredis was given.
+if test "${with_libhiredis+set}" = set; then :
+ withval=$with_libhiredis;
+else
+ withval="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libhiredis" >&5
+$as_echo_n "checking for libhiredis... " >&6; }
+found_libhiredis="no"
+if test x_$withval = x_yes -o x_$withval != x_no; then
+ if test x_$withval = x_ -o x_$withval = x_yes; then
+ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
+ fi
+ for dir in $withval ; do
+ if test -f "$dir/include/hiredis/hiredis.h"; then
+ found_libhiredis="yes"
+ if test "$dir" != "/usr"; then
+ CPPFLAGS="$CPPFLAGS -I$dir/include"
+ LDFLAGS="$LDFLAGS -L$dir/lib"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
+$as_echo "found in $dir" >&6; }
+
+$as_echo "#define USE_REDIS 1" >>confdefs.h
+
+ LIBS="$LIBS -lhiredis"
+ break;
+ fi
+ done
+ if test x_$found_libhiredis != x_yes; then
+ as_fn_error $? "Could not find libhiredis, hiredis.h" "$LINENO" 5
+ fi
+ for ac_header in hiredis/hiredis.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "hiredis/hiredis.h" "ac_cv_header_hiredis_hiredis_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_hiredis_hiredis_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HIREDIS_HIREDIS_H 1
+_ACEOF
+
+fi
+
+done
+
+ ac_fn_c_check_decl "$LINENO" "redisConnect" "ac_cv_have_decl_redisConnect" "$ac_includes_default
+ #include <hiredis/hiredis.h>
+
+"
+if test "x$ac_cv_have_decl_redisConnect" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_REDISCONNECT $ac_have_decl
+_ACEOF
+
+fi
+
# set static linking if requested
staticexe=""
WINDRES="$ac_cv_prog_WINDRES"
fi
- LIBS="$LIBS -liphlpapi"
+ LIBS="$LIBS -liphlpapi -lcrypt32"
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
fi
-for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget
+for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
-if echo $build_os | grep darwin8 > /dev/null; then
+if echo $target_os | grep darwin8 > /dev/null; then
$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
enableval=$enable_cachedb;
fi
+# turn on cachedb when hiredis support is enabled.
+if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
case "$enable_cachedb" in
yes)
-version=1.7.0
+version=1.7.3
date=`date +'%b %e, %Y'`
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by unbound $as_me 1.7.0, which was
+This file was extended by unbound $as_me 1.7.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
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.7.0
+unbound config.status 1.7.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[7])
-m4_define([VERSION_MICRO],[0])
+m4_define([VERSION_MICRO],[3])
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])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=7
-LIBUNBOUND_REVISION=7
+LIBUNBOUND_REVISION=11
LIBUNBOUND_AGE=5
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.6.7 had 7:6:5
# 1.6.8 had 7:7:5
# 1.7.0 had 7:8:5
+# 1.7.1 had 7:9:5
+# 1.7.2 had 7:10:5
+# 1.7.3 had 7:11:5
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
ACX_LIBTOOL_C_ONLY
# Checks for header files.
-AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
;;
esac
+AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support]))
+use_ed448="no"
+case "$enable_ed448" in
+ no)
+ ;;
+ *)
+ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
+ AC_CHECK_DECLS([NID_ED448], [
+ use_ed448="yes"
+ ], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.])
+ fi ], [AC_INCLUDES_DEFAULT
+#include <openssl/evp.h>
+ ])
+ fi
+ if test $use_ed448 = "yes"; then
+ AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
+ fi
+ ;;
+esac
+
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
case "$enable_event_api" in
yes)
#include <expat.h>
])
+# hiredis (redis C client for cachedb)
+AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path],
+ [specify explicit path for libhiredis.]),
+ [ ],[ withval="no" ])
+AC_MSG_CHECKING(for libhiredis)
+found_libhiredis="no"
+if test x_$withval = x_yes -o x_$withval != x_no; then
+ if test x_$withval = x_ -o x_$withval = x_yes; then
+ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
+ fi
+ for dir in $withval ; do
+ if test -f "$dir/include/hiredis/hiredis.h"; then
+ found_libhiredis="yes"
+ dnl assume /usr is in default path.
+ if test "$dir" != "/usr"; then
+ CPPFLAGS="$CPPFLAGS -I$dir/include"
+ LDFLAGS="$LDFLAGS -L$dir/lib"
+ fi
+ AC_MSG_RESULT(found in $dir)
+ AC_DEFINE([USE_REDIS], [1], [Define this to use hiredis client.])
+ LIBS="$LIBS -lhiredis"
+ break;
+ fi
+ done
+ if test x_$found_libhiredis != x_yes; then
+ AC_ERROR([Could not find libhiredis, hiredis.h])
+ fi
+ AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT])
+ AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT
+ #include <hiredis/hiredis.h>
+ ])
+fi
+
# set static linking if requested
AC_SUBST(staticexe)
staticexe=""
#include <windows.h>
])
AC_CHECK_TOOL(WINDRES, windres)
- LIBS="$LIBS -liphlpapi"
+ LIBS="$LIBS -liphlpapi -lcrypt32"
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
AC_SUBST(WINAPPS)
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
#endif
])
AC_SEARCH_LIBS([setusercontext], [util])
-AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget])
+AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
-if echo $build_os | grep darwin8 > /dev/null; then
+if echo $target_os | grep darwin8 > /dev/null; then
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
fi
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
# check for cachedb if requested
AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage]))
+# turn on cachedb when hiredis support is enabled.
+if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
case "$enable_cachedb" in
yes)
AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support])
/** default port for DNS traffic. */
#define UNBOUND_DNS_PORT 53
+/** default port for DNS over TLS traffic. */
+#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953
control = acl_refuse_non_local;
else if(strcmp(s2, "allow_snoop") == 0)
control = acl_allow_snoop;
+ else if(strcmp(s2, "allow_setrd") == 0)
+ control = acl_allow_setrd;
else {
log_err("access control type %s unknown", str);
return 0;
/** allow full access for recursion (+RD) queries */
acl_allow,
/** allow full access for all queries, recursion and cache snooping */
- acl_allow_snoop
+ acl_allow_snoop,
+ /** allow full access for recursion queries and set RD flag regardless of request */
+ acl_allow_setrd
};
/**
/** dump one rrset zonefile line */
static int
-dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
+dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
{
char s[65535];
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
/** dump rrset key and data info */
static int
-dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
+dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
struct packed_rrset_data* d, time_t now)
{
size_t i;
/** dump lruhash rrset cache */
static int
-dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
+dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
{
struct lruhash_entry* e;
/* lruhash already locked by caller */
/** dump rrset cache */
static int
-dump_rrset_cache(SSL* ssl, struct worker* worker)
+dump_rrset_cache(RES* ssl, struct worker* worker)
{
struct rrset_cache* r = worker->env.rrset_cache;
size_t slab;
/** dump message to rrset reference */
static int
-dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
+dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
{
char* nm, *tp, *cl;
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
/** dump message entry */
static int
-dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
+dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
time_t now)
{
size_t i;
/** dump lruhash msg cache */
static int
-dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
+dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
{
struct lruhash_entry* e;
struct query_info* k;
/** dump msg cache */
static int
-dump_msg_cache(SSL* ssl, struct worker* worker)
+dump_msg_cache(RES* ssl, struct worker* worker)
{
struct slabhash* sh = worker->env.msg_cache;
size_t slab;
}
int
-dump_cache(SSL* ssl, struct worker* worker)
+dump_cache(RES* ssl, struct worker* worker)
{
if(!dump_rrset_cache(ssl, worker))
return 0;
/** read a line from ssl into buffer */
static int
-ssl_read_buf(SSL* ssl, sldns_buffer* buf)
+ssl_read_buf(RES* ssl, sldns_buffer* buf)
{
return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
sldns_buffer_capacity(buf));
/** check fixed text on line */
static int
-read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
+read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
{
if(!ssl_read_buf(ssl, buf)) return 0;
return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
/** load an RR into rrset */
static int
-load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
+load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
unsigned int i, int is_rrsig, int* go_on, time_t now)
{
/** load an rrset entry */
static int
-load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
+load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
{
char* s = (char*)sldns_buffer_begin(buf);
struct regional* region = worker->scratchpad;
/** load rrset cache */
static int
-load_rrset_cache(SSL* ssl, struct worker* worker)
+load_rrset_cache(RES* ssl, struct worker* worker)
{
sldns_buffer* buf = worker->env.scratch_buffer;
if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
/** load a msg rrset reference */
static int
-load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
+load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
struct regional *region, struct ub_packed_rrset_key** rrset,
int* go_on)
{
/** load a msg entry */
static int
-load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
+load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
{
struct regional* region = worker->scratchpad;
struct query_info qinf;
/** load msg cache */
static int
-load_msg_cache(SSL* ssl, struct worker* worker)
+load_msg_cache(RES* ssl, struct worker* worker)
{
sldns_buffer* buf = worker->env.scratch_buffer;
if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
}
int
-load_cache(SSL* ssl, struct worker* worker)
+load_cache(RES* ssl, struct worker* worker)
{
if(!load_rrset_cache(ssl, worker))
return 0;
/** print details on a delegation point */
static void
-print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
+print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
{
char buf[257];
struct delegpt_addr* a;
/** print main dp info */
static void
-print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
+print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
{
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
return;
}
-int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
+int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
size_t nmlen, int ATTR_UNUSED(nmlabs))
{
/* deep links into the iterator module */
free(daemon->workers);
daemon->workers = NULL;
daemon->num = 0;
+ alloc_clear_special(&daemon->superalloc);
#ifdef USE_DNSTAP
dt_delete(daemon->dtenv);
+ daemon->dtenv = NULL;
#endif
#ifdef USE_DNSCRYPT
dnsc_delete(daemon->dnscenv);
+ daemon->dnscenv = NULL;
#endif
daemon->cfg = NULL;
}
#include "services/cache/infra.h"
#include "services/mesh.h"
#include "services/localzone.h"
+#include "services/authzone.h"
#include "util/storage/slabhash.h"
#include "util/fptr_wlist.h"
#include "util/data/dname.h"
#endif
}
-/*
- * The following function was generated using the openssl utility, using
- * the command : "openssl dhparam -C 2048"
- * (some openssl versions reject DH that is 'too small', eg. 512).
- */
-#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
-#ifndef S_SPLINT_S
-static DH *get_dh2048(void)
-{
- static unsigned char dh2048_p[]={
- 0xE7,0x36,0x28,0x3B,0xE4,0xC3,0x32,0x1C,0x01,0xC3,0x67,0xD6,
- 0xF5,0xF3,0xDA,0xDC,0x71,0xC0,0x42,0x8B,0xE6,0xEB,0x8D,0x80,
- 0x35,0x7F,0x09,0x45,0x30,0xE5,0xB2,0x92,0x81,0x3F,0x08,0xCD,
- 0x36,0x5E,0x19,0x83,0x62,0xCC,0xAE,0x9B,0x81,0x66,0x24,0xEE,
- 0x16,0x6F,0xA9,0x9E,0xF4,0x82,0x1B,0xDD,0x46,0xC7,0x33,0x5D,
- 0xF4,0xCA,0xE6,0x8F,0xFC,0xD4,0xD8,0x58,0x94,0x24,0x5D,0xFF,
- 0x0A,0xE8,0xEF,0x3D,0xCE,0xBB,0x50,0x94,0xE0,0x5F,0xE8,0x41,
- 0xC3,0x35,0x30,0x37,0xD5,0xCB,0x8F,0x3D,0x95,0x15,0x1A,0x77,
- 0x42,0xB2,0x06,0x86,0xF6,0x09,0x66,0x0E,0x9A,0x25,0x94,0x3E,
- 0xD2,0x04,0x25,0x25,0x1D,0x23,0xEB,0xDC,0x4D,0x0C,0x83,0x28,
- 0x2E,0x15,0x81,0x2D,0xC1,0xAF,0x8D,0x36,0x64,0xE3,0x9A,0x83,
- 0x78,0xC2,0x8D,0xC0,0x9D,0xD9,0x3A,0x1C,0xC5,0x2B,0x50,0x68,
- 0x07,0xA9,0x4B,0x8C,0x07,0x57,0xD6,0x15,0x03,0x4E,0x9E,0x01,
- 0xF2,0x6F,0x35,0xAC,0x26,0x9C,0x92,0x68,0x61,0x13,0xFB,0x01,
- 0xBA,0x22,0x36,0x01,0x55,0xB6,0x62,0xD9,0xB2,0x98,0xCE,0x5D,
- 0x4B,0xA5,0x41,0xD6,0xE5,0x70,0x78,0x12,0x1F,0x64,0xB6,0x6F,
- 0xB0,0x91,0x51,0x91,0x92,0xC0,0x94,0x3A,0xD1,0x28,0x4D,0x30,
- 0x84,0x3E,0xE4,0xE4,0x7F,0x47,0x89,0xB1,0xB6,0x8C,0x8E,0x0E,
- 0x26,0xDB,0xCD,0x17,0x07,0x2A,0x21,0x7A,0xCC,0x68,0xE8,0x57,
- 0x94,0x9E,0x59,0x61,0xEC,0x20,0x34,0x26,0x0D,0x66,0x44,0xEB,
- 0x6F,0x02,0x58,0xE2,0xED,0xF6,0xF3,0x1B,0xBF,0x9E,0x45,0x52,
- 0x5A,0x49,0xA1,0x5B,
- };
- static unsigned char dh2048_g[]={
- 0x02,
- };
- DH *dh = NULL;
- BIGNUM *p = NULL, *g = NULL;
-
- dh = DH_new();
- p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
- g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
- if (!dh || !p || !g)
- goto err;
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
- dh->p = p;
- dh->g = g;
-#else
- if (!DH_set0_pqg(dh, p, NULL, g))
- goto err;
-#endif
- return dh;
-err:
- if (p)
- BN_free(p);
- if (g)
- BN_free(g);
- if (dh)
- DH_free(dh);
- return NULL;
-}
-#endif /* SPLINT */
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
-
-struct daemon_remote*
-daemon_remote_create(struct config_file* cfg)
+static int
+remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
{
char* s_cert;
char* s_key;
- struct daemon_remote* rc = (struct daemon_remote*)calloc(1,
- sizeof(*rc));
- if(!rc) {
- log_err("out of memory in daemon_remote_create");
- return NULL;
- }
- rc->max_active = 10;
-
- if(!cfg->remote_control_enable) {
- rc->ctx = NULL;
- return rc;
- }
rc->ctx = SSL_CTX_new(SSLv23_server_method());
if(!rc->ctx) {
log_crypto_err("could not SSL_CTX_new");
- free(rc);
- return NULL;
+ return 0;
}
if(!listen_sslctx_setup(rc->ctx)) {
- daemon_remote_delete(rc);
- return NULL;
+ return 0;
}
- if (cfg->remote_control_use_cert == 0) {
- /* No certificates are requested */
-#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
- SSL_CTX_set_security_level(rc->ctx, 0);
-#endif
- if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL, eNULL")) {
- log_crypto_err("Failed to set aNULL cipher list");
- daemon_remote_delete(rc);
- return NULL;
- }
-
- /* in openssl 1.1, the securitylevel 0 allows eNULL, that
- * does not need the DH */
-#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
- /* Since we have no certificates and hence no source of
- * DH params, let's generate and set them
- */
- if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh2048())) {
- log_crypto_err("Wanted to set DH param, but failed");
- daemon_remote_delete(rc);
- return NULL;
- }
-#endif
- return rc;
- }
- rc->use_cert = 1;
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
if(!s_cert || !s_key) {
setup_error:
free(s_cert);
free(s_key);
- daemon_remote_delete(rc);
- return NULL;
+ return 0;
}
SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert));
SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL);
free(s_cert);
free(s_key);
+ return 1;
+}
+
+struct daemon_remote*
+daemon_remote_create(struct config_file* cfg)
+{
+ struct daemon_remote* rc = (struct daemon_remote*)calloc(1,
+ sizeof(*rc));
+ if(!rc) {
+ log_err("out of memory in daemon_remote_create");
+ return NULL;
+ }
+ rc->max_active = 10;
+ if(!cfg->remote_control_enable) {
+ rc->ctx = NULL;
+ return rc;
+ }
+ if(options_remote_is_address(cfg) && cfg->control_use_cert) {
+ if(!remote_setup_ctx(rc, cfg)) {
+ daemon_remote_delete(rc);
+ return NULL;
+ }
+ rc->use_cert = 1;
+ } else {
+ struct config_strlist* p;
+ rc->ctx = NULL;
+ rc->use_cert = 0;
+ if(!options_remote_is_address(cfg))
+ for(p = cfg->control_ifs.first; p; p = p->next) {
+ if(p->str && p->str[0] != '/')
+ log_warn("control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", p->str);
+ }
+ }
return rc;
}
{
struct listen_port* l = NULL;
log_assert(cfg->remote_control_enable && cfg->control_port);
- if(cfg->control_ifs) {
+ if(cfg->control_ifs.first) {
struct config_strlist* p;
- for(p = cfg->control_ifs; p; p = p->next) {
+ for(p = cfg->control_ifs.first; p; p = p->next) {
if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) {
listening_ports_free(l);
return NULL;
log_err("out of memory");
goto close_exit;
}
+ n->fd = newfd;
/* start in reading state */
n->c = comm_point_create_raw(rc->worker->base, newfd, 0,
&remote_control_callback, n);
comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT);
memcpy(&n->c->repinfo.addr, &addr, addrlen);
n->c->repinfo.addrlen = addrlen;
- n->shake_state = rc_hs_read;
- n->ssl = SSL_new(rc->ctx);
- if(!n->ssl) {
- log_crypto_err("could not SSL_new");
- comm_point_delete(n->c);
- free(n);
- goto close_exit;
- }
- SSL_set_accept_state(n->ssl);
- (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
- if(!SSL_set_fd(n->ssl, newfd)) {
- log_crypto_err("could not SSL_set_fd");
- SSL_free(n->ssl);
- comm_point_delete(n->c);
- free(n);
- goto close_exit;
+ if(rc->use_cert) {
+ n->shake_state = rc_hs_read;
+ n->ssl = SSL_new(rc->ctx);
+ if(!n->ssl) {
+ log_crypto_err("could not SSL_new");
+ comm_point_delete(n->c);
+ free(n);
+ goto close_exit;
+ }
+ SSL_set_accept_state(n->ssl);
+ (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
+ if(!SSL_set_fd(n->ssl, newfd)) {
+ log_crypto_err("could not SSL_set_fd");
+ SSL_free(n->ssl);
+ comm_point_delete(n->c);
+ free(n);
+ goto close_exit;
+ }
+ } else {
+ n->ssl = NULL;
}
n->rc = rc;
}
int
-ssl_print_text(SSL* ssl, const char* text)
+ssl_print_text(RES* res, const char* text)
{
int r;
- if(!ssl)
+ if(!res)
return 0;
- ERR_clear_error();
- if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) {
- if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
- verbose(VERB_QUERY, "warning, in SSL_write, peer "
- "closed connection");
+ if(res->ssl) {
+ ERR_clear_error();
+ if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) {
+ if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
+ verbose(VERB_QUERY, "warning, in SSL_write, peer "
+ "closed connection");
+ return 0;
+ }
+ log_crypto_err("could not SSL_write");
return 0;
}
- log_crypto_err("could not SSL_write");
- return 0;
+ } else {
+ size_t at = 0;
+ while(at < strlen(text)) {
+ ssize_t r = send(res->fd, text+at, strlen(text)-at, 0);
+ if(r == -1) {
+ if(errno == EAGAIN || errno == EINTR)
+ continue;
+#ifndef USE_WINSOCK
+ log_err("could not send: %s", strerror(errno));
+#else
+ log_err("could not send: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ return 0;
+ }
+ at += r;
+ }
}
return 1;
}
/** print text over the ssl connection */
static int
-ssl_print_vmsg(SSL* ssl, const char* format, va_list args)
+ssl_print_vmsg(RES* ssl, const char* format, va_list args)
{
char msg[1024];
vsnprintf(msg, sizeof(msg), format, args);
}
/** printf style printing to the ssl connection */
-int ssl_printf(SSL* ssl, const char* format, ...)
+int ssl_printf(RES* ssl, const char* format, ...)
{
va_list args;
int ret;
}
int
-ssl_read_line(SSL* ssl, char* buf, size_t max)
+ssl_read_line(RES* res, char* buf, size_t max)
{
int r;
size_t len = 0;
- if(!ssl)
+ if(!res)
return 0;
while(len < max) {
- ERR_clear_error();
- if((r=SSL_read(ssl, buf+len, 1)) <= 0) {
- if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
- buf[len] = 0;
- return 1;
+ if(res->ssl) {
+ ERR_clear_error();
+ if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) {
+ if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
+ buf[len] = 0;
+ return 1;
+ }
+ log_crypto_err("could not SSL_read");
+ return 0;
+ }
+ } else {
+ while(1) {
+ ssize_t rr = recv(res->fd, buf+len, 1, 0);
+ if(rr <= 0) {
+ if(rr == 0) {
+ buf[len] = 0;
+ return 1;
+ }
+ if(errno == EINTR || errno == EAGAIN)
+ continue;
+#ifndef USE_WINSOCK
+ log_err("could not recv: %s", strerror(errno));
+#else
+ log_err("could not recv: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ return 0;
+ }
+ break;
}
- log_crypto_err("could not SSL_read");
- return 0;
}
if(buf[len] == '\n') {
/* return string without \n */
}
/** send the OK to the control client */
-static void send_ok(SSL* ssl)
+static void send_ok(RES* ssl)
{
(void)ssl_printf(ssl, "ok\n");
}
/** do the stop command */
static void
-do_stop(SSL* ssl, struct daemon_remote* rc)
+do_stop(RES* ssl, struct daemon_remote* rc)
{
rc->worker->need_to_exit = 1;
comm_base_exit(rc->worker->base);
/** do the reload command */
static void
-do_reload(SSL* ssl, struct daemon_remote* rc)
+do_reload(RES* ssl, struct daemon_remote* rc)
{
rc->worker->need_to_exit = 0;
comm_base_exit(rc->worker->base);
/** do the verbosity command */
static void
-do_verbosity(SSL* ssl, char* str)
+do_verbosity(RES* ssl, char* str)
{
int val = atoi(str);
if(val == 0 && strcmp(str, "0") != 0) {
/** print stats from statinfo */
static int
-print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s)
+print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
{
struct timeval sumwait, avg;
if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm,
/** print stats for one thread */
static int
-print_thread_stats(SSL* ssl, int i, struct ub_stats_info* s)
+print_thread_stats(RES* ssl, int i, struct ub_stats_info* s)
{
char nm[32];
snprintf(nm, sizeof(nm), "thread%d", i);
/** print long number */
static int
-print_longnum(SSL* ssl, const char* desc, size_t x)
+print_longnum(RES* ssl, const char* desc, size_t x)
{
if(x > 1024*1024*1024) {
/* more than a Gb */
/** print mem stats */
static int
-print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
+print_mem(RES* ssl, struct worker* worker, struct daemon* daemon)
{
size_t msg, rrset, val, iter, respip;
#ifdef CLIENT_SUBNET
/** print uptime stats */
static int
-print_uptime(SSL* ssl, struct worker* worker, int reset)
+print_uptime(RES* ssl, struct worker* worker, int reset)
{
struct timeval now = *worker->env.now_tv;
struct timeval up, dt;
/** print extended histogram */
static int
-print_hist(SSL* ssl, struct ub_stats_info* s)
+print_hist(RES* ssl, struct ub_stats_info* s)
{
struct timehist* hist;
size_t i;
/** print extended stats */
static int
-print_ext(SSL* ssl, struct ub_stats_info* s)
+print_ext(RES* ssl, struct ub_stats_info* s)
{
int i;
char nm[16];
(unsigned long)s->svr.ans_bogus)) return 0;
if(!ssl_printf(ssl, "num.rrset.bogus"SQ"%lu\n",
(unsigned long)s->svr.rrset_bogus)) return 0;
+ if(!ssl_printf(ssl, "num.query.aggressive.NOERROR"SQ"%lu\n",
+ (unsigned long)s->svr.num_neg_cache_noerror)) return 0;
+ if(!ssl_printf(ssl, "num.query.aggressive.NXDOMAIN"SQ"%lu\n",
+ (unsigned long)s->svr.num_neg_cache_nxdomain)) return 0;
/* threat detection */
if(!ssl_printf(ssl, "unwanted.queries"SQ"%lu\n",
(unsigned long)s->svr.unwanted_queries)) return 0;
if(!ssl_printf(ssl, "num.query.dnscrypt.replay"SQ"%lu\n",
(unsigned long)s->svr.num_query_dnscrypt_replay)) return 0;
#endif /* USE_DNSCRYPT */
+ if(!ssl_printf(ssl, "num.query.authzone.up"SQ"%lu\n",
+ (unsigned long)s->svr.num_query_authzone_up)) return 0;
+ if(!ssl_printf(ssl, "num.query.authzone.down"SQ"%lu\n",
+ (unsigned long)s->svr.num_query_authzone_down)) return 0;
return 1;
}
/** do the stats command */
static void
-do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
+do_stats(RES* ssl, struct daemon_remote* rc, int reset)
{
struct daemon* daemon = rc->worker->daemon;
struct ub_stats_info total;
/** parse commandline argument domain name */
static int
-parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs)
+parse_arg_name(RES* ssl, char* str, uint8_t** res, size_t* len, int* labs)
{
uint8_t nm[LDNS_MAX_DOMAINLEN+1];
size_t nmlen = sizeof(nm);
/** find second argument, modifies string */
static int
-find_arg2(SSL* ssl, char* arg, char** arg2)
+find_arg2(RES* ssl, char* arg, char** arg2)
{
char* as = strchr(arg, ' ');
char* at = strchr(arg, '\t');
/** Add a new zone */
static int
-perform_zone_add(SSL* ssl, struct local_zones* zones, char* arg)
+perform_zone_add(RES* ssl, struct local_zones* zones, char* arg)
{
uint8_t* nm;
int nmlabs;
/** Do the local_zone command */
static void
-do_zone_add(SSL* ssl, struct local_zones* zones, char* arg)
+do_zone_add(RES* ssl, struct local_zones* zones, char* arg)
{
if(!perform_zone_add(ssl, zones, arg))
return;
/** Do the local_zones command */
static void
-do_zones_add(SSL* ssl, struct local_zones* zones)
+do_zones_add(RES* ssl, struct local_zones* zones)
{
char buf[2048];
int num = 0;
/** Remove a zone */
static int
-perform_zone_remove(SSL* ssl, struct local_zones* zones, char* arg)
+perform_zone_remove(RES* ssl, struct local_zones* zones, char* arg)
{
uint8_t* nm;
int nmlabs;
/** Do the local_zone_remove command */
static void
-do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg)
+do_zone_remove(RES* ssl, struct local_zones* zones, char* arg)
{
if(!perform_zone_remove(ssl, zones, arg))
return;
/** Do the local_zones_remove command */
static void
-do_zones_remove(SSL* ssl, struct local_zones* zones)
+do_zones_remove(RES* ssl, struct local_zones* zones)
{
char buf[2048];
int num = 0;
/** Add new RR data */
static int
-perform_data_add(SSL* ssl, struct local_zones* zones, char* arg)
+perform_data_add(RES* ssl, struct local_zones* zones, char* arg)
{
if(!local_zones_add_RR(zones, arg)) {
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
/** Do the local_data command */
static void
-do_data_add(SSL* ssl, struct local_zones* zones, char* arg)
+do_data_add(RES* ssl, struct local_zones* zones, char* arg)
{
if(!perform_data_add(ssl, zones, arg))
return;
/** Do the local_datas command */
static void
-do_datas_add(SSL* ssl, struct local_zones* zones)
+do_datas_add(RES* ssl, struct local_zones* zones)
{
char buf[2048];
int num = 0;
/** Remove RR data */
static int
-perform_data_remove(SSL* ssl, struct local_zones* zones, char* arg)
+perform_data_remove(RES* ssl, struct local_zones* zones, char* arg)
{
uint8_t* nm;
int nmlabs;
/** Do the local_data_remove command */
static void
-do_data_remove(SSL* ssl, struct local_zones* zones, char* arg)
+do_data_remove(RES* ssl, struct local_zones* zones, char* arg)
{
if(!perform_data_remove(ssl, zones, arg))
return;
/** Do the local_datas_remove command */
static void
-do_datas_remove(SSL* ssl, struct local_zones* zones)
+do_datas_remove(RES* ssl, struct local_zones* zones)
{
char buf[2048];
int num = 0;
/** Add a new zone to view */
static void
-do_view_zone_add(SSL* ssl, struct worker* worker, char* arg)
+do_view_zone_add(RES* ssl, struct worker* worker, char* arg)
{
char* arg2;
struct view* v;
/** Remove a zone from view */
static void
-do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg)
+do_view_zone_remove(RES* ssl, struct worker* worker, char* arg)
{
char* arg2;
struct view* v;
/** Add new RR data to view */
static void
-do_view_data_add(SSL* ssl, struct worker* worker, char* arg)
+do_view_data_add(RES* ssl, struct worker* worker, char* arg)
{
char* arg2;
struct view* v;
/** Remove RR data from view */
static void
-do_view_data_remove(SSL* ssl, struct worker* worker, char* arg)
+do_view_data_remove(RES* ssl, struct worker* worker, char* arg)
{
char* arg2;
struct view* v;
/** cache lookup of nameservers */
static void
-do_lookup(SSL* ssl, struct worker* worker, char* arg)
+do_lookup(RES* ssl, struct worker* worker, char* arg)
{
uint8_t* nm;
int nmlabs;
/** flush a type */
static void
-do_flush_type(SSL* ssl, struct worker* worker, char* arg)
+do_flush_type(RES* ssl, struct worker* worker, char* arg)
{
uint8_t* nm;
int nmlabs;
/** flush statistics */
static void
-do_flush_stats(SSL* ssl, struct worker* worker)
+do_flush_stats(RES* ssl, struct worker* worker)
{
worker_stats_clear(worker);
send_ok(ssl);
/** flush infra cache */
static void
-do_flush_infra(SSL* ssl, struct worker* worker, char* arg)
+do_flush_infra(RES* ssl, struct worker* worker, char* arg)
{
struct sockaddr_storage addr;
socklen_t len;
/** flush requestlist */
static void
-do_flush_requestlist(SSL* ssl, struct worker* worker)
+do_flush_requestlist(RES* ssl, struct worker* worker)
{
mesh_delete_all(worker->env.mesh);
send_ok(ssl);
struct reply_info* d = (struct reply_info*)e->data;
if(d->ttl > inf->expired) {
d->ttl = inf->expired;
+ d->prefetch_ttl = inf->expired;
inf->num_msgs++;
}
}
/** remove all rrsets and keys from zone from cache */
static void
-do_flush_zone(SSL* ssl, struct worker* worker, char* arg)
+do_flush_zone(RES* ssl, struct worker* worker, char* arg)
{
uint8_t* nm;
int nmlabs;
/** remove all bogus rrsets, msgs and keys from cache */
static void
-do_flush_bogus(SSL* ssl, struct worker* worker)
+do_flush_bogus(RES* ssl, struct worker* worker)
{
struct del_info inf;
/* what we do is to set them all expired */
/** remove all negative(NODATA,NXDOMAIN), and servfail messages from cache */
static void
-do_flush_negative(SSL* ssl, struct worker* worker)
+do_flush_negative(RES* ssl, struct worker* worker)
{
struct del_info inf;
/* what we do is to set them all expired */
/** remove name rrset from cache */
static void
-do_flush_name(SSL* ssl, struct worker* w, char* arg)
+do_flush_name(RES* ssl, struct worker* w, char* arg)
{
uint8_t* nm;
int nmlabs;
/** printout a delegation point info */
static int
-ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass,
+ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass,
struct delegpt* dp)
{
char buf[257];
/** print root forwards */
static int
-print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root)
+print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root)
{
struct delegpt* dp;
dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN);
/** parse args into delegpt */
static struct delegpt*
-parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
+parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names)
{
/* parse args and add in */
char* p = args;
struct delegpt* dp = delegpt_create_mlc(nm);
struct sockaddr_storage addr;
socklen_t addrlen;
+ char* auth_name;
if(!dp) {
(void)ssl_printf(ssl, "error out of memory\n");
return NULL;
p = skipwhite(p); /* position at next spot */
}
/* parse address */
- if(!extstrtoaddr(todo, &addr, &addrlen)) {
+ if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) {
if(allow_names) {
uint8_t* n = NULL;
size_t ln;
}
} else {
/* add address */
- if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
+ if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
+ auth_name)) {
(void)ssl_printf(ssl, "error out of memory\n");
delegpt_free_mlc(dp);
return NULL;
/** do the status command */
static void
-do_forward(SSL* ssl, struct worker* worker, char* args)
+do_forward(RES* ssl, struct worker* worker, char* args)
{
struct iter_forwards* fwd = worker->env.fwds;
uint8_t* root = (uint8_t*)"\000";
}
static int
-parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp,
+parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp,
int* insecure, int* prime)
{
char* zonename;
/** do the forward_add command */
static void
-do_forward_add(SSL* ssl, struct worker* worker, char* args)
+do_forward_add(RES* ssl, struct worker* worker, char* args)
{
struct iter_forwards* fwd = worker->env.fwds;
int insecure = 0;
/** do the forward_remove command */
static void
-do_forward_remove(SSL* ssl, struct worker* worker, char* args)
+do_forward_remove(RES* ssl, struct worker* worker, char* args)
{
struct iter_forwards* fwd = worker->env.fwds;
int insecure = 0;
/** do the stub_add command */
static void
-do_stub_add(SSL* ssl, struct worker* worker, char* args)
+do_stub_add(RES* ssl, struct worker* worker, char* args)
{
struct iter_forwards* fwd = worker->env.fwds;
int insecure = 0, prime = 0;
/** do the stub_remove command */
static void
-do_stub_remove(SSL* ssl, struct worker* worker, char* args)
+do_stub_remove(RES* ssl, struct worker* worker, char* args)
{
struct iter_forwards* fwd = worker->env.fwds;
int insecure = 0;
/** do the insecure_add command */
static void
-do_insecure_add(SSL* ssl, struct worker* worker, char* arg)
+do_insecure_add(RES* ssl, struct worker* worker, char* arg)
{
size_t nmlen;
int nmlabs;
/** do the insecure_remove command */
static void
-do_insecure_remove(SSL* ssl, struct worker* worker, char* arg)
+do_insecure_remove(RES* ssl, struct worker* worker, char* arg)
{
size_t nmlen;
int nmlabs;
}
static void
-do_insecure_list(SSL* ssl, struct worker* worker)
+do_insecure_list(RES* ssl, struct worker* worker)
{
char buf[257];
struct trust_anchor* a;
/** do the status command */
static void
-do_status(SSL* ssl, struct worker* worker)
+do_status(RES* ssl, struct worker* worker)
{
int i;
time_t uptime;
uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec;
if(!ssl_printf(ssl, "uptime: " ARG_LL "d seconds\n", (long long)uptime))
return;
- if(!ssl_printf(ssl, "options:%s%s\n" ,
+ if(!ssl_printf(ssl, "options:%s%s%s%s\n" ,
(worker->daemon->reuseport?" reuseport":""),
- (worker->daemon->rc->accept_list?" control(ssl)":"")))
+ (worker->daemon->rc->accept_list?" control":""),
+ (worker->daemon->rc->accept_list && worker->daemon->rc->use_cert?"(ssl)":""),
+ (worker->daemon->rc->accept_list && worker->daemon->cfg->control_ifs.first && worker->daemon->cfg->control_ifs.first->str && worker->daemon->cfg->control_ifs.first->str[0] == '/'?"(namedpipe)":"")
+ ))
return;
if(!ssl_printf(ssl, "unbound (pid %d) is running...\n",
(int)getpid()))
/** do the dump_requestlist command */
static void
-do_dump_requestlist(SSL* ssl, struct worker* worker)
+do_dump_requestlist(RES* ssl, struct worker* worker)
{
struct mesh_area* mesh;
struct mesh_state* m;
/** the infra cache */
struct infra_cache* infra;
/** the SSL connection */
- SSL* ssl;
+ RES* ssl;
/** the time now */
time_t now;
/** ssl failure? stop writing and skip the rest. If the tcp
/** do the dump_infra command */
static void
-do_dump_infra(SSL* ssl, struct worker* worker)
+do_dump_infra(RES* ssl, struct worker* worker)
{
struct infra_arg arg;
arg.infra = worker->env.infra_cache;
/** do the log_reopen command */
static void
-do_log_reopen(SSL* ssl, struct worker* worker)
+do_log_reopen(RES* ssl, struct worker* worker)
{
struct config_file* cfg = worker->env.cfg;
send_ok(ssl);
/** do the set_option command */
static void
-do_set_option(SSL* ssl, struct worker* worker, char* arg)
+do_set_option(RES* ssl, struct worker* worker, char* arg)
{
char* arg2;
if(!find_arg2(ssl, arg, &arg2))
/* routine to printout option values over SSL */
void remote_get_opt_ssl(char* line, void* arg)
{
- SSL* ssl = (SSL*)arg;
+ RES* ssl = (RES*)arg;
(void)ssl_printf(ssl, "%s\n", line);
}
/** do the get_option command */
static void
-do_get_option(SSL* ssl, struct worker* worker, char* arg)
+do_get_option(RES* ssl, struct worker* worker, char* arg)
{
int r;
r = config_get_option(worker->env.cfg, arg, remote_get_opt_ssl, ssl);
/** do the list_forwards command */
static void
-do_list_forwards(SSL* ssl, struct worker* worker)
+do_list_forwards(RES* ssl, struct worker* worker)
{
/* since its a per-worker structure no locks needed */
struct iter_forwards* fwds = worker->env.fwds;
/** do the list_stubs command */
static void
-do_list_stubs(SSL* ssl, struct worker* worker)
+do_list_stubs(RES* ssl, struct worker* worker)
{
struct iter_hints_stub* z;
struct trust_anchor* a;
}
}
+/** do the list_auth_zones command */
+static void
+do_list_auth_zones(RES* ssl, struct auth_zones* az)
+{
+ struct auth_zone* z;
+ char buf[257], buf2[256];
+ lock_rw_rdlock(&az->lock);
+ RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
+ lock_rw_rdlock(&z->lock);
+ dname_str(z->name, buf);
+ if(z->zone_expired)
+ snprintf(buf2, sizeof(buf2), "expired");
+ else {
+ uint32_t serial = 0;
+ if(auth_zone_get_serial(z, &serial))
+ snprintf(buf2, sizeof(buf2), "serial %u",
+ (unsigned)serial);
+ else snprintf(buf2, sizeof(buf2), "no serial");
+ }
+ if(!ssl_printf(ssl, "%s\t%s\n", buf, buf2)) {
+ /* failure to print */
+ lock_rw_unlock(&z->lock);
+ lock_rw_unlock(&az->lock);
+ return;
+ }
+ lock_rw_unlock(&z->lock);
+ }
+ lock_rw_unlock(&az->lock);
+}
+
/** do the list_local_zones command */
static void
-do_list_local_zones(SSL* ssl, struct local_zones* zones)
+do_list_local_zones(RES* ssl, struct local_zones* zones)
{
struct local_zone* z;
char buf[257];
/** do the list_local_data command */
static void
-do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones)
+do_list_local_data(RES* ssl, struct worker* worker, struct local_zones* zones)
{
struct local_zone* z;
struct local_data* d;
/** do the view_list_local_zones command */
static void
-do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg)
+do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg)
{
struct view* v = views_find_view(worker->daemon->views,
arg, 0 /* get read lock*/);
/** do the view_list_local_data command */
static void
-do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg)
+do_view_list_local_data(RES* ssl, struct worker* worker, char* arg)
{
struct view* v = views_find_view(worker->daemon->views,
arg, 0 /* get read lock*/);
/** the infra cache */
struct infra_cache* infra;
/** the SSL to print to */
- SSL* ssl;
+ RES* ssl;
/** all or only ratelimited */
int all;
/** current time */
/** do the ratelimit_list command */
static void
-do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
+do_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
{
struct ratelimit_list_arg a;
a.all = 0;
/** do the ip_ratelimit_list command */
static void
-do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
+do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
{
struct ip_ratelimit_list_arg a;
a.all = 0;
/** tell other processes to execute the command */
static void
-distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
+distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
{
int i;
if(!cmd || !ssl)
/** execute a remote control command */
static void
-execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
+execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
struct worker* worker)
{
char* p = skipwhite(cmd);
} else if(cmdcmp(p, "ip_ratelimit_list", 17)) {
do_ip_ratelimit_list(ssl, worker, p+17);
return;
+ } else if(cmdcmp(p, "list_auth_zones", 15)) {
+ do_list_auth_zones(ssl, worker->env.auth_zones);
+ return;
} else if(cmdcmp(p, "stub_add", 8)) {
/* must always distribute this cmd */
if(rc) distribute_cmd(rc, ssl, cmd);
/** handle remote control request */
static void
-handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
+handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
{
int r;
char pre[10];
fd_set_block(s->c->fd);
/* try to read magic UBCT[version]_space_ string */
- ERR_clear_error();
- if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) {
- if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN)
+ if(res->ssl) {
+ ERR_clear_error();
+ if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) {
+ if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN)
+ return;
+ log_crypto_err("could not SSL_read");
return;
- log_crypto_err("could not SSL_read");
- return;
+ }
+ } else {
+ while(1) {
+ ssize_t rr = recv(res->fd, magic, sizeof(magic)-1, 0);
+ if(rr <= 0) {
+ if(rr == 0) return;
+ if(errno == EINTR || errno == EAGAIN)
+ continue;
+#ifndef USE_WINSOCK
+ log_err("could not recv: %s", strerror(errno));
+#else
+ log_err("could not recv: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ return;
+ }
+ r = (int)rr;
+ break;
+ }
}
magic[6] = 0;
if( r != 6 || strncmp(magic, "UBCT", 4) != 0) {
}
/* read the command line */
- if(!ssl_read_line(ssl, buf, sizeof(buf))) {
+ if(!ssl_read_line(res, buf, sizeof(buf))) {
return;
}
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
if(strcmp(magic, pre) != 0) {
verbose(VERB_QUERY, "control connection had bad "
"version %s, cmd: %s", magic, buf);
- ssl_printf(ssl, "error version mismatch\n");
+ ssl_printf(res, "error version mismatch\n");
return;
}
verbose(VERB_DETAIL, "control cmd: %s", buf);
/* figure out what to do */
- execute_cmd(rc, ssl, buf, rc->worker);
+ execute_cmd(rc, res, buf, rc->worker);
+}
+
+/** handle SSL_do_handshake changes to the file descriptor to wait for later */
+static int
+remote_handshake_later(struct daemon_remote* rc, struct rc_state* s,
+ struct comm_point* c, int r, int r2)
+{
+ if(r2 == SSL_ERROR_WANT_READ) {
+ if(s->shake_state == rc_hs_read) {
+ /* try again later */
+ return 0;
+ }
+ s->shake_state = rc_hs_read;
+ comm_point_listen_for_rw(c, 1, 0);
+ return 0;
+ } else if(r2 == SSL_ERROR_WANT_WRITE) {
+ if(s->shake_state == rc_hs_write) {
+ /* try again later */
+ return 0;
+ }
+ s->shake_state = rc_hs_write;
+ comm_point_listen_for_rw(c, 0, 1);
+ return 0;
+ } else {
+ if(r == 0)
+ log_err("remote control connection closed prematurely");
+ log_addr(1, "failed connection from",
+ &s->c->repinfo.addr, s->c->repinfo.addrlen);
+ log_crypto_err("remote control failed ssl");
+ clean_point(rc, s);
+ }
+ return 0;
}
int remote_control_callback(struct comm_point* c, void* arg, int err,
struct comm_reply* ATTR_UNUSED(rep))
{
+ RES res;
struct rc_state* s = (struct rc_state*)arg;
struct daemon_remote* rc = s->rc;
int r;
clean_point(rc, s);
return 0;
}
- /* (continue to) setup the SSL connection */
- ERR_clear_error();
- r = SSL_do_handshake(s->ssl);
- if(r != 1) {
- int r2 = SSL_get_error(s->ssl, r);
- if(r2 == SSL_ERROR_WANT_READ) {
- if(s->shake_state == rc_hs_read) {
- /* try again later */
- return 0;
- }
- s->shake_state = rc_hs_read;
- comm_point_listen_for_rw(c, 1, 0);
- return 0;
- } else if(r2 == SSL_ERROR_WANT_WRITE) {
- if(s->shake_state == rc_hs_write) {
- /* try again later */
- return 0;
- }
- s->shake_state = rc_hs_write;
- comm_point_listen_for_rw(c, 0, 1);
- return 0;
- } else {
- if(r == 0)
- log_err("remote control connection closed prematurely");
- log_addr(1, "failed connection from",
- &s->c->repinfo.addr, s->c->repinfo.addrlen);
- log_crypto_err("remote control failed ssl");
- clean_point(rc, s);
- return 0;
+ if(s->ssl) {
+ /* (continue to) setup the SSL connection */
+ ERR_clear_error();
+ r = SSL_do_handshake(s->ssl);
+ if(r != 1) {
+ int r2 = SSL_get_error(s->ssl, r);
+ return remote_handshake_later(rc, s, c, r, r2);
}
+ s->shake_state = rc_none;
}
- s->shake_state = rc_none;
/* once handshake has completed, check authentication */
if (!rc->use_cert) {
}
/* if OK start to actually handle the request */
- handle_req(rc, s, s->ssl);
+ res.ssl = s->ssl;
+ res.fd = c->fd;
+ handle_req(rc, s, &res);
verbose(VERB_ALGO, "remote control operation completed");
clean_point(rc, s);
/** the ssl state */
SSL* ssl;
#endif
+ /** file descriptor */
+ int fd;
/** the rc this is part of */
struct daemon_remote* rc;
};
#endif
};
+/**
+ * Connection to print to, either SSL or plain over fd
+ */
+struct remote_stream {
+#ifdef HAVE_SSL
+ /** SSL structure, nonNULL if using SSL */
+ SSL* ssl;
+#endif
+ /** file descriptor for plain transfer */
+ int fd;
+};
+typedef struct remote_stream RES;
+
/**
* Create new remote control state for the daemon.
* @param cfg: config file with key file settings.
* @param text: the text.
* @return false on connection failure.
*/
-int ssl_print_text(SSL* ssl, const char* text);
+int ssl_print_text(RES* ssl, const char* text);
/**
* printf style printing to the ssl connection
- * @param ssl: the SSL connection to print to. Blocking.
+ * @param ssl: the RES connection to print to. Blocking.
* @param format: printf style format string.
* @return success or false on a network failure.
*/
-int ssl_printf(SSL* ssl, const char* format, ...)
+int ssl_printf(RES* ssl, const char* format, ...)
ATTR_FORMAT(printf, 2, 3);
/**
* Read until \n is encountered
- * If SSL signals EOF, the string up to then is returned (without \n).
- * @param ssl: the SSL connection to read from. blocking.
+ * If stream signals EOF, the string up to then is returned (without \n).
+ * @param ssl: the RES connection to read from. blocking.
* @param buf: buffer to read to.
* @param max: size of buffer.
* @return false on connection failure.
*/
-int ssl_read_line(SSL* ssl, char* buf, size_t max);
+int ssl_read_line(RES* ssl, char* buf, size_t max);
#endif /* HAVE_SSL */
#endif /* DAEMON_REMOTE_H */
#include "sldns/sbuffer.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
+#include "services/authzone.h"
#include "validator/val_kcache.h"
+#include "validator/val_neg.h"
/** add timers and the values do not overflow or become negative */
static void
(unsigned)worker->env.mesh->stats_jostled);
}
+/** Set the neg cache stats. */
+static void
+set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr,
+ int reset)
+{
+ int m = modstack_find(&worker->env.mesh->mods, "validator");
+ struct val_env* ve;
+ struct val_neg_cache* neg;
+ if(m == -1)
+ return;
+ ve = (struct val_env*)worker->env.modinfo[m];
+ if(!ve->neg_cache)
+ return;
+ neg = ve->neg_cache;
+ lock_basic_lock(&neg->lock);
+ svr->num_neg_cache_noerror = (long long)neg->num_neg_cache_noerror;
+ svr->num_neg_cache_nxdomain = (long long)neg->num_neg_cache_nxdomain;
+ if(reset && !worker->env.cfg->stat_cumulative) {
+ neg->num_neg_cache_noerror = 0;
+ neg->num_neg_cache_nxdomain = 0;
+ }
+ lock_basic_unlock(&neg->lock);
+}
+
/** get rrsets bogus number from validator */
static size_t
get_rrset_bogus(struct worker* worker, int reset)
s->svr.nonce_cache_count = 0;
s->svr.num_query_dnscrypt_replay = 0;
#endif /* USE_DNSCRYPT */
+ if(worker->env.auth_zones) {
+ if(reset && !worker->env.cfg->stat_cumulative) {
+ lock_rw_wrlock(&worker->env.auth_zones->lock);
+ } else {
+ lock_rw_rdlock(&worker->env.auth_zones->lock);
+ }
+ s->svr.num_query_authzone_up = (long long)worker->env.
+ auth_zones->num_query_up;
+ s->svr.num_query_authzone_down = (long long)worker->env.
+ auth_zones->num_query_down;
+ if(reset && !worker->env.cfg->stat_cumulative) {
+ worker->env.auth_zones->num_query_up = 0;
+ worker->env.auth_zones->num_query_down = 0;
+ }
+ lock_rw_unlock(&worker->env.auth_zones->lock);
+ }
+
+ /* Set neg cache usage numbers */
+ set_neg_cache_stats(worker, &s->svr, reset);
/* get tcp accept usage */
s->svr.tcp_accept_usage = 0;
fatal_exit("could not set up listen SSL_CTX");
}
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
- cfg->tls_cert_bundle)))
+ cfg->tls_cert_bundle, cfg->tls_win_cert)))
fatal_exit("could not set up connect SSL_CTX");
#endif
verbose(VERB_QUERY, "request bad, has TC bit on");
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
}
- if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
+ if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY &&
+ LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY) {
verbose(VERB_QUERY, "request unknown opcode %d",
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL);
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
}
- if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) {
+ if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 &&
+ (LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 1 ||
+ LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) {
verbose(VERB_QUERY, "request wrong nr an=%d",
LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
* let validator do that */
return 0;
case sec_status_bogus:
+ case sec_status_secure_sentinel_fail:
/* some rrsets are bogus, reply servfail */
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
}
}
/* check security status of the cached answer */
- if( rep->security == sec_status_bogus && must_validate) {
+ if(must_validate && (rep->security == sec_status_bogus ||
+ rep->security == sec_status_secure_sentinel_fail)) {
/* BAD cached */
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
return 0;
}
+/**
+ * Answer notify queries. These are notifies for authoritative zones,
+ * the reply is an ack that the notify has been received. We need to check
+ * access permission here.
+ * @param w: worker
+ * @param qinfo: query info. Pointer into packet buffer.
+ * @param edns: edns info from query.
+ * @param repinfo: reply info with source address.
+ * @param pkt: packet buffer.
+ */
+static void
+answer_notify(struct worker* w, struct query_info* qinfo,
+ struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo)
+{
+ int refused = 0;
+ int rcode = LDNS_RCODE_NOERROR;
+ uint32_t serial = 0;
+ int has_serial;
+ if(!w->env.auth_zones) return;
+ has_serial = auth_zone_parse_notify_serial(pkt, &serial);
+ if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
+ qinfo->qname_len, qinfo->qclass, &repinfo->addr,
+ repinfo->addrlen, has_serial, serial, &refused)) {
+ rcode = LDNS_RCODE_NOERROR;
+ } else {
+ if(refused)
+ rcode = LDNS_RCODE_REFUSED;
+ else rcode = LDNS_RCODE_SERVFAIL;
+ }
+
+ if(verbosity >= VERB_DETAIL) {
+ char buf[380];
+ char zname[255+1];
+ char sr[25];
+ dname_str(qinfo->qname, zname);
+ sr[0]=0;
+ if(has_serial)
+ snprintf(sr, sizeof(sr), "serial %u ",
+ (unsigned)serial);
+ if(rcode == LDNS_RCODE_REFUSED)
+ snprintf(buf, sizeof(buf),
+ "refused NOTIFY %sfor %s from", sr, zname);
+ else if(rcode == LDNS_RCODE_SERVFAIL)
+ snprintf(buf, sizeof(buf),
+ "servfail for NOTIFY %sfor %s from", sr, zname);
+ else snprintf(buf, sizeof(buf),
+ "received NOTIFY %sfor %s from", sr, zname);
+ log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen);
+ }
+ edns->edns_version = EDNS_ADVERTISED_VERSION;
+ edns->udp_size = EDNS_ADVERTISED_SIZE;
+ edns->ext_rcode = 0;
+ edns->bits &= EDNS_DO;
+ edns->opt_list = NULL;
+ error_encode(pkt, rcode, qinfo,
+ *(uint16_t*)(void *)sldns_buffer_begin(pkt),
+ sldns_buffer_read_u16_at(pkt, 2), edns);
+ LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
+}
+
static int
deny_refuse(struct comm_point* c, enum acl_access acl,
enum acl_access deny, enum acl_access refuse,
regional_free_all(worker->scratchpad);
goto send_reply;
}
+ if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
+ LDNS_PACKET_NOTIFY) {
+ answer_notify(worker, &qinfo, &edns, c->buffer, repinfo);
+ regional_free_all(worker->scratchpad);
+ goto send_reply;
+ }
if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo,
&edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist,
acladdr->taglen, acladdr->tag_actions,
return ret;
}
+ /* If this request does not have the recursion bit set, verify
+ * ACLs allow the recursion bit to be treated as set. */
+ if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
+ acl == acl_allow_setrd ) {
+ LDNS_RD_SET(sldns_buffer_begin(c->buffer));
+ }
+
/* If this request does not have the recursion bit set, verify
* ACLs allow the snooping. */
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
- struct module_qstate* q)
+ char* tls_auth_name, struct module_qstate* q)
{
struct worker* worker = q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
e->qstate = q;
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
want_dnssec, nocaps, q->env->cfg->tcp_upstream,
- ssl_upstream, addr, addrlen, zone, zonelen, q,
+ ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
if(!e->qsent) {
return NULL;
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
- int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
+ int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
+ struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
return 0;
+19 June 2018: Wouter
+ - Fix for unbound-control on Windows and set TCP socket parameters
+ more closely.
+ - Fix windows unbound-control no cert bad file descriptor error.
+
+18 June 2018: Wouter
+ - Fix that control-use-cert: no works for 127.0.0.1 to disable certs.
+ - Fix unbound-checkconf for control-use-cert.
+
+15 June 2018: Wouter
+ - tag for 1.7.3rc1.
+
+14 June 2018: Wouter
+ - #4103: Fix that auth-zone does not insist on SOA record first in
+ file for url downloads.
+ - Fix that first control-interface determines if TLS is used. Warn
+ when IP address interfaces are used without TLS.
+ - Fix nettle compile.
+
+12 June 2018: Ralph
+ - Don't count CNAME response types received during qname minimisation as
+ query restart.
+
+12 June 2018: Wouter
+ - #4102 for NSD, but for Unbound. Named unix pipes do not use
+ certificate and key files, access can be restricted with file and
+ directory permissions. The option control-use-cert is no longer
+ used, and ignored if found in unbound.conf.
+ - Rename tls-additional-ports to tls-additional-port, because every
+ line adds one port.
+ - Fix buffer size warning in unit test.
+ - remade dependencies in the Makefile.
+
+6 June 2018: Wouter
+ - Patch to fix openwrt for mac os build darwin detection in configure.
+
+5 June 2018: Wouter
+ - Fix crash if ratelimit taken into use with unbound-control
+ instead of with unbound.conf.
+
+4 June 2018: Wouter
+ - Fix deadlock caused by incoming notify for auth-zone.
+ - tag for 1.7.2rc1, became 1.7.2 release on 11 June 2018,
+ trunk is 1.7.3 in development from this point.
+ - #4100: Fix stub reprime when it becomes useless.
+
+1 June 2018: Wouter
+ - Rename additional-tls-port to tls-additional-ports.
+ The older name is accepted for backwards compatibility.
+
+30 May 2018: Wouter
+ - Patch from Syzdek: Add ability to ignore RD bit and treat all
+ requests as if the RD bit is set.
+
+29 May 2018: Wouter
+ - in compat/arc4random call getentropy_urandom when getentropy fails
+ with ENOSYS.
+ - Fix that fallback for windows port.
+
+28 May 2018: Wouter
+ - Fix windows tcp and tls spin on events.
+ - Add routine from getdns to add windows cert store to the SSL_CTX.
+ - tls-win-cert option that adds the system certificate store for
+ authenticating DNS-over-TLS connections. It can be used instead
+ of the tls-cert-bundle option, or with it to add certificates.
+
+25 May 2018: Wouter
+ - For TCP and TLS connections that don't establish, perform address
+ update in infra cache, so future selections can exclude them.
+ - Fix that tcp sticky events are removed for closed fd on windows.
+ - Fix close events for tcp only.
+
+24 May 2018: Wouter
+ - Fix that libunbound can do DNS-over-TLS, when configured.
+ - Fix that windows unbound service can use DNS-over-TLS.
+ - unbound-host initializes ssl (for potential DNS-over-TLS usage
+ inside libunbound), when ssl upstream or a cert-bundle is configured.
+
+23 May 2018: Wouter
+ - Use accept4 to speed up incoming TCP (and TLS) connections,
+ available on Linux, FreeBSD and OpenBSD.
+
+17 May 2018: Ralph
+ - Qname minimisation default changed to yes.
+
+15 May 2018: Wouter
+ - Fix low-rtt-pct to low-rtt-permil, as it is parts in one thousand.
+
+11 May 2018: Wouter
+ - Fix contrib/libunbound.pc for libssl libcrypto references,
+ from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=226914
+
+7 May 2018: Wouter
+ - Fix windows to not have sticky TLS events for TCP.
+ - Fix read of DNS over TLS length and data in one read call.
+ - Fix mesh state assertion failure due to callback removal.
+
+3 May 2018: Wouter
+ - Fix that configure --with-libhiredis also turns on cachedb.
+ - Fix gcc 8 buffer warning in testcode.
+ - Fix function type cast warning in libunbound context callback type.
+
+2 May 2018: Wouter
+ - Fix fail to reject dead peers in forward-zone, with ssl-upstream.
+
+1 May 2018: Wouter
+ - Fix that unbound-control reload frees the rrset keys and returns
+ the memory pages to the system.
+
+30 April 2018: Wouter
+ - Fix spelling error in man page and note defaults as no instead of
+ off.
+
+26 April 2018: Wouter
+ - Fix for crash in daemon_cleanup with dnstap during reload,
+ from Saksham Manchanda.
+ - Also that for dnscrypt.
+ - tag for 1.7.1rc1 release. Became 1.7.1 release on 3 May, trunk
+ is from here 1.7.2 in development.
+
+25 April 2018: Ralph
+ - Fix memory leak when caching wildcard records for aggressive NSEC use
+
+24 April 2018: Wouter
+ - Fix contrib/fastrpz.patch for this release.
+ - Fix auth https for libev.
+
+24 April 2018: Ralph
+ - Added root-key-sentinel support
+
+23 April 2018: Wouter
+ - makedist uses bz2 for expat code, instead of tar.gz.
+ - Fix #4092: libunbound: use-caps-for-id lacks colon in
+ config_set_option.
+ - auth zone http download stores exact copy of downloaded file,
+ including comments in the file.
+ - Fix sldns parse failure for CDS alternate delete syntax empty hex.
+ - Attempt for auth zone fix; add of callback in mesh gets from
+ callback does not skip callback of result.
+ - Fix cname classification with qname minimisation enabled.
+ - list_auth_zones unbound-control command.
+
+20 April 2018: Wouter
+ - man page documentation for dns-over-tls forward-addr '#' notation.
+ - removed free from failed parse case.
+ - Fix #4091: Fix that reload of auth-zone does not merge the zonefile
+ with the previous contents.
+ - Delete auth zone when removed from config.
+
+19 April 2018: Wouter
+ - Can set tls authentication with forward-addr: IP#tls.auth.name
+ And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem".
+ such as forward-addr: 9.9.9.9@853#dns.quad9.net or
+ 1.1.1.1@853#cloudflare-dns.com
+ - Fix #658: unbound using TLS in a forwarding configuration does not
+ verify the server's certificate (RFC 8310 support).
+ - For addr with #authname and no @port notation, the default is 853.
+
+18 April 2018: Wouter
+ - Fix auth-zone retry timer to be on schedule with retry timeout,
+ with backoff. Also time a refresh at the zone expiry.
+
+17 April 2018: Wouter
+ - auth zone notify work.
+ - allow-notify: config statement for auth-zones.
+ - unit test for allow-notify
+
+16 April 2018: Wouter
+ - Fix auth zone target lookup iterator.
+ - auth zone notify with prefix
+ - auth zone notify work.
+
+13 April 2018: Wouter
+ - Fix for max include depth for authzones.
+ - Fix memory free on fail for $INCLUDE in authzone.
+ - Fix that an internal error to look up the wrong rr type for
+ auth zone gets stopped, before trying to send there.
+ - auth zone notify work.
+
+10 April 2018: Ralph
+ - num.query.aggressive.NOERROR and num.query.aggressive.NXDOMAIN
+ statistics counters.
+
+10 April 2018: Wouter
+ - documentation for low-rtt and low-rtt-pct.
+ - auth zone notify work.
+
+9 April 2018: Wouter
+ - Fix that flush_zone sets prefetch ttl expired, so that with
+ serve-expired enabled it'll start prefetching those entries.
+ - num.query.authzone.up and num.query.authzone.down statistics counters.
+ - Fix downstream auth zone, only fallback when auth zone fails to
+ answer and fallback is enabled.
+ - Accept both option names with and without colon for get_option
+ and set_option.
+ - low-rtt and low-rtt-pct in unbound.conf enable the server selection
+ of fast servers for some percentage of the time.
+
+5 April 2018: Wouter
+ - Combine write of tcp length and tcp query for dns over tls.
+ - nitpick fixes in example.conf.
+ - Fix above stub queries for type NS and useless delegation point.
+ - Fix unbound-control over pipe with openssl 1.1.1, the TLSv1.3
+ tls_choose_sigalg routine does not allow the ciphers for the pipe,
+ so use TLSv1.2.
+ - ED448 support.
+
+3 April 2018: Wouter
+ - Fix #4043: make test fails due to v6 presentation issue in macOS.
+ - Fix unable to resolve after new WLAN connection, due to auth-zone
+ failing with a forwarder set. Now, auth-zone is only used for
+ answers (not referrals) when a forwarder is set.
+
+29 March 2018: Ralph
+ - Check "result" in dup_all(), by Florian Obser.
+
+23 March 2018: Ralph
+ - Fix unbound-control get_option aggressive-nsec
+
+21 March 2018: Ralph
+ - Do not use cached NSEC records to generate negative answers for
+ domains under DNSSEC Negative Trust Anchors.
+
+19 March 2018: Wouter
+ - iana port update.
+
+16 March 2018: Wouter
+ - corrected a minor typo in the changelog.
+ - move htobe64/be64toh portability code to cachedb.c.
+
+15 March 2018: Wouter
+ - Add --with-libhiredis, unbound support for a new cachedb backend
+ that uses a Redis server as the storage. This implementation
+ depends on the hiredis client library (https://redislabs.com/lp/hiredis/).
+ And unbound should be built with both --enable-cachedb and
+ --with-libhiredis[=PATH] (where $PATH/include/hiredis/hiredis.h
+ should exist). Patch from Jinmei Tatuya (Infoblox).
+ - Fix #3817: core dump happens in libunbound delete, when queued
+ servfail hits deleted message queue.
+ - Create additional tls service interfaces by opening them on other
+ portnumbers and listing the portnumbers as additional-tls-port: nr.
+
+13 March 2018: Wouter
+ - Fix typo in documentation.
+ - Fix #3736: Fix 0 TTL domains stuck on SERVFAIL unless manually
+ flushed with serve-expired on.
+
12 March 2018: Wouter
- Added documentation for aggressive-nsec: yes.
- - tag 1.7.0rc3.
+ - tag 1.7.0rc3. That became the 1.7.0 release on 15 Mar, trunk
+ now has 1.7.1 in development.
+ - Fix #3727: Protocol name is TLS, options have been renamed but
+ documentation is not consistent.
+ - Check IXFR start serial.
9 March 2018: Wouter
- Fix #3598: Fix swig build issue on rhel6 based system.
-README for Unbound 1.7.0
+README for Unbound 1.7.3
Copyright 2007 NLnet Labs
http://unbound.net
#
# Example configuration file.
#
-# See unbound.conf(5) man page, version 1.7.0.
+# See unbound.conf(5) man page, version 1.7.3.
#
# this is a comment.
# upstream connections use TCP only (and no UDP), "yes" or "no"
# useful for tunneling scenarios, default no.
# tcp-upstream: no
-
+
# upstream connections also use UDP (even if do-udp is no).
# useful if if you want UDP upstream, but don't provide UDP downstream.
# udp-upstream-without-downstream: no
# to this server. Specify classless netblocks with /size and action.
# By default everything is refused, except for localhost.
# Choose deny (drop message), refuse (polite error reply),
- # allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
+ # allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),
+ # allow_snoop (recursive and nonrecursive ok)
# deny_non_local (drop queries unless can be answered from local-data)
# refuse_non_local (like deny_non_local but polite error reply).
# access-control: 0.0.0.0/0 refuse
# enable to not answer version.server and version.bind queries.
# hide-version: no
-
+
# enable to not answer trustanchor.unbound queries.
# hide-trustanchor: no
# Sent minimum amount of information to upstream servers to enhance
# privacy. Only sent minimum required labels of the QNAME and set QTYPE
# to A when possible.
- # qname-minimisation: no
+ # qname-minimisation: yes
# QNAME minimisation in strict mode. Do not fall-back to sending full
# QNAME to potentially broken nameservers. A lot of domains will not be
# trust anchor signaling sends a RFC8145 key tag query after priming.
# trust-anchor-signaling: no
+ # Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
+ # root-key-sentinel: yes
+
# File with DLV trusted keys. Same format as trust-anchor-file.
# There can be only one DLV configured, it is trusted from root down.
# DLV is going to be decommissioned. Please do not use it any more.
# o inform acts like transparent, but logs client IP address
# 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.
+ # 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
# 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.
# 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.
# tls-upstream: no
# Certificates used to authenticate connections made upstream.
# tls-cert-bundle: ""
+ # Add system certs to the cert bundle, from the Windows Cert Store
+ # tls-win-cert: no
+
+ # Also serve tls on these port numbers (eg. 443, ...), by listing
+ # tls-additional-port: portno for each of the port numbers.
+
# DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
# dns64-prefix: 64:ff9b::0/96
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
# ip-ratelimit-factor: 10
+ # what is considered a low rtt (ping time for upstream server), in msec
+ # low-rtt: 45
+ # select low rtt this many times out of 1000. 0 means the fast server
+ # select is disabled. prefetches are not sped up.
+ # low-rtt-permil: 0
+
# Specific options for ipsecmod. unbound needs to be configured with
# --enable-ipsecmod for these to take effect.
#
# set up the keys and certificates with unbound-control-setup.
# control-enable: no
- # Set to no and use an absolute path as control-interface to use
- # a unix local named pipe for unbound-control.
- # control-use-cert: yes
-
# what interfaces are listened to for remote control.
# give 0.0.0.0 and ::0 to listen to all interfaces.
+ # set to an absolute path to use a unix local name pipe, certificates
+ # are not used for that, so key and cert files need not be present.
# control-interface: 127.0.0.1
# control-interface: ::1
# port number for remote control operations.
# control-port: 8953
+ # for localhost, you can disable use of TLS by setting this to "no"
+ # For local sockets this option is ignored, and TLS is not used.
+ # control-use-cert: "yes"
+
# unbound server key file.
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
# has a copy of the root for local usage. The second serves example.org
# authoritatively. zonefile: reads from file (and writes to it if you also
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
+# With allow-notify: you can give additional (apart from masters) sources of
+# notifies.
# auth-zone:
# name: "."
# for-downstream: no
# name: "viewname"
# local-zone: "example.com" redirect
# local-data: "example.com A 192.0.2.3"
-# local-data-ptr: "192.0.2.3 www.example.com"
+# local-data-ptr: "192.0.2.3 www.example.com"
# view-first: no
# view:
# name: "anotherview"
# backend: "testframe"
# # secret seed string to calculate hashed keys
# secret-seed: "default"
+#
+# # For "redis" backend:
+# # redis server's IP address or host name
+# redis-server-host: 127.0.0.1
+# # redis server's TCP port
+# redis-server-port: 6379
+# # timeout (in ms) for communication with the redis server
+# redis-timeout: 100
-.TH "libunbound" "3" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "libunbound" "3" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.7.0 functions.
+\- Unbound DNS validating resolver 1.7.3 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
-.TH "unbound-anchor" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "unbound-anchor" "8" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
-.TH "unbound-checkconf" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "unbound-checkconf" "8" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
-.TH "unbound-control" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "unbound-control" "8" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
Remove all information at or below the name from the cache.
The rrsets and key entries are removed so that new lookups will be performed.
This needs to walk and inspect the entire cache, and is a slow operation.
+The entries are set to expired in the implementation of this command (so,
+with serve\-expired enabled, it'll serve that information but schedule a
+prefetch for new information).
.TP
.B flush_bogus
Remove all bogus data from the cache.
just the ratelimited ips, with their estimated qps. The ratelimited
ips are dropped before checking the cache.
.TP
+.B list_auth_zones
+List the auth zones that are configured. Printed one per line with a
+status, indicating if the zone is expired and current serial number.
+.TP
.B view_list_local_zones \fIview\fR
\fIlist_local_zones\fR for given view.
.TP
key/server secret key pair. This cache should be able to host QPS * `replay
window` interval keys to prevent replay of a query during `replay window`
seconds.
+.TP
+.I num.query.authzone.up
+The number of queries answered from auth\-zone data, upstream queries.
+These queries would otherwise have been sent (with fallback enabled) to
+the internet, but are now answered from the auth zone.
+.TP
+.I num.query.authzone.down
+The number of queries for downstream answered from auth\-zone data.
+These queries are from downstream clients, and have had an answer from
+the data in the auth zone.
+.TP
+.I num.query.aggressive.NOERROR
+The number of queries answered using cached NSEC records with NODATA RCODE.
+These queries would otherwise have been sent to the internet, but are now
+answered using cached data.
+.TP
+.I num.query.aggressive.NXDOMAIN
+The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
+These queries would otherwise have been sent to the internet, but are now
+answered using cached data.
.SH "FILES"
.TP
.I @ub_conf_file@
-.TH "unbound\-host" "1" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "unbound\-host" "1" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
-.TH "unbound" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "unbound" "8" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" unbound.8 -- unbound manual
.\"
.\"
.SH "NAME"
.B unbound
-\- Unbound DNS validating resolver 1.7.0.
+\- Unbound DNS validating resolver 1.7.3.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
-.TH "unbound.conf" "5" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
+.TH "unbound.conf" "5" "Jun 21, 2018" "NLnet Labs" "unbound 1.7.3"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
.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
but use udp to fetch data upstream.
.TP
.B tls\-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
+Enabled or disable whether the upstream queries use TLS only for transport.
+Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
TCP wireformat. The other server must support this (see
\fBtls\-service\-key\fR).
+If you enable this, also configure a tls\-cert\-bundle or use tls\-win\cert to
+load CA certs, otherwise the connections cannot be authenticated.
.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 tls\-service\-key: \fI<file>
-If enabled, the server provider SSL service on its TCP sockets. The clients
+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,
Alternate syntax for \fBtls\-service\-pem\fR.
.TP
.B tls\-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.
+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>
Alternate syntax for \fBtls\-port\fR.
.B ssl\-cert\-bundle: \fI<file>
Alternate syntax for \fBtls\-cert\-bundle\fR.
.TP
+.B tls\-win\-cert: \fI<yes or no>
+Add the system certificates to the cert bundle certificates for authentication.
+If no cert bundle, it uses only these certificates. Default is no.
+On windows this option uses the certificates from the cert store. Use
+the tls\-cert\-bundle option on other systems.
+.TP
+.B tls\-additional\-port: \fI<portnr>
+List portnumbers as tls\-additional\-port, and when interfaces are defined,
+eg. with the @port suffix, as this port number, they provide dns over TLS
+service. Can list multiple, each on a new statement.
+.TP
.B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation.
Default is no.
.B access\-control: \fI<IP netblock> <action>
The netblock is given as an IP4 or IP6 address with /size appended for a
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
-\fIallow\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or \fIrefuse_non_local\fR.
+\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
+\fIrefuse_non_local\fR.
The most specific netblock match is used, if none match \fIdeny\fR is used.
.IP
The action \fIdeny\fR stops queries from hosts from that netblock.
are made for the authoritative data. For nonrecursive queries any replies
from the dynamic cache are refused.
.IP
+The \fIallow_setrd\fR action ignores the recursion desired (RD) bit and
+treats all requests as if the recursion desired bit is set. Note that this
+behavior violates RFC 1034 which states that a name server should never perform
+recursive service unless asked via the RD bit since this interferes with
+trouble shooting of name servers and their databases. This prohibited behavior
+may be useful if another DNS server must forward requests for specific
+zones to a resolver DNS server, but only supports stub domains and
+sends queries to the resolver DNS server with the RD bit cleared.
+.IP
The action \fIallow_snoop\fR gives nonrecursive access too. This give
both recursive and non recursive access. The name \fIallow_snoop\fR refers
to cache snooping, a technique to use nonrecursive queries to examine
and the zones are signed. This enforces DNSSEC validation on nameserver
NS sets and the nameserver addresses that are encountered on the referral
path to the answer.
-Default off, because it burdens the authority servers, and it is
+Default no, because it burdens the authority servers, and it is
not RFC standard, and could lead to performance problems because of the
extra query load that is generated. Experimental option.
If you enable it consider adding more numbers after the target\-fetch\-policy
Only sent minimum required labels of the QNAME and set QTYPE to A when
possible. Best effort approach; full QNAME and original QTYPE will be sent when
upstream replies with a RCODE other than NOERROR, except when receiving
-NXDOMAIN from a DNSSEC signed zone. Default is off.
+NXDOMAIN from a DNSSEC signed zone. Default is yes.
.TP
.B qname\-minimisation\-strict: \fI<yes or no>
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
.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 off. It helps to reduce the query rate towards targets that get
-a very high nonexistant name lookup rate.
+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
.B trust\-anchor\-signaling: \fI<yes or no>
Send RFC8145 key tag query after trust anchor priming. Default is off.
.TP
+.B root\-key\-sentinel: \fI<yes or no>
+Root key trust anchor sentinel. Default is on.
+.TP
.B dlv\-anchor\-file: \fI<filename>
This option was used during early days DNSSEC deployment when no parent-side
DS record registrations were easily available. Nowadays, it is best to have
This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the
factor given.
+.TP 5
+.B low\-rtt: \fI<msec time>
+Set the time in millisecond that is considere a low ping time for fast
+server selection with the low\-rtt\-permil option, that turns this on or off.
+The default is 45 msec, a number from IPv6 quick response documents.
+.TP 5
+.B low\-rtt\-permil: \fI<number>
+Specify how many times out of 1000 to pick the fast server from the low
+rtt band. 0 turns the feature off. A value of 900 would pick the fast
+server when such fast servers are available 90 percent of the time, and
+the remaining time perform normal exploration of random servers.
+When prefetch is enabled (or serve\-expired), such prefetches are not
+sped up, because there is no one waiting for it, and it presents a good
+moment to perform server exploration. The low\-rtt option can be used
+to specify which servers are picked for fast server selection, servers
+with a ping roundtrip time below that value are considered.
+The default for low\-rtt\-permil is 0.
.SS "Remote Control Options"
In the
.B remote\-control:
clause are the declarations for the remote control facility. If this is
enabled, the \fIunbound\-control\fR(8) utility can be used to send
commands to the running unbound server. The server uses these clauses
-to setup SSLv3 / TLSv1 security for the connection. The
+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.
Use 0.0.0.0 and ::0 to listen to all interfaces.
If you change this and permissions have been dropped, you must restart
the server for the change to take effect.
+.IP
+If you set it to an absolute path, a local socket is used. The local socket
+does not use the certificates and keys, so those files need not be present.
+To restrict access, unbound sets permissions on the file to the user and
+group that is configured, the access bits are set to allow the group members
+to access the control socket file. Put users that need to access the socket
+in the that group. To restrict access further, create a directory to put
+the control socket in and restrict access to that directory.
.TP 5
.B control\-port: \fI<port number>
The port number to listen on for IPv4 or IPv6 control interfaces,
the server for the change to take effect.
.TP 5
.B control\-use\-cert: \fI<yes or no>
-Whether to require certificate authentication of control connections.
-The default is "yes".
-This should not be changed unless there are other mechanisms in place
-to prevent untrusted users from accessing the remote control
-interface.
+For localhost control-interface you can disable the use of TLS by setting
+this option to "no", default is "yes". For local sockets, TLS is disabled
+and the value of this option is ignored.
.TP 5
.B server\-key\-file: \fI<private key file>
Path to the server private key, by default unbound_server.key.
To use a nondefault port for DNS communication append '@' with the port number.
.TP
.B stub\-prime: \fI<yes or no>
-This option is by default off. If enabled it performs NS set priming,
+This option is by default no. If enabled it performs NS set priming,
which is similar to root hints, where it starts using the list of nameservers
currently published by the zone. Thus, if the hint list is slightly outdated,
the resolver picks up a correct list online.
The default is no.
.TP
.B stub\-tls\-upstream: \fI<yes or no>
-Enabled or disable whether the queries to this stub use SSL for transport.
+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>
.B forward\-addr: \fI<IP address>
IP address of server to forward to. Can be IP 4 or IP 6.
To use a nondefault port for DNS communication append '@' with the port number.
+If tls is enabled, then you can append a '#' and a name, then it'll check
+the tls authentication certificates with that name. If you combine
+the '@' and '#', the '@' comes first.
+.IP
+At high verbosity it logs the TLS certificate, with TLS enabled.
+If you leave out the '#' and auth name from the forward\-addr, any
+name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
.TP
.B forward\-first: \fI<yes or no>
If enabled, a query is attempted without the forward clause if it fails.
The default is no.
.TP
.B forward\-tls\-upstream: \fI<yes or no>
-Enabled or disable whether the queries to this forwarder use SSL for transport.
+Enabled or disable whether the queries to this forwarder use TLS for transport.
Default is no.
+If you enable this, also configure a tls\-cert\-bundle or use tls\-win\cert to
+load CA certs, otherwise the connections cannot be authenticated.
.TP
.B forward\-ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBforward\-tls\-upstream\fR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection.
.TP
+.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
+With allow\-notify you can specify additional sources of notifies.
+When notified, the server attempts to first probe and then zone transfer.
+If the notify is from a master, it first attempts that master. Otherwise
+other masters are attempted. If there are no masters, but only urls, the
+file is downloaded when notified. The masters from master: statements are
+allowed notify by default.
+.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
to the query without performing iterative DNS resolution.
If Unbound cannot even find an answer in the backend, it resolves the
query as usual, and stores the answer in the backend.
+.P
+If Unbound was built with
+\fB\-\-with\-libhiredis\fR
+on a system that has installed the hiredis C client library of Redis,
+then the "redis" backend can be used.
+This backend communicates with the specified Redis server over a TCP
+connection to store and retrieve cache data.
+It can be used as a persistent and/or shared cache backend.
+It should be noted that Unbound never removes data stored in the Redis server,
+even if some data have expired in terms of DNS TTL or the Redis server has
+cached too much data;
+if necessary the Redis server must be configured to limit the cache size,
+preferably with some kind of least-recently-used eviction policy.
+This backend uses synchronous communication with the Redis server
+based on the assumption that the communication is stable and sufficiently
+fast.
+The thread waiting for a response from the Redis server cannot handle
+other DNS queries.
+Although the backend has the ability to reconnect to the server when
+the connection is closed unexpectedly and there is a configurable timeout
+in case the server is overly slow or hangs up, these cases are assumed
+to be very rare.
+If connection close or timeout happens too often, Unbound will be
+effectively unusable with this backend.
+It's the administrator's responsibility to make the assumption hold.
+.P
The
.B cachedb:
clause gives custom settings of the cache DB module.
.TP
.B backend: \fI<backend name>\fR
Specify the backend database name.
-Currently, only the in-memory "testframe" backend is supported.
-As the name suggests this backend is not of any practical use.
-This option defaults to "testframe".
+The default database is the in-memory backend named "testframe", which,
+as the name suggests, is not of any practical use.
+Depending on the build-time configuration, "redis" backend may also be
+used as described above.
.TP
.B secret-seed: \fI<"secret string">\fR
Specify a seed to calculate a hash value from query information.
If the backend database is shared by multiple Unbound instances,
all instances must use the same secret seed.
This option defaults to "default".
+.P
+The following
+.B cachedb
+otions are specific to the redis backend.
+.TP
+.B redis-server-host: \fI<server address or name>\fR
+The IP (either v6 or v4) address or domain name of the Redis server.
+In general an IP address should be specified as otherwise Unbound will have to
+resolve the name of the server every time it establishes a connection
+to the server.
+This option defaults to "127.0.0.1".
+.TP
+.B redis-server-port: \fI<port number>\fR
+The TCP port number of the Redis server.
+This option defaults to 6379.
+.TP
+.B redis-timeout: \fI<msec>\fR
+The period until when Unbound waits for a response from the Redis sever.
+If this timeout expires Unbound closes the connection, treats it as
+if the Redis server does not have the requested data, and will try to
+re-establish a new connection later.
+This option defaults to 100 milliseconds.
.SH "MEMORY CONTROL EXAMPLE"
In the example config settings below memory usage is reduced. Some service
levels are lower, notable very large data and a high TCP load are no longer
}
for(a = dp->target_list; a; a = a->next_target) {
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
- a->bogus, a->lame))
+ a->bogus, a->lame, a->tls_auth_name))
return NULL;
}
return copy;
if(ns->got4 && ns->got6)
ns->resolved = 1;
}
- return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame);
+ return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
}
int
delegpt_add_addr(struct delegpt* dp, struct regional* region,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
- uint8_t lame)
+ uint8_t lame, char* tls_auth_name)
{
struct delegpt_addr* a;
log_assert(!dp->dp_type_mlc);
a->bogus = bogus;
a->lame = lame;
a->dnsseclame = 0;
+ if(tls_auth_name) {
+ a->tls_auth_name = regional_strdup(region, tls_auth_name);
+ if(!a->tls_auth_name)
+ return 0;
+ } else {
+ a->tls_auth_name = NULL;
+ }
return 1;
}
(ns->done_pside6?" PSIDE_AAAA":""));
}
for(a = dp->target_list; a; a = a->next_target) {
+ char s[128];
const char* str = " ";
if(a->bogus && a->lame) str = " BOGUS ADDR_LAME ";
else if(a->bogus) str = " BOGUS ";
else if(a->lame) str = " ADDR_LAME ";
- log_addr(VERB_ALGO, str, &a->addr, a->addrlen);
+ if(a->tls_auth_name)
+ snprintf(s, sizeof(s), "%s[%s]", str,
+ a->tls_auth_name);
+ else snprintf(s, sizeof(s), "%s", str);
+ log_addr(VERB_ALGO, s, &a->addr, a->addrlen);
}
}
}
a = dp->target_list;
while(a) {
na = a->next_target;
+ free(a->tls_auth_name);
free(a);
a = na;
}
}
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
- socklen_t addrlen, uint8_t bogus, uint8_t lame)
+ socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name)
{
struct delegpt_addr* a;
log_assert(dp->dp_type_mlc);
a->bogus = bogus;
a->lame = lame;
a->dnsseclame = 0;
+ if(tls_auth_name) {
+ a->tls_auth_name = strdup(tls_auth_name);
+ if(!a->tls_auth_name) {
+ free(a);
+ return 0;
+ }
+ } else {
+ a->tls_auth_name = NULL;
+ }
return 1;
}
if(ns->got4 && ns->got6)
ns->resolved = 1;
}
- return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame);
+ return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, NULL);
}
size_t delegpt_get_mem(struct delegpt* dp)
* option is useful to mark the address dnsseclame.
* This value is not copied in addr-copy and dp-copy. */
uint8_t dnsseclame;
+ /** the TLS authentication name, (if not NULL) to use. */
+ char* tls_auth_name;
};
/**
* @param addrlen: the length of addr.
* @param bogus: if address is bogus.
* @param lame: if address is lame.
+ * @param tls_auth_name: TLS authentication name (or NULL).
* @return false on error.
*/
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
struct sockaddr_storage* addr, socklen_t addrlen,
- uint8_t bogus, uint8_t lame);
+ uint8_t bogus, uint8_t lame, char* tls_auth_name);
/**
* Find NS record in name list of delegation point.
* @param addrlen: the length of addr.
* @param bogus: if address is bogus.
* @param lame: if address is lame.
+ * @param tls_auth_name: TLS authentication name (or NULL).
* @return false on error.
*/
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
- socklen_t addrlen, uint8_t bogus, uint8_t lame);
+ socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name);
/**
* Add target address to the delegation point.
struct config_strlist* p;
struct sockaddr_storage addr;
socklen_t addrlen;
+ char* tls_auth_name;
for(p = s->addrs; p; p = p->next) {
log_assert(p->str);
- if(!extstrtoaddr(p->str, &addr, &addrlen)) {
+ if(!authextstrtoaddr(p->str, &addr, &addrlen, &tls_auth_name)) {
log_err("cannot parse forward %s ip address: '%s'",
s->name, p->str);
return 0;
}
- if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
+ if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
+ tls_auth_name)) {
log_err("out of memory");
return 0;
}
struct config_strlist* p;
struct sockaddr_storage addr;
socklen_t addrlen;
+ char* auth_name;
for(p = s->addrs; p; p = p->next) {
log_assert(p->str);
- if(!extstrtoaddr(p->str, &addr, &addrlen)) {
+ if(!authextstrtoaddr(p->str, &addr, &addrlen, &auth_name)) {
log_err("cannot parse stub %s ip address: '%s'",
s->name, p->str);
return 0;
}
- if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
+ if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
+ auth_name)) {
log_err("out of memory");
return 0;
}
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
struct delegpt* dp, int* selected_rtt, int open_target,
- struct sock_list* blacklist)
+ struct sock_list* blacklist, time_t prefetch)
{
- int got_num = 0, low_rtt = 0, swap_to_front;
+ int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
struct delegpt_addr* a, *n, *prev=NULL;
/* fillup sel_rtt and find best rtt in the bunch */
return 0 to force the caller to fetch more */
}
+ if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
+ low_rtt < env->cfg->low_rtt &&
+ ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
+ /* the query is not prefetch, but for a downstream client,
+ * there is a low_rtt (fast) server. We choose that x% of the
+ * time */
+ /* pick rtt numbers from 0..LOWBAND_RTT */
+ rtt_band = env->cfg->low_rtt - low_rtt;
+ }
+
got_num = 0;
a = dp->result_list;
while(a) {
}
/* classify the server address and determine what to do */
swap_to_front = 0;
- if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
+ if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= rtt_band) {
got_num++;
swap_to_front = 1;
- } else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
+ } else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=rtt_band) {
got_num++;
swap_to_front = 1;
}
iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp,
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_lame,
- int* chase_to_rd, int open_target, struct sock_list* blacklist)
+ int* chase_to_rd, int open_target, struct sock_list* blacklist,
+ time_t prefetch)
{
int sel;
int selrtt;
struct delegpt_addr* a, *prev;
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
- *env->now, dp, &selrtt, open_target, blacklist);
+ *env->now, dp, &selrtt, open_target, blacklist, prefetch);
if(num == 0)
return NULL;
}
int
-iter_indicates_dnssec_fwd(struct module_env* env, struct query_info *qinfo)
+iter_qname_indicates_dnssec(struct module_env* env, struct query_info *qinfo)
{
struct trust_anchor* a;
if(!env || !env->anchors || !qinfo || !qinfo->qname)
* @param open_target: number of currently outstanding target queries.
* If we wait for these, perhaps more server addresses become available.
* @param blacklist: the IP blacklist to use.
+ * @param prefetch: if not 0, prefetch is in use for this query.
+ * This means the query can have different timing, because prefetch is
+ * not waited upon by the downstream client, and thus a good time to
+ * perform exploration of other targets.
* @return best target or NULL if no target.
* if not null, that target is removed from the result list in the dp.
*/
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp, uint8_t* name,
size_t namelen, uint16_t qtype, int* dnssec_lame,
- int* chase_to_rd, int open_target, struct sock_list* blacklist);
+ int* chase_to_rd, int open_target, struct sock_list* blacklist,
+ time_t prefetch);
/**
* Allocate dns_msg from parsed msg, in regional.
struct delegpt* dp);
/**
- * See if qname has DNSSEC needs in the forwarding case. This is true if
- * there is a trust anchor above it. Whether there is an insecure delegation
- * to the data is unknown, but CD-retry is needed.
+ * See if qname has DNSSEC needs. This is true if there is a trust anchor above
+ * it. Whether there is an insecure delegation to the data is unknown.
* @param env: environment with anchors.
* @param qinfo: query name and class.
* @return true if trust anchor above qname, false if no anchor or insecure
* point above qname.
*/
-int iter_indicates_dnssec_fwd(struct module_env* env,
+int iter_qname_indicates_dnssec(struct module_env* env,
struct query_info *qinfo);
/**
/** see if last resort is possible - does config allow queries to parent */
static int
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
- uint16_t qclass)
+ uint16_t qclass, struct delegpt** retdp)
{
struct delegpt* fwddp;
struct iter_hints_stub* stub;
/* has_parent side is turned off for stub_first, where we
* are allowed to go to the parent */
stub->dp->has_parent_side_NS) {
+ if(retdp) *retdp = stub->dp;
return 0;
}
if((fwddp = forwards_find(env->fwds, nm, qclass)) &&
/* has_parent_side is turned off for forward_first, where
* we are allowed to go to the parent */
fwddp->has_parent_side_NS) {
+ if(retdp) *retdp = fwddp;
return 0;
}
return 1;
if(iq->depth == ie->max_dependency_depth)
return;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
- iq->qchase.qclass))
+ iq->qchase.qclass, NULL))
return;
/* is this query the same as the nscheck? */
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS &&
*/
if (iq->refetch_glue &&
iq->dp &&
- !can_have_last_resort(qstate->env,
- iq->dp->name,
- iq->dp->namelen,
- iq->qchase.qclass)) {
+ !can_have_last_resort(qstate->env, iq->dp->name,
+ iq->dp->namelen, iq->qchase.qclass, NULL)) {
iq->refetch_glue = 0;
}
iq->qchase.qname_len, iq->qchase.qtype,
iq->qchase.qclass, qstate->query_flags,
qstate->region, qstate->env->scratch, 0);
- if(!msg && qstate->env->neg_cache) {
+ if(!msg && qstate->env->neg_cache &&
+ iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) {
/* 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,
delnamelen = iq->qchase.qname_len;
}
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
- (iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway)) {
+ (iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
+ && can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL))) {
/* remove first label from delname, root goes to hints,
* but only to fetch glue, not for qtype=DS. */
/* also when prefetching an NS record, fetch it again from
*/
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
iq->dp)) {
+ struct delegpt* retdp = NULL;
+ if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
+ if(retdp) {
+ verbose(VERB_QUERY, "cache has stub "
+ "or fwd but no addresses, "
+ "fallback to config");
+ iq->dp = delegpt_copy(retdp,
+ qstate->region);
+ if(!iq->dp) {
+ log_err("out of memory in "
+ "stub/fwd fallback");
+ return error_response(qstate,
+ id, LDNS_RCODE_SERVFAIL);
+ }
+ break;
+ }
+ verbose(VERB_ALGO, "useless dp "
+ "but cannot go up, servfail");
+ delegpt_log(VERB_ALGO, iq->dp);
+ return error_response(qstate, id,
+ LDNS_RCODE_SERVFAIL);
+ }
if(dname_is_root(iq->dp->name)) {
/* use safety belt */
verbose(VERB_QUERY, "Cache has root NS but "
log_assert(iq->dp);
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
- iq->qchase.qclass)) {
+ iq->qchase.qclass, NULL)) {
/* fail -- no more targets, no more hope of targets, no hope
* of a response. */
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
for(a = p->target_list; a; a=a->next_target) {
(void)delegpt_add_addr(iq->dp, qstate->region,
&a->addr, a->addrlen, a->bogus,
- a->lame);
+ a->lame, a->tls_auth_name);
}
}
iq->dp->has_parent_side_NS = 1;
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
(ie->supports_ipv4 && !ns->done_pside4)) &&
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
- iq->qchase.qclass)) {
+ iq->qchase.qclass, NULL)) {
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
"because it is also a stub/forward,",
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
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);
+ if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) {
+ verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone");
+ } else {
+ lock_rw_wrlock(&qstate->env->auth_zones->lock);
+ qstate->env->auth_zones->num_query_up++;
+ lock_rw_unlock(&qstate->env->auth_zones->lock);
+ 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) {
target = iter_server_selection(ie, qstate->env, iq->dp,
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
&iq->dnssec_lame_query, &iq->chase_to_rd,
- iq->num_target_queries, qstate->blacklist);
+ iq->num_target_queries, qstate->blacklist,
+ qstate->prefetch_leeway);
/* If no usable target was selected... */
if(!target) {
* (blacklist nonempty) and no trust-anchors are configured
* above the qname or on the first attempt when dnssec is on */
EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&&
- !qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
+ !qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), &target->addr, target->addrlen,
iq->dp->name, iq->dp->namelen,
- (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
+ (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
+ target->tls_auth_name, qstate);
if(!outq) {
log_addr(VERB_DETAIL, "error sending query to auth server",
&target->addr, target->addrlen);
}
type = response_type_from_server(
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
- iq->response, &iq->qchase, iq->dp);
+ iq->response, &iq->qinfo_out, iq->dp);
iq->chase_to_rd = 0;
- if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
+ if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) &&
+ !iq->auth_zone_response) {
/* When forwarding (RD bit is set), we handle referrals
* differently. No queries should be sent elsewhere */
type = RESPONSE_TYPE_ANSWER;
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
- if (qstate->env->cfg->qname_minimisation)
- iq->minimisation_state = INIT_MINIMISE_STATE;
/* Clear the query state, since this is a query restart. */
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;
+ if(iq->minimisation_state != MINIMISE_STATE)
+ /* Only count as query restart when it is not an extra
+ * query as result of qname minimisation. */
+ iq->query_restart_count++;
+ if(qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = INIT_MINIMISE_STATE;
/* stop current outstanding queries.
* FIXME: should the outstanding queries be waited for and
struct ctx_query*
context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
- ub_callback_type cb, void* cbarg)
+ ub_callback_type cb, ub_event_callback_type cb_event, void* cbarg)
{
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
if(!q) return NULL;
}
lock_basic_unlock(&ctx->cfglock);
q->node.key = &q->querynum;
- q->async = (cb != NULL);
+ q->async = (cb != NULL || cb_event != NULL);
q->cb = cb;
+ q->cb_event = cb_event;
q->cb_arg = cbarg;
q->res = (struct ub_result*)calloc(1, sizeof(*q->res));
if(!q->res) {
#include "util/rbtree.h"
#include "services/modstack.h"
#include "libunbound/unbound.h"
+#include "libunbound/unbound-event.h"
#include "util/data/packed_rrset.h"
struct libworker;
struct tube;
/** was this query cancelled (for bg worker) */
int cancelled;
- /** for async query, the callback function */
+ /** for async query, the callback function of type ub_callback_type */
ub_callback_type cb;
+ /** for event callbacks the type is ub_event_callback_type */
+ ub_event_callback_type cb_event;
/** for async query, the callback user arg */
void* cb_arg;
* @param rrtype: type
* @param rrclass: class
* @param cb: callback for async, or NULL for sync.
+ * @param cb_event: event callback for async, or NULL for sync.
* @param cbarg: user arg for async queries.
* @return new ctx_query or NULL for malloc failure.
*/
struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
- int rrclass, ub_callback_type cb, void* cbarg);
+ int rrclass, ub_callback_type cb, ub_event_callback_type cb_event,
+ void* cbarg);
/**
* Get a new alloc. Creates a new one or uses a cached one.
}
/* create new ctx_query and attempt to add to the list */
lock_basic_unlock(&ctx->cfglock);
- q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
+ q = context_new(ctx, name, rrtype, rrclass, NULL, NULL, NULL);
if(!q)
return UB_NOMEM;
/* become a resolver thread for a bit */
ub_comm_base_now(ctx->event_worker->base);
/* create new ctx_query and attempt to add to the list */
- q = context_new(ctx, name, rrtype, rrclass, (ub_callback_type)callback,
- mydata);
+ q = context_new(ctx, name, rrtype, rrclass, NULL, callback, mydata);
if(!q)
return UB_NOMEM;
}
/* create new ctx_query and attempt to add to the list */
- q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
+ q = context_new(ctx, name, rrtype, rrclass, callback, NULL, mydata);
if(!q)
return UB_NOMEM;
hints_delete(w->env->hints);
w->env->hints = NULL;
}
- if(cfg->ssl_upstream) {
+ if(cfg->ssl_upstream || (cfg->tls_cert_bundle && cfg->tls_cert_bundle[0]) || cfg->tls_win_cert) {
w->sslctx = connect_sslctx_create(NULL, NULL,
- cfg->tls_cert_bundle);
+ cfg->tls_cert_bundle, cfg->tls_win_cert);
if(!w->sslctx) {
/* to make the setup fail after unlock */
hints_delete(w->env->hints);
/* cleanup */
m = UB_LIBCMD_QUIT;
+ w->want_quit = 1;
tube_remove_bg_listen(w->ctx->qq_pipe);
tube_remove_bg_write(w->ctx->rr_pipe);
libworker_delete(w);
res->nxdomain = 1;
if(msg_security == sec_status_secure)
res->secure = 1;
- if(msg_security == sec_status_bogus)
+ if(msg_security == sec_status_bogus ||
+ msg_security == sec_status_secure_sentinel_fail)
res->bogus = 1;
}
enum sec_status s, char* why_bogus)
{
struct ctx_query* q = (struct ctx_query*)arg;
- ub_event_callback_type cb = (ub_event_callback_type)q->cb;
+ ub_event_callback_type cb = q->cb_event;
void* cb_arg = q->cb_arg;
int cancelled = q->cancelled;
uint8_t* msg = NULL;
uint32_t len = 0;
+ if(w->want_quit) {
+ context_query_delete(q);
+ return;
+ }
/* serialize and delete unneeded q */
if(w->is_bg_thread) {
lock_basic_lock(&w->ctx->cfglock);
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
- size_t zonelen, int ssl_upstream, struct module_qstate* q)
+ size_t zonelen, int ssl_upstream, char* tls_auth_name,
+ struct module_qstate* q)
{
struct libworker* w = (struct libworker*)q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
e->qstate = q;
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
- addr, addrlen, zone, zonelen, q, libworker_handle_service_reply,
- e, w->back->udp_buff, q->env);
+ tls_auth_name, addr, addrlen, zone, zonelen, q,
+ libworker_handle_service_reply, e, w->back->udp_buff, q->env);
if(!e->qsent) {
return NULL;
}
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
- int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
+ int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
+ struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
return 0;
int is_bg;
/** is this a bg worker that is threaded (not forked)? */
int is_bg_thread;
+ /** want to quit, stop handling new content */
+ int want_quit;
/** copy of the module environment with worker local entries. */
struct module_env* env;
long long num_query_dnscrypt_replay;
/** number of dnscrypt nonces cache entries */
long long nonce_cache_count;
+ /** number of queries for unbound's auth_zones, upstream query */
+ long long num_query_authzone_up;
+ /** number of queries for unbound's auth_zones, downstream answers */
+ long long num_query_authzone_down;
+ /** number of times neg cache records were used to generate NOERROR
+ * responses. */
+ long long num_neg_cache_noerror;
+ /** number of times neg cache records were used to generate NXDOMAIN
+ * responses. */
+ long long num_neg_cache_nxdomain;
};
/**
* @param zone: delegation point name.
* @param zonelen: length of zone name wireformat dname.
* @param ssl_upstream: use SSL for upstream queries.
+ * @param tls_auth_name: if ssl_upstream, use this name with TLS
+ * authentication.
* @param q: wich query state to reactivate upon return.
* @return: false on failure (memory or socket related). no query was
* sent.
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
- size_t zonelen, int ssl_upstream, struct module_qstate* q);
+ size_t zonelen, int ssl_upstream, char* tls_auth_name,
+ struct module_qstate* q);
/** process incoming replies from the network */
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
* @param zone: wireformat dname of the zone.
* @param zonelen: length of zone name.
* @param ssl_upstream: use SSL for upstream queries.
+ * @param tls_auth_name: if ssl_upstream, use this name with TLS
+ * authentication.
* @param q: wich query state to reactivate upon return.
* @return: false on failure (memory or socket related). no query was
* sent.
struct outbound_entry* worker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
- size_t zonelen, int ssl_upstream, struct module_qstate* q);
+ size_t zonelen, int ssl_upstream, char* tls_auth_name,
+ struct module_qstate* q);
/**
* process control messages from the main thread. Frees the control
#define AUTH_HTTP_PORT 80
/* auth https port number */
#define AUTH_HTTPS_PORT 443
+/* max depth for nested $INCLUDEs */
+#define MAX_INCLUDE_DEPTH 10
/** pick up nextprobe task to start waiting to perform transfer actions */
static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
- int failure);
+ int failure, int lookup_only);
/** move to sending the probe packets, next if fails. task_probe */
static void xfr_probe_send_or_end(struct auth_xfer* xfr,
struct module_env* env);
+/** pick up probe task with specified(or NULL) destination first,
+ * or transfer task if nothing to probe, or false if already in progress */
+static int xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
+ struct auth_master* spec);
+/** delete xfer structure (not its tree entry) */
+void auth_xfer_delete(struct auth_xfer* xfr);
/** create new dns_msg */
static struct dns_msg*
* @param state: parse state with $ORIGIN, $TTL and 'prev-dname' and so on,
* that is kept between includes.
* The lineno is set at 1 and then increased by the function.
+ * @param fname: file name.
+ * @param depth: recursion depth for includes
* returns false on failure, has printed an error message
*/
static int
az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
- struct sldns_file_parse_state* state)
+ struct sldns_file_parse_state* state, char* fname, int depth)
{
size_t rr_len, dname_len;
int status;
FILE* inc;
int lineno_orig = state->lineno;
char* incfile = (char*)rr + 8;
+ if(depth > MAX_INCLUDE_DEPTH) {
+ log_err("%s:%d max include depth"
+ "exceeded", fname, state->lineno);
+ return 0;
+ }
/* skip spaces */
while(*incfile == ' ' || *incfile == '\t')
incfile++;
}
/* recurse read that file now */
if(!az_parse_file(z, inc, rr, rrbuflen,
- state)) {
+ state, incfile, depth+1)) {
log_err("%s:%d cannot parse include "
- "file %s", z->zonefile,
+ "file %s", fname,
lineno_orig, incfile);
fclose(inc);
+ free(incfile);
return 0;
}
fclose(inc);
continue;
}
if(status != 0) {
- log_err("parse error %s %d:%d: %s", z->zonefile,
+ log_err("parse error %s %d:%d: %s", fname,
state->lineno, LDNS_WIREPARSE_OFFSET(status),
sldns_get_errorstr_parse(status));
return 0;
sldns_wire2str_type_buf(sldns_wirerr_get_type(rr,
rr_len, dname_len), buf, sizeof(buf));
log_err("%s:%d cannot insert RR of type %s",
- z->zonefile, state->lineno, buf);
+ fname, state->lineno, buf);
return 0;
}
}
free(n);
return 0;
}
+
+ /* clear the data tree */
+ traverse_postorder(&z->data, auth_data_del, NULL);
+ rbtree_init(&z->data, &auth_data_cmp);
+
memset(&state, 0, sizeof(state));
/* default TTL to 3600 */
state.default_ttl = 3600;
state.origin_len = z->namelen;
}
/* parse the (toplevel) file */
- if(!az_parse_file(z, in, rr, sizeof(rr), &state)) {
+ if(!az_parse_file(z, in, rr, sizeof(rr), &state, z->zonefile, 0)) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
log_err("error parsing zonefile %s for %s",
z->zonefile, n?n:"error");
/** write buffer to file and check return codes */
static int
-write_out(FILE* out, const char* str)
+write_out(FILE* out, const char* str, size_t len)
{
- size_t r, len = strlen(str);
+ size_t r;
if(len == 0)
return 1;
r = fwrite(str, 1, len, out);
verbose(VERB_ALGO, "failed to rr2str rr %d", (int)i);
continue;
}
- if(!write_out(out, buf))
+ if(!write_out(out, buf, strlen(buf)))
return 0;
}
return 1;
return 1;
}
+/** find serial number of zone or false if none */
+int
+auth_zone_get_serial(struct auth_zone* z, uint32_t* serial)
+{
+ struct auth_data* apex;
+ struct auth_rrset* soa;
+ struct packed_rrset_data* d;
+ apex = az_find_name(z, z->name, z->namelen);
+ if(!apex) return 0;
+ soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
+ if(!soa || soa->data->count==0)
+ return 0; /* no RRset or no RRs in rrset */
+ if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */
+ d = soa->data;
+ *serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20));
+ return 1;
+}
+
/** Find auth_zone SOA and populate the values in xfr(soa values). */
static int
xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
lock_rw_unlock(&az->lock);
/* set options */
+ z->zone_deleted = 0;
if(!auth_zone_set_zonefile(z, c->zonefile)) {
if(x) {
lock_basic_unlock(&x->lock);
return 1;
}
+/** set all auth zones deleted, then in auth_zones_cfg, it marks them
+ * as nondeleted (if they are still in the config), and then later
+ * we can find deleted zones */
+static void
+az_setall_deleted(struct auth_zones* az)
+{
+ struct auth_zone* z;
+ lock_rw_wrlock(&az->lock);
+ RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
+ lock_rw_wrlock(&z->lock);
+ z->zone_deleted = 1;
+ lock_rw_unlock(&z->lock);
+ }
+ lock_rw_unlock(&az->lock);
+}
+
+/** find zones that are marked deleted and delete them.
+ * This is called from apply_cfg, and there are no threads and no
+ * workers, so the xfr can just be deleted. */
+static void
+az_delete_deleted_zones(struct auth_zones* az)
+{
+ struct auth_zone* z;
+ struct auth_zone* delete_list = NULL, *next;
+ struct auth_xfer* xfr;
+ lock_rw_wrlock(&az->lock);
+ RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
+ lock_rw_wrlock(&z->lock);
+ if(z->zone_deleted) {
+ /* we cannot alter the rbtree right now, but
+ * we can put it on a linked list and then
+ * delete it */
+ z->delete_next = delete_list;
+ delete_list = z;
+ }
+ lock_rw_unlock(&z->lock);
+ }
+ /* now we are out of the tree loop and we can loop and delete
+ * the zones */
+ z = delete_list;
+ while(z) {
+ next = z->delete_next;
+ xfr = auth_xfer_find(az, z->name, z->namelen, z->dclass);
+ if(xfr) {
+ (void)rbtree_delete(&az->xtree, &xfr->node);
+ auth_xfer_delete(xfr);
+ }
+ (void)rbtree_delete(&az->ztree, &z->node);
+ auth_zone_delete(z);
+ z = next;
+ }
+ lock_rw_unlock(&az->lock);
+}
+
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup)
{
struct config_auth* p;
+ az_setall_deleted(az);
for(p = cfg->auths; p; p = p->next) {
if(!p->name || p->name[0] == 0) {
log_warn("auth-zone without a name, skipped");
return 0;
}
}
+ az_delete_deleted_zones(az);
if(!auth_zones_read_zones(az))
return 0;
if(setup) {
}
free(xfr->task_transfer);
}
+ auth_free_masters(xfr->allow_notify_list);
free(xfr);
}
/* answer it from zone z */
r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
lock_rw_unlock(&z->lock);
- if(fallback) {
+ if(!r && fallback) {
/* fallback to regular answering (recursive) */
return 0;
}
+ lock_rw_wrlock(&az->lock);
+ az->num_query_down++;
+ lock_rw_unlock(&az->lock);
/* encode answer */
if(!r)
return r;
}
+int
+auth_zone_parse_notify_serial(sldns_buffer* pkt, uint32_t *serial)
+{
+ struct query_info q;
+ uint16_t rdlen;
+ memset(&q, 0, sizeof(q));
+ sldns_buffer_set_position(pkt, 0);
+ if(!query_info_parse(&q, pkt)) return 0;
+ if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) return 0;
+ /* skip name of RR in answer section */
+ if(sldns_buffer_remaining(pkt) < 1) return 0;
+ if(pkt_dname_len(pkt) == 0) return 0;
+ /* check type */
+ if(sldns_buffer_remaining(pkt) < 10 /* type,class,ttl,rdatalen*/)
+ return 0;
+ if(sldns_buffer_read_u16(pkt) != LDNS_RR_TYPE_SOA) return 0;
+ sldns_buffer_skip(pkt, 2); /* class */
+ sldns_buffer_skip(pkt, 4); /* ttl */
+ rdlen = sldns_buffer_read_u16(pkt); /* rdatalen */
+ if(sldns_buffer_remaining(pkt) < rdlen) return 0;
+ if(rdlen < 22) return 0; /* bad soa length */
+ sldns_buffer_skip(pkt, (ssize_t)(rdlen-20));
+ *serial = sldns_buffer_read_u32(pkt);
+ /* return true when has serial in answer section */
+ return 1;
+}
+
+/** see if addr appears in the list */
+static int
+addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
+ socklen_t addrlen)
+{
+ struct auth_addr* p;
+ for(p=list; p; p=p->next) {
+ if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0)
+ return 1;
+ }
+ return 0;
+}
+
+/** check if an address matches a master specification (or one of its
+ * addresses in the addr list) */
+static int
+addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
+ socklen_t addrlen, struct auth_master** fromhost)
+{
+ struct sockaddr_storage a;
+ socklen_t alen = 0;
+ int net = 0;
+ if(addr_in_list(master->list, addr, addrlen)) {
+ *fromhost = master;
+ return 1;
+ }
+ /* compare address (but not port number, that is the destination
+ * port of the master, the port number of the received notify is
+ * allowed to by any port on that master) */
+ if(extstrtoaddr(master->host, &a, &alen) &&
+ sockaddr_cmp_addr(addr, addrlen, &a, alen)==0) {
+ *fromhost = master;
+ return 1;
+ }
+ /* prefixes, addr/len, like 10.0.0.0/8 */
+ /* not http and has a / and there is one / */
+ if(master->allow_notify && !master->http &&
+ strchr(master->host, '/') != NULL &&
+ strchr(master->host, '/') == strrchr(master->host, '/') &&
+ netblockstrtoaddr(master->host, UNBOUND_DNS_PORT, &a, &alen,
+ &net) && alen == addrlen) {
+ if(addr_in_common(addr, (addr_is_ip6(addr, addrlen)?128:32),
+ &a, net, alen) >= net) {
+ *fromhost = NULL; /* prefix does not have destination
+ to send the probe or transfer with */
+ return 1; /* matches the netblock */
+ }
+ }
+ return 0;
+}
+
+/** check access list for notifies */
+static int
+az_xfr_allowed_notify(struct auth_xfer* xfr, struct sockaddr_storage* addr,
+ socklen_t addrlen, struct auth_master** fromhost)
+{
+ struct auth_master* p;
+ for(p=xfr->allow_notify_list; p; p=p->next) {
+ if(addr_matches_master(p, addr, addrlen, fromhost)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/** see if the serial means the zone has to be updated, i.e. the serial
+ * is newer than the zone serial, or we have no zone */
+static int
+xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial)
+{
+ if(!xfr->have_zone)
+ return 1; /* no zone, anything is better */
+ if(xfr->zone_expired)
+ return 1; /* expired, the sent serial is better than expired
+ data */
+ 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;
+}
+
+/** note notify serial, updates the notify information in the xfr struct */
+static void
+xfr_note_notify_serial(struct auth_xfer* xfr, int has_serial, uint32_t serial)
+{
+ if(xfr->notify_received && xfr->notify_has_serial && has_serial) {
+ /* see if this serial is newer */
+ if(compare_serial(xfr->notify_serial, serial) < 0)
+ xfr->notify_serial = serial;
+ } else if(xfr->notify_received && xfr->notify_has_serial &&
+ !has_serial) {
+ /* remove serial, we have notify without serial */
+ xfr->notify_has_serial = 0;
+ xfr->notify_serial = 0;
+ } else if(xfr->notify_received && !xfr->notify_has_serial) {
+ /* we already have notify without serial, keep it
+ * that way; no serial check when current operation
+ * is done */
+ } else {
+ xfr->notify_received = 1;
+ xfr->notify_has_serial = has_serial;
+ xfr->notify_serial = serial;
+ }
+}
+
+/** process a notify serial, start new probe or note serial. xfr is locked */
+static void
+xfr_process_notify(struct auth_xfer* xfr, struct module_env* env,
+ int has_serial, uint32_t serial, struct auth_master* fromhost)
+{
+ /* if the serial of notify is older than we have, don't fetch
+ * a zone, we already have it */
+ if(has_serial && !xfr_serial_means_update(xfr, serial)) {
+ lock_basic_unlock(&xfr->lock);
+ return;
+ }
+ /* start new probe with this addr src, or note serial */
+ if(!xfr_start_probe(xfr, env, fromhost)) {
+ /* not started because already in progress, note the serial */
+ xfr_note_notify_serial(xfr, has_serial, serial);
+ lock_basic_unlock(&xfr->lock);
+ }
+ /* successful end of start_probe unlocked xfr->lock */
+}
+
+int auth_zones_notify(struct auth_zones* az, struct module_env* env,
+ uint8_t* nm, size_t nmlen, uint16_t dclass,
+ struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
+ uint32_t serial, int* refused)
+{
+ struct auth_xfer* xfr;
+ struct auth_master* fromhost = NULL;
+ /* see which zone this is */
+ lock_rw_rdlock(&az->lock);
+ xfr = auth_xfer_find(az, nm, nmlen, dclass);
+ if(!xfr) {
+ lock_rw_unlock(&az->lock);
+ /* no such zone, refuse the notify */
+ *refused = 1;
+ return 0;
+ }
+ lock_basic_lock(&xfr->lock);
+ lock_rw_unlock(&az->lock);
+
+ /* check access list for notifies */
+ if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost)) {
+ lock_basic_unlock(&xfr->lock);
+ /* notify not allowed, refuse the notify */
+ *refused = 1;
+ return 0;
+ }
+
+ /* process the notify */
+ xfr_process_notify(xfr, env, has_serial, serial, fromhost);
+ return 1;
+}
+
/** set a zone expired */
static void
auth_xfer_set_expired(struct auth_xfer* xfr, struct module_env* env,
}
}
+/** copy a list of auth_addrs */
+static struct auth_addr*
+auth_addr_list_copy(struct auth_addr* source)
+{
+ struct auth_addr* list = NULL, *last = NULL;
+ struct auth_addr* p;
+ for(p=source; p; p=p->next) {
+ struct auth_addr* a = (struct auth_addr*)memdup(p, sizeof(*p));
+ if(!a) {
+ log_err("malloc failure");
+ auth_free_master_addrs(list);
+ return NULL;
+ }
+ a->next = NULL;
+ if(last) last->next = a;
+ if(!list) list = a;
+ last = a;
+ }
+ return list;
+}
+
+/** copy a master to a new structure, NULL on alloc failure */
+static struct auth_master*
+auth_master_copy(struct auth_master* o)
+{
+ struct auth_master* m;
+ if(!o) return NULL;
+ m = (struct auth_master*)memdup(o, sizeof(*o));
+ if(!m) {
+ log_err("malloc failure");
+ return NULL;
+ }
+ m->next = NULL;
+ if(m->host) {
+ m->host = strdup(m->host);
+ if(!m->host) {
+ free(m);
+ log_err("malloc failure");
+ return NULL;
+ }
+ }
+ if(m->file) {
+ m->file = strdup(m->file);
+ if(!m->file) {
+ free(m->host);
+ free(m);
+ log_err("malloc failure");
+ return NULL;
+ }
+ }
+ if(m->list) {
+ m->list = auth_addr_list_copy(m->list);
+ if(!m->list) {
+ free(m->file);
+ free(m->host);
+ free(m);
+ return NULL;
+ }
+ }
+ return m;
+}
+
+/** copy the master addresses from the task_probe lookups to the allow_notify
+ * list of masters */
+static void
+probe_copy_masters_for_allow_notify(struct auth_xfer* xfr)
+{
+ struct auth_master* list = NULL, *last = NULL;
+ struct auth_master* p;
+ /* build up new list with copies */
+ for(p = xfr->task_probe->masters; p; p=p->next) {
+ struct auth_master* m = auth_master_copy(p);
+ if(!m) {
+ auth_free_masters(list);
+ /* failed because of malloc failure, use old list */
+ return;
+ }
+ m->next = NULL;
+ if(last) last->next = m;
+ if(!list) list = m;
+ last = m;
+ }
+ /* success, replace list */
+ auth_free_masters(xfr->allow_notify_list);
+ xfr->allow_notify_list = list;
+}
+
/** start the lookups for task_transfer */
static void
xfr_transfer_start_lookups(struct auth_xfer* xfr)
if(xfr->task_transfer->scan_specific) {
xfr->task_transfer->scan_specific = NULL;
xfr->task_transfer->scan_target = xfr->task_transfer->masters;
+ if(xfr->task_transfer->scan_target && xfr->task_transfer->
+ scan_target->list)
+ xfr->task_transfer->scan_addr =
+ xfr->task_transfer->scan_target->list;
return;
}
if(!xfr->task_transfer->scan_target)
return;
xfr->task_transfer->scan_target = xfr->task_transfer->scan_target->next;
+ if(xfr->task_transfer->scan_target && xfr->task_transfer->
+ scan_target->list)
+ xfr->task_transfer->scan_addr =
+ xfr->task_transfer->scan_target->list;
return;
}
if(xfr->task_probe->scan_specific) {
xfr->task_probe->scan_specific = NULL;
xfr->task_probe->scan_target = xfr->task_probe->masters;
+ if(xfr->task_probe->scan_target && xfr->task_probe->
+ scan_target->list)
+ xfr->task_probe->scan_addr =
+ xfr->task_probe->scan_target->list;
return;
}
if(!xfr->task_probe->scan_target)
return;
xfr->task_probe->scan_target = xfr->task_probe->scan_target->next;
+ if(xfr->task_probe->scan_target && xfr->task_probe->
+ scan_target->list)
+ xfr->task_probe->scan_addr =
+ xfr->task_probe->scan_target->list;
return;
}
return 1;
}
-/** see if the serial means the zone has to be updated, i.e. the serial
- * is newer than the zone serial, or we have no zone */
-static int
-xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial)
-{
- if(!xfr->have_zone)
- return 1; /* no zone, anything is better */
- if(xfr->zone_expired)
- return 1; /* expired, the sent serial is better than expired
- data */
- 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,
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)
+/** check syntax of chunklist zonefile, parse first RR, return false on
+ * failure and return a string in the scratch buffer (first RR string)
* on failure. */
static int
http_zonefile_syntax_check(struct auth_xfer* xfr, sldns_buffer* buf)
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",
+ log_err("parse failure on first 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 "
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' && i==end-1) {
+ sldns_buffer_write_u8_at(buf, i, 0);
+ sldns_buffer_set_limit(buf, end-1);
+ return;
+ }
if(c == '\n')
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
}
return 1;
}
+/** write http chunks to zonefile to create downloaded file */
+static int
+auth_zone_write_chunks(struct auth_xfer* xfr, const char* fname)
+{
+ FILE* out;
+ struct auth_chunk* p;
+ out = fopen(fname, "w");
+ if(!out) {
+ log_err("could not open %s: %s", fname, strerror(errno));
+ return 0;
+ }
+ for(p = xfr->task_transfer->chunks_first; p ; p = p->next) {
+ if(!write_out(out, (char*)p->data, p->len)) {
+ log_err("could not write http download to %s", fname);
+ fclose(out);
+ return 0;
+ }
+ }
+ fclose(out);
+ return 1;
+}
+
/** write to zonefile after zone has been updated */
static void
xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
}
snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", z->zonefile,
(unsigned)getpid());
- if(!auth_zone_write_file(z, tmpfile)) {
+ if(xfr->task_transfer->master->http) {
+ /* use the stored chunk list to write them */
+ if(!auth_zone_write_chunks(xfr, tmpfile)) {
+ unlink(tmpfile);
+ lock_rw_unlock(&z->lock);
+ }
+ } else if(!auth_zone_write_file(z, tmpfile)) {
unlink(tmpfile);
lock_rw_unlock(&z->lock);
return;
/* not needed, host is in IP addr format */
return 0;
}
+ if(master->allow_notify)
+ return 0; /* allow-notifies are not transferred from, no
+ lookup is needed */
/* use mesh_new_callback to probe for non-addr hosts,
* and then wait for them to be looked up (in cache, or query) */
socklen_t addrlen = 0;
struct auth_master* master = xfr->task_transfer->master;
if(!master) return 0;
+ if(master->allow_notify) return 0; /* only for notify */
/* get master addr */
if(xfr->task_transfer->scan_addr) {
xfr_transfer_disown(xfr);
/* pick up the nextprobe task and wait */
- xfr_set_timeout(xfr, env, 1);
+ xfr_set_timeout(xfr, env, 1, 0);
lock_basic_unlock(&xfr->lock);
}
size_t i;
struct packed_rrset_data* data;
if(!m || !rrset) return;
+ if(rrtype != LDNS_RR_TYPE_A && rrtype != LDNS_RR_TYPE_AAAA)
+ return;
data = (struct packed_rrset_data*)rrset->entry.data;
for(i=0; i<data->count; i++) {
struct auth_addr* a;
/* 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);
+ if(xfr->notify_received && (!xfr->notify_has_serial ||
+ (xfr->notify_has_serial &&
+ xfr_serial_means_update(xfr, xfr->notify_serial)))) {
+ uint32_t sr = xfr->notify_serial;
+ int has_sr = xfr->notify_has_serial;
+ /* we received a notify while probe/transfer was
+ * in progress. start a new probe and transfer */
+ xfr->notify_received = 0;
+ xfr->notify_has_serial = 0;
+ xfr->notify_serial = 0;
+ if(!xfr_start_probe(xfr, env, NULL)) {
+ /* if we couldn't start it, already in
+ * progress; restore notify serial,
+ * while xfr still locked */
+ xfr->notify_received = 1;
+ xfr->notify_has_serial = has_sr;
+ xfr->notify_serial = sr;
+ lock_basic_unlock(&xfr->lock);
+ }
+ return;
+ } else {
+ /* pick up the nextprobe task and wait (normail wait time) */
+ xfr_set_timeout(xfr, env, 0, 0);
+ }
lock_basic_unlock(&xfr->lock);
return;
}
/* pick master */
struct auth_master* master = xfr_probe_current_master(xfr);
if(!master) return 0;
+ if(master->allow_notify) return 0; /* only for notify */
+ if(master->http) return 0; /* only masters get SOA UDP probe,
+ not urls, if those are in this list */
/* get master addr */
if(xfr->task_probe->scan_addr) {
if(xfr->have_zone)
xfr->lease_time = *env->now;
if(xfr->task_nextprobe->worker == NULL)
- xfr_set_timeout(xfr, env, 0);
+ xfr_set_timeout(xfr, env, 0, 0);
}
/* other tasks are running, we don't do this anymore */
xfr_probe_disown(xfr);
/* not needed, host is in IP addr format */
return 0;
}
+ if(master->allow_notify && !master->http &&
+ strchr(master->host, '/') != NULL &&
+ strchr(master->host, '/') == strrchr(master->host, '/')) {
+ return 0; /* is IP/prefix format, not something to look up */
+ }
/* use mesh_new_callback to probe for non-addr hosts,
* and then wait for them to be looked up (in cache, or query) */
}
xfr_probe_move_to_next_lookup(xfr, env);
}
+ /* probe of list has ended. Create or refresh the list of of
+ * allow_notify addrs */
+ probe_copy_masters_for_allow_notify(xfr);
+ if(xfr->task_probe->only_lookup) {
+ /* only wanted lookups for copy, stop probe and start wait */
+ xfr->task_probe->only_lookup = 0;
+ xfr_probe_disown(xfr);
+ xfr_set_timeout(xfr, env, 0, 0);
+ lock_basic_unlock(&xfr->lock);
+ return;
+ }
/* send probe packets */
while(!xfr_probe_end_of_list(xfr)) {
xfr_probe_disown(xfr);
/* pick up the nextprobe task and wait */
- xfr_set_timeout(xfr, env, 1);
+ xfr_set_timeout(xfr, env, 1, 0);
lock_basic_unlock(&xfr->lock);
}
xfr_nextprobe_disown(xfr);
+ if(!xfr_start_probe(xfr, env, NULL)) {
+ /* not started because already in progress */
+ lock_basic_unlock(&xfr->lock);
+ }
+}
+
+/** return true if there are probe (SOA UDP query) targets in the master list*/
+static int
+have_probe_targets(struct auth_master* list)
+{
+ struct auth_master* p;
+ for(p=list; p; p = p->next) {
+ if(!p->allow_notify && p->host)
+ return 1;
+ }
+ return 0;
+}
+
+/** start task_probe if possible, if no masters for probe start task_transfer
+ * returns true if task has been started, and false if the task is already
+ * in progress. */
+static int
+xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
+ struct auth_master* spec)
+{
/* 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) {
+ if(!have_probe_targets(xfr->task_probe->masters) &&
+ !(xfr->task_probe->only_lookup &&
+ 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);
+ xfr_start_transfer(xfr, env, spec);
+ return 1;
}
- return;
+ /* task transfer already in progress */
+ return 0;
}
/* pick up the probe task ourselves */
xfr->task_probe->cp = NULL;
/* start the task */
- /* this was a timeout, so no specific first master to scan */
- xfr_probe_start_list(xfr, NULL);
+ /* if this was a timeout, no specific first master to scan */
+ /* otherwise, spec is nonNULL the notified master, scan
+ * first and also transfer first from it */
+ xfr_probe_start_list(xfr, spec);
/* setup to start the lookup of hostnames of masters afresh */
xfr_probe_start_lookups(xfr);
/* send the probe packet or next send, or end task */
xfr_probe_send_or_end(xfr, env);
- } else {
- lock_basic_unlock(&xfr->lock);
+ return 1;
}
+ return 0;
}
/** for task_nextprobe.
* @param xfr: task structure
* @param env: module environment, with worker and time.
* @param failure: set true if timer should be set for failure retry.
+ * @param lookup_only: only perform lookups when timer done, 0 sec timeout
*/
static void
xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
- int failure)
+ int failure, int lookup_only)
{
struct timeval tv;
log_assert(xfr->task_nextprobe != NULL);
* 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->lease_time)
+ if(xfr->lease_time && !failure)
xfr->task_nextprobe->next_probe = xfr->lease_time;
if(!failure) {
if(failure)
xfr->task_nextprobe->next_probe +=
xfr->task_nextprobe->backoff;
+ /* put the timer exactly on expiry, if possible */
+ if(xfr->lease_time && xfr->lease_time+xfr->expiry <
+ xfr->task_nextprobe->next_probe &&
+ xfr->lease_time+xfr->expiry > *env->now)
+ xfr->task_nextprobe->next_probe =
+ xfr->lease_time+xfr->expiry;
} else {
xfr->task_nextprobe->next_probe +=
xfr->task_nextprobe->backoff;
tv.tv_sec = xfr->task_nextprobe->next_probe -
*(xfr->task_nextprobe->env->now);
else tv.tv_sec = 0;
+ if(tv.tv_sec != 0 && lookup_only && xfr->task_probe->masters) {
+ /* don't lookup_only, if lookup timeout is 0 anyway,
+ * or if we don't have masters to lookup */
+ tv.tv_sec = 0;
+ if(xfr->task_probe && xfr->task_probe->worker == NULL)
+ xfr->task_probe->only_lookup = 1;
+ }
if(verbosity >= VERB_ALGO) {
char zname[255+1];
dname_str(xfr->name, zname);
* 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);
+ if(x->task_nextprobe && x->task_nextprobe->worker == NULL) {
+ xfr_set_timeout(x, env, 0, 1);
+ }
lock_basic_unlock(&x->lock);
}
lock_rw_unlock(&az->lock);
return 0;
}
}
+ for(p = c->allow_notify; p; p = p->next) {
+ m = auth_master_new(&list);
+ m->allow_notify = 1;
+ m->host = strdup(p->str);
+ if(!m->host) {
+ log_err("malloc failure");
+ return 0;
+ }
+ }
return 1;
}
rbtree_type xtree;
/** do we have downstream enabled */
int have_downstream;
+ /** number of queries upstream */
+ size_t num_query_up;
+ /** number of queries downstream */
+ size_t num_query_down;
};
/**
/** for upstream: this zone answers queries that unbound intends to
* send upstream. */
int for_upstream;
+ /** zone has been deleted */
+ int zone_deleted;
+ /** deletelist pointer, unused normally except during delete */
+ struct auth_zone* delete_next;
};
/**
* Hold the lock to access this member (and the serial).
*/
int notify_received;
+ /** true if the notify_received has a serial number */
+ int notify_has_serial;
/** serial number of the notify */
uint32_t notify_serial;
+ /** the list of masters for checking notifies. This list is
+ * empty on start, and a copy of the list from the probe_task when
+ * it is done looking them up. */
+ struct auth_master* allow_notify_list;
/* protected by the lock on the structure, information about
* the loaded authority zone. */
struct auth_master* lookup_target;
/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
int lookup_aaaa;
+ /** we only want to do lookups for making config work (for notify),
+ * don't proceed with UDP SOA probe queries */
+ int only_lookup;
/** once notified, or the timeout has been reached. a scan starts. */
/** the scan specific target (notify source), or NULL if none */
int http;
/** use IXFR for this master */
int ixfr;
+ /** this is an allow notify member, the master can send notifies
+ * to us, but we don't send SOA probes, or zone transfer from it */
+ int allow_notify;
/** use ssl for channel */
int ssl;
/** the port number (for urls) */
int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
uint16_t dclass);
+/** process notify for auth zones.
+ * first checks the access list. Then processes the notify. This starts
+ * the probe sequence or it notes the serial number (if any)
+ * @param az: auth zones structure.
+ * @param env: module env of the worker that is handling the notify. it will
+ * pick up the task probe (or transfer), unless already in progress by
+ * another worker.
+ * @param nm: name of the zone. Uncompressed. from query.
+ * @param nmlen: length of name.
+ * @param dclass: class of zone.
+ * @param addr: source address of notify
+ * @param addrlen: length of addr.
+ * @param has_serial: if true, the notify has a serial attached.
+ * @param serial: the serial number, if has_serial is true.
+ * @param refused: is set to true on failure to note refused access.
+ * @return fail on failures (refused is false) and when access is
+ * denied (refused is true). True when processed.
+ */
+int auth_zones_notify(struct auth_zones* az, struct module_env* env,
+ uint8_t* nm, size_t nmlen, uint16_t dclass,
+ struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
+ uint32_t serial, int* refused);
+
+/** process notify packet and read serial number from SOA.
+ * returns 0 if no soa record in the notify */
+int auth_zone_parse_notify_serial(struct sldns_buffer* pkt, uint32_t *serial);
+
/** read auth zone from zonefile. caller must lock zone. false on failure */
int auth_zone_read_zonefile(struct auth_zone* z);
+/** find serial number of zone or false if none (no SOA record) */
+int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
+
/** compare auth_zones for sorted rbtree */
int auth_zone_cmp(const void* z1, const void* z2);
infra->host_ttl = cfg->host_ttl;
name_tree_init(&infra->domain_limits);
infra_dp_ratelimit = cfg->ratelimit;
- if(cfg->ratelimit != 0) {
- infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
- INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
- &rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
- &rate_deldatafunc, NULL);
- if(!infra->domain_rates) {
- infra_delete(infra);
- return NULL;
- }
- /* insert config data into ratelimits */
- if(!infra_ratelimit_cfg_insert(infra, cfg)) {
- infra_delete(infra);
- return NULL;
- }
- name_tree_init_parents(&infra->domain_limits);
+ infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
+ INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
+ &rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
+ &rate_deldatafunc, NULL);
+ if(!infra->domain_rates) {
+ infra_delete(infra);
+ return NULL;
+ }
+ /* insert config data into ratelimits */
+ if(!infra_ratelimit_cfg_insert(infra, cfg)) {
+ infra_delete(infra);
+ return NULL;
}
+ name_tree_init_parents(&infra->domain_limits);
infra_ip_ratelimit = cfg->ip_ratelimit;
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
wc_dname[1] = (uint8_t)'*';
memmove(wc_dname+2, ce, ce_len);
+ free(rrset->rk.dname);
rrset->rk.dname_len = ce_len + 2;
rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len);
if(!rrset->rk.dname) {
+ alloc_special_release(alloc, rrset);
log_err("memdup failure in rrset_cache_update_wildcard");
return;
}
return 1;
}
+/** see if interface is ssl, its port number == the ssl port number */
+static int
+if_is_ssl(const char* ifname, const char* port, int ssl_port,
+ struct config_strlist* tls_additional_port)
+{
+ struct config_strlist* s;
+ char* p = strchr(ifname, '@');
+ if(!p && atoi(port) == ssl_port)
+ return 1;
+ if(p && atoi(p+1) == ssl_port)
+ return 1;
+ for(s = tls_additional_port; s; s = s->next) {
+ if(p && atoi(p+1) == atoi(s->str))
+ return 1;
+ if(!p && atoi(port) == atoi(s->str))
+ return 1;
+ }
+ return 0;
+}
+
/**
* Helper for ports_open. Creates one interface (or NULL for default).
* @param ifname: The interface ip address.
* @param rcv: receive buffer size for UDP
* @param snd: send buffer size for UDP
* @param ssl_port: ssl service port number
+ * @param tls_additional_port: list of additional ssl service port numbers.
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
* set to false on exit if reuseport failed due to no kernel support.
* @param transparent: set IP_TRANSPARENT socket option.
static int
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
struct addrinfo *hints, const char* port, struct listen_port** list,
- size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent,
- int tcp_mss, int freebind, int use_systemd, int dnscrypt_port)
+ size_t rcv, size_t snd, int ssl_port,
+ struct config_strlist* tls_additional_port, int* reuseport,
+ int transparent, int tcp_mss, int freebind, int use_systemd,
+ int dnscrypt_port)
{
int s, noip6=0;
#ifdef USE_DNSCRYPT
}
}
if(do_tcp) {
- int is_ssl = ((strchr(ifname, '@') &&
- atoi(strchr(ifname, '@')+1) == ssl_port) ||
- (!strchr(ifname, '@') && atoi(port) == ssl_port));
+ int is_ssl = if_is_ssl(ifname, port, ssl_port,
+ tls_additional_port);
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
&noip6, 0, 0, reuseport, transparent, tcp_mss,
freebind, use_systemd)) == -1) {
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port, reuseport,
- cfg->ip_transparent,
+ cfg->ssl_port, cfg->tls_additional_port,
+ reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
listening_ports_free(list);
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port, reuseport,
- cfg->ip_transparent,
+ cfg->ssl_port, cfg->tls_additional_port,
+ reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
listening_ports_free(list);
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port, reuseport,
- cfg->ip_transparent,
+ cfg->ssl_port, cfg->tls_additional_port,
+ reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
listening_ports_free(list);
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port, reuseport,
- cfg->ip_transparent,
+ cfg->ssl_port, cfg->tls_additional_port,
+ reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
listening_ports_free(list);
comm_point_drop_reply(&rep->query_reply);
mesh->num_reply_addrs--;
}
- for(cb=mstate->cb_list; cb; cb=cb->next) {
+ while((cb = mstate->cb_list)!=NULL) {
+ mstate->cb_list = cb->next;
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
sec_status_unchecked, NULL);
else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL;
- if(!rcode && rep->security == sec_status_bogus) {
+ if(!rcode && (rep->security == sec_status_bogus ||
+ rep->security == sec_status_secure_sentinel_fail)) {
if(!(reason = errinf_to_str(&m->s)))
rcode = LDNS_RCODE_SERVFAIL;
}
/* examine security status */
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
m->s.env->cfg->ignore_cd) && rep &&
- rep->security <= sec_status_bogus) {
+ (rep->security <= sec_status_bogus ||
+ rep->security == sec_status_secure_sentinel_fail)) {
rcode = LDNS_RCODE_SERVFAIL;
if(m->s.env->cfg->stat_extended)
m->s.env->mesh->ans_bogus++;
}
}
mstate->replies_sent = 1;
- for(c = mstate->cb_list; c; c = c->next) {
+ while((c = mstate->cb_list) != NULL) {
+ /* take this cb off the list; so that the list can be
+ * changed, eg. by adds from the callback routine */
+ if(!mstate->reply_list && mstate->cb_list && !c->next) {
+ /* was a reply state, not anymore */
+ mstate->s.env->mesh->num_reply_states--;
+ }
+ mstate->cb_list = c->next;
+ if(!mstate->reply_list && !mstate->cb_list &&
+ mstate->super_set.count == 0)
+ mstate->s.env->mesh->num_detached_states++;
mesh_do_callback(mstate, mstate->s.return_rcode, rep, c);
}
}
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
#endif
pend->c->ssl_shake_state = comm_ssl_shake_write;
+#ifdef HAVE_SSL_SET1_HOST
+ if(w->tls_auth_name) {
+ SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
+ /* setting the hostname makes openssl verify the
+ * host name in the x509 certificate in the
+ * SSL connection*/
+ if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
+ log_err("SSL_set1_host failed");
+ pend->c->fd = s;
+ comm_point_close(pend->c);
+ return 0;
+ }
+ }
+#endif /* HAVE_SSL_SET1_HOST */
}
w->pkt = NULL;
w->next_waiting = (void*)pend;
struct service_callback* p = sq->cblist, *np;
free(sq->qbuf);
free(sq->zone);
+ free(sq->tls_auth_name);
edns_opt_list_free(sq->opt_list);
while(p) {
np = p->next;
w->cb = callback;
w->cb_arg = callback_arg;
w->ssl_upstream = sq->ssl_upstream;
+ w->tls_auth_name = sq->tls_auth_name;
#ifndef S_SPLINT_S
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
+ tv.tv_sec = timeout/1000;
+ tv.tv_usec = (timeout%1000)*1000;
#endif
comm_timer_set(w->timer, &tv);
if(pend) {
static struct serviced_query*
serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
- struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
- size_t zonelen, int qtype, struct edns_option* opt_list)
+ char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
+ uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list)
{
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
#ifdef UNBOUND_DEBUG
sq->nocaps = nocaps;
sq->tcp_upstream = tcp_upstream;
sq->ssl_upstream = ssl_upstream;
+ if(tls_auth_name) {
+ sq->tls_auth_name = strdup(tls_auth_name);
+ if(!sq->tls_auth_name) {
+ free(sq->zone);
+ free(sq->qbuf);
+ free(sq);
+ return NULL;
+ }
+ } else {
+ sq->tls_auth_name = NULL;
+ }
memcpy(&sq->addr, addr, addrlen);
sq->addrlen = addrlen;
sq->opt_list = NULL;
if(opt_list) {
sq->opt_list = edns_opt_copy_alloc(opt_list);
if(!sq->opt_list) {
+ free(sq->tls_auth_name);
free(sq->zone);
free(sq->qbuf);
free(sq);
}
if(sq->tcp_upstream || sq->ssl_upstream) {
struct timeval now = *sq->outnet->now_tv;
- if(now.tv_sec > sq->last_sent_time.tv_sec ||
+ if(error!=NETEVENT_NOERROR) {
+ if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
+ sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
+ -1, sq->last_rtt, (time_t)now.tv_sec))
+ log_err("out of memory in TCP exponential backoff.");
+ } else if(now.tv_sec > sq->last_sent_time.tv_sec ||
(now.tv_sec == sq->last_sent_time.tv_sec &&
now.tv_usec > sq->last_sent_time.tv_usec)) {
/* convert from microseconds to milliseconds */
log_assert(roundtime >= 0);
/* only store if less then AUTH_TIMEOUT seconds, it could be
* huge due to system-hibernated and we woke up */
- if(roundtime < TCP_AUTH_QUERY_TIMEOUT*1000) {
+ if(roundtime < 60000) {
if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
roundtime, sq->last_rtt, (time_t)now.tv_sec))
static int
serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
{
- int vs, rtt;
+ int vs, rtt, timeout;
uint8_t edns_lame_known;
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone,
sq->zonelen, *sq->outnet->now_secs, &vs, &edns_lame_known,
&rtt))
return 0;
+ sq->last_rtt = rtt;
if(vs != -1)
sq->status = serviced_query_TCP_EDNS;
else sq->status = serviced_query_TCP;
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
sq->last_sent_time = *sq->outnet->now_tv;
- sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT,
+ if(sq->tcp_upstream || sq->ssl_upstream) {
+ timeout = rtt;
+ if(rtt >= 376 && rtt < TCP_AUTH_QUERY_TIMEOUT)
+ timeout = TCP_AUTH_QUERY_TIMEOUT;
+ } else {
+ timeout = TCP_AUTH_QUERY_TIMEOUT;
+ }
+ sq->pending = pending_tcp_query(sq, buff, timeout,
serviced_tcp_callback, sq);
return sq->pending != NULL;
}
struct serviced_query*
outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
- int nocaps, int tcp_upstream, int ssl_upstream,
+ int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, struct module_qstate* qstate,
comm_point_callback_type* callback, void* callback_arg, sldns_buffer* buff,
if(!sq) {
/* make new serviced query entry */
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
- tcp_upstream, ssl_upstream, addr, addrlen, zone,
- zonelen, (int)qinfo->qtype, qstate->edns_opts_back_out);
+ tcp_upstream, ssl_upstream, tls_auth_name, addr,
+ addrlen, zone, zonelen, (int)qinfo->qtype,
+ qstate->edns_opts_back_out);
if(!sq) {
free(cb);
return NULL;
void* cb_arg;
/** if it uses ssl upstream */
int ssl_upstream;
+ /** ref to the tls_auth_name from the serviced_query */
+ char* tls_auth_name;
};
/**
int nocaps;
/** tcp upstream used, use tcp, or ssl_upstream for SSL */
int tcp_upstream, ssl_upstream;
+ /** the name of the tls authentication name, eg. 'ns.example.com'
+ * or NULL */
+ char* tls_auth_name;
/** where to send it */
struct sockaddr_storage addr;
/** length of addr field in use. */
int retry;
/** time last UDP was sent */
struct timeval last_sent_time;
- /** rtt of last (UDP) message */
+ /** rtt of last message */
int last_rtt;
/** do we know edns probe status already, for UDP_EDNS queries */
int edns_lame_known;
* checks id.
* @param sq: serviced query.
* @param packet: wireformat query to send to destination. copied from.
- * @param timeout: in seconds from now.
+ * @param timeout: in milliseconds from now.
* Timer starts running now. Timer may expire if all buffers are used,
* without any query been sent to the server yet.
* @param callback: function to call on error, timeout or reply.
* @param nocaps: ignore use_caps_for_id and use unperturbed qname.
* @param tcp_upstream: use TCP for upstream queries.
* @param ssl_upstream: use SSL for upstream queries.
+ * @param tls_auth_name: when ssl_upstream is true, use this name to check
+ * the server's peer certificate.
* @param addr: to which server to send the query.
* @param addrlen: length of addr.
* @param zone: name of the zone of the delegation point. wireformat dname.
*/
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
- int nocaps, int tcp_upstream, int ssl_upstream,
+ int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, struct module_qstate* qstate,
comm_point_callback_type* callback, void* callback_arg,
return 256;
case LDNS_ECDSAP384SHA384:
return 384;
+#endif
+#ifdef USE_ED25519
+ case LDNS_ED25519:
+ return 256;
+#endif
+#ifdef USE_ED448
+ case LDNS_ED448:
+ return 456;
#endif
default:
return 0;
}
#endif /* USE_ED25519 */
+#ifdef USE_ED448
+EVP_PKEY*
+sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
+{
+ /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
+ uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
+ 0x71, 0x03, 0x3a, 0x00};
+ int pre_len = 12;
+ uint8_t buf[256];
+ EVP_PKEY *evp_key;
+ /* pp gets modified by d2i() */
+ const unsigned char* pp = (unsigned char*)buf;
+ if(keylen != 57 || keylen + pre_len > sizeof(buf))
+ return NULL; /* wrong length */
+ memmove(buf, pre, pre_len);
+ memmove(buf+pre_len, key, keylen);
+ evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
+ return evp_key;
+}
+#endif /* USE_ED448 */
+
int
sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
const EVP_MD* md)
*/
EVP_PKEY* sldns_ed255192pkey_raw(const unsigned char* key, size_t len);
+/**
+ * Converts a holding buffer with key material to EVP PKEY in openssl.
+ * Only available if ldns was compiled with ED448.
+ * \param[in] key the uncompressed wireformat of the key.
+ * \param[in] len length of key data
+ * \return the key or NULL on error.
+ */
+EVP_PKEY* sldns_ed4482pkey_raw(const unsigned char* key, size_t len);
+
/**
* Utility function to calculate hash using generic EVP_MD pointer.
* \param[in] data the data to hash.
return LDNS_WIREPARSE_ERR_OK;
}
+/** see if the string ends, or ends in whitespace */
+static int
+sldns_is_last_of_string(const char* str)
+{
+ if(*str == 0) return 1;
+ while(isspace((unsigned char)*str))
+ str++;
+ if(*str == 0) return 1;
+ return 0;
+}
+
int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
{
const char* s = str;
s++;
continue;
}
- if(dlen == 0 && *s == '0' && *(s+1) == 0) {
+ if(dlen == 0 && *s == '0' && sldns_is_last_of_string(s+1)) {
*len = 0;
return LDNS_WIREPARSE_ERR_OK;
}
# endif
}
#endif
- if(cfg->remote_control_enable && cfg->remote_control_use_cert) {
+ if(cfg->remote_control_enable && options_remote_is_address(cfg)
+ && cfg->control_use_cert) {
check_chroot_string("server-key-file", &cfg->server_key_file,
cfg->chrootdir, cfg);
check_chroot_string("server-cert-file", &cfg->server_cert_file,
printf(" ratelimit_list [+a] list ratelimited domains\n");
printf(" ip_ratelimit_list [+a] list ratelimited ip addresses\n");
printf(" +a list all, also not ratelimited\n");
+ printf(" list_auth_zones list auth zones\n");
printf(" view_list_local_zones view list local-zones in view\n");
printf(" view_list_local_data view list local-data RRs in view\n");
printf(" view_local_zone view name type add local-zone in view\n");
PR_UL("num.answer.secure", s->svr.ans_secure);
PR_UL("num.answer.bogus", s->svr.ans_bogus);
PR_UL("num.rrset.bogus", s->svr.rrset_bogus);
+ PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror);
+ PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain);
/* threat detection */
PR_UL("unwanted.queries", s->svr.unwanted_queries);
PR_UL("unwanted.replies", s->svr.unwanted_replies);
PR_UL("num.query.dnscrypt.replay",
s->svr.num_query_dnscrypt_replay);
#endif /* USE_DNSCRYPT */
+ PR_UL("num.query.authzone.up", s->svr.num_query_authzone_up);
+ PR_UL("num.query.authzone.down", s->svr.num_query_authzone_down);
}
/** print statistics out of memory structures */
char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
SSL_CTX* ctx;
- if(cfg->remote_control_use_cert) {
- s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
- c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
- c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
- if(!s_cert || !c_key || !c_cert)
- fatal_exit("out of memory");
- }
+ if(!(options_remote_is_address(cfg) && cfg->control_use_cert))
+ return NULL;
+ s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
+ c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
+ c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
+ if(!s_cert || !c_key || !c_cert)
+ fatal_exit("out of memory");
ctx = SSL_CTX_new(SSLv23_client_method());
if(!ctx)
ssl_err("could not allocate SSL_CTX pointer");
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
!= SSL_OP_NO_SSLv2)
ssl_err("could not set SSL_OP_NO_SSLv2");
- if(cfg->remote_control_use_cert) {
- if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
- != SSL_OP_NO_SSLv3)
- ssl_err("could not set SSL_OP_NO_SSLv3");
- if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
- !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
- || !SSL_CTX_check_private_key(ctx))
- ssl_err("Error setting up SSL_CTX client key and cert");
- if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
- ssl_err("Error setting up SSL_CTX verify, server cert");
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
-
- free(s_cert);
- free(c_key);
- free(c_cert);
- } else {
- /* Use ciphers that don't require authentication */
-#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
- SSL_CTX_set_security_level(ctx, 0);
-#endif
- if(!SSL_CTX_set_cipher_list(ctx, "aNULL, eNULL"))
- ssl_err("Error setting NULL cipher!");
- }
+ if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
+ != SSL_OP_NO_SSLv3)
+ ssl_err("could not set SSL_OP_NO_SSLv3");
+ if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
+ !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
+ || !SSL_CTX_check_private_key(ctx))
+ ssl_err("Error setting up SSL_CTX client key and cert");
+ if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
+ ssl_err("Error setting up SSL_CTX verify, server cert");
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
+
+ free(s_cert);
+ free(c_key);
+ free(c_cert);
return ctx;
}
{
struct sockaddr_storage addr;
socklen_t addrlen;
- int addrfamily = 0;
- int fd;
+ int addrfamily = 0, proto = IPPROTO_TCP;
+ int fd, useport = 1;
/* use svr or the first config entry */
if(!svr) {
- if(cfg->control_ifs) {
- svr = cfg->control_ifs->str;
+ if(cfg->control_ifs.first) {
+ svr = cfg->control_ifs.first->str;
} else if(cfg->do_ip4) {
svr = "127.0.0.1";
} else {
(void)strlcpy(usock->sun_path, svr, sizeof(usock->sun_path));
addrlen = (socklen_t)sizeof(struct sockaddr_un);
addrfamily = AF_LOCAL;
+ useport = 0;
+ proto = 0;
#endif
} else {
if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
}
if(addrfamily == 0)
- addrfamily = addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET;
- fd = socket(addrfamily, SOCK_STREAM, 0);
+ addrfamily = addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET;
+ fd = socket(addrfamily, SOCK_STREAM, proto);
if(fd == -1) {
#ifndef USE_WINSOCK
fatal_exit("socket: %s", strerror(errno));
}
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
#ifndef USE_WINSOCK
- log_err_addr("connect", strerror(errno), &addr, addrlen);
- if(errno == ECONNREFUSED && statuscmd) {
+ int err = errno;
+ if(!useport) log_err("connect: %s for %s", strerror(err), svr);
+ else log_err_addr("connect", strerror(err), &addr, addrlen);
+ if(err == ECONNREFUSED && statuscmd) {
printf("unbound is stopped\n");
exit(3);
}
#else
- log_err_addr("connect", wsa_strerror(WSAGetLastError()), &addr, addrlen);
- if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) {
+ int wsaerr = WSAGetLastError();
+ if(!useport) log_err("connect: %s for %s", wsa_strerror(wsaerr), svr);
+ else log_err_addr("connect", wsa_strerror(wsaerr), &addr, addrlen);
+ if(wsaerr == WSAECONNREFUSED && statuscmd) {
printf("unbound is stopped\n");
exit(3);
}
/** setup SSL on the connection */
static SSL*
-setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg)
+setup_ssl(SSL_CTX* ctx, int fd)
{
SSL* ssl;
X509* x;
int r;
+ if(!ctx) return NULL;
ssl = SSL_new(ctx);
if(!ssl)
ssl_err("could not SSL_new");
/* check authenticity of server */
if(SSL_get_verify_result(ssl) != X509_V_OK)
ssl_err("SSL verification failed");
- if(cfg->remote_control_use_cert) {
- x = SSL_get_peer_certificate(ssl);
- if(!x)
- ssl_err("Server presented no peer certificate");
- X509_free(x);
- }
+ x = SSL_get_peer_certificate(ssl);
+ if(!x)
+ ssl_err("Server presented no peer certificate");
+ X509_free(x);
return ssl;
}
+/** read from ssl or fd, fatalexit on error, 0 EOF, 1 success */
+static int
+remote_read(SSL* ssl, int fd, char* buf, size_t len)
+{
+ if(ssl) {
+ int r;
+ ERR_clear_error();
+ if((r = SSL_read(ssl, buf, (int)len-1)) <= 0) {
+ if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
+ /* EOF */
+ return 0;
+ }
+ ssl_err("could not SSL_read");
+ }
+ buf[r] = 0;
+ } else {
+ ssize_t rr = recv(fd, buf, len-1, 0);
+ if(rr <= 0) {
+ if(rr == 0) {
+ /* EOF */
+ return 0;
+ }
+#ifndef USE_WINSOCK
+ fatal_exit("could not recv: %s", strerror(errno));
+#else
+ fatal_exit("could not recv: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ }
+ buf[rr] = 0;
+ }
+ return 1;
+}
+
+/** write to ssl or fd, fatalexit on error */
+static void
+remote_write(SSL* ssl, int fd, const char* buf, size_t len)
+{
+ if(ssl) {
+ if(SSL_write(ssl, buf, (int)len) <= 0)
+ ssl_err("could not SSL_write");
+ } else {
+ if(send(fd, buf, len, 0) < (ssize_t)len) {
+#ifndef USE_WINSOCK
+ fatal_exit("could not send: %s", strerror(errno));
+#else
+ fatal_exit("could not send: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ }
+ }
+}
+
/** send stdin to server */
static void
-send_file(SSL* ssl, FILE* in, char* buf, size_t sz)
+send_file(SSL* ssl, int fd, FILE* in, char* buf, size_t sz)
{
while(fgets(buf, (int)sz, in)) {
- if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0)
- ssl_err("could not SSL_write contents");
+ remote_write(ssl, fd, buf, strlen(buf));
}
}
/** send end-of-file marker to server */
static void
-send_eof(SSL* ssl)
+send_eof(SSL* ssl, int fd)
{
char e[] = {0x04, 0x0a};
- if(SSL_write(ssl, e, (int)sizeof(e)) <= 0)
- ssl_err("could not SSL_write end-of-file marker");
+ remote_write(ssl, fd, e, sizeof(e));
}
/** send command and display result */
static int
-go_cmd(SSL* ssl, int quiet, int argc, char* argv[])
+go_cmd(SSL* ssl, int fd, int quiet, int argc, char* argv[])
{
char pre[10];
const char* space=" ";
const char* newline="\n";
int was_error = 0, first_line = 1;
- int r, i;
+ int i;
char buf[1024];
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
- if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0)
- ssl_err("could not SSL_write");
+ remote_write(ssl, fd, pre, strlen(pre));
for(i=0; i<argc; i++) {
- if(SSL_write(ssl, space, (int)strlen(space)) <= 0)
- ssl_err("could not SSL_write");
- if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0)
- ssl_err("could not SSL_write");
+ remote_write(ssl, fd, space, strlen(space));
+ remote_write(ssl, fd, argv[i], strlen(argv[i]));
}
- if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0)
- ssl_err("could not SSL_write");
+ remote_write(ssl, fd, newline, strlen(newline));
if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
- send_file(ssl, stdin, buf, sizeof(buf));
+ send_file(ssl, fd, stdin, buf, sizeof(buf));
}
else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 ||
strcmp(argv[0], "local_zones_remove") == 0 ||
strcmp(argv[0], "local_datas") == 0 ||
strcmp(argv[0], "local_datas_remove") == 0)) {
- send_file(ssl, stdin, buf, sizeof(buf));
- send_eof(ssl);
+ send_file(ssl, fd, stdin, buf, sizeof(buf));
+ send_eof(ssl, fd);
}
while(1) {
- ERR_clear_error();
- if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
- if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
- /* EOF */
- break;
- }
- ssl_err("could not SSL_read");
+ if(remote_read(ssl, fd, buf, sizeof(buf)) == 0) {
+ break; /* EOF */
}
- buf[r] = 0;
if(first_line && strncmp(buf, "error", 5) == 0) {
printf("%s", buf);
was_error = 1;
/* contact server */
fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0);
- ssl = setup_ssl(ctx, fd, cfg);
+ ssl = setup_ssl(ctx, fd);
/* send command */
- ret = go_cmd(ssl, quiet, argc, argv);
+ ret = go_cmd(ssl, fd, quiet, argc, argv);
- SSL_free(ssl);
+ if(ssl) SSL_free(ssl);
#ifndef USE_WINSOCK
close(fd);
#else
closesocket(fd);
#endif
- SSL_CTX_free(ctx);
+ if(ctx) SSL_CTX_free(ctx);
config_delete(cfg);
return ret;
}
/* nss3 */
#include "nss.h"
#endif
+#ifdef HAVE_SSL
+#ifdef HAVE_OPENSSL_SSL_H
+#include <openssl/ssl.h>
+#endif
+#ifdef HAVE_OPENSSL_ERR_H
+#include <openssl/err.h>
+#endif
+#endif /* HAVE_SSL */
/** verbosity for unbound-host app */
static int verb = 0;
if(argc != 1)
usage();
+#ifdef HAVE_SSL
+#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
+ ERR_load_crypto_strings();
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
+ ERR_load_SSL_strings();
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
+ OpenSSL_add_all_algorithms();
+#else
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
+ | OPENSSL_INIT_ADD_ALL_DIGESTS
+ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
+ (void)SSL_library_init();
+#else
+ (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
+#endif
+#endif /* HAVE_SSL */
#ifdef HAVE_NSS
if(NSS_NoDB_Init(".") != SECSuccess) {
fprintf(stderr, "could not init NSS\n");
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
- struct module_qstate* ATTR_UNUSED(q))
+ char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
return 0;
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
- struct module_qstate* ATTR_UNUSED(q))
+ char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
return 0;
}
}
+/** free the special list */
+static void
+alloc_clear_special_list(struct alloc_cache* alloc)
+{
+ alloc_special_type* p, *np;
+ /* free */
+ p = alloc->quar;
+ while(p) {
+ np = alloc_special_next(p);
+ /* deinit special type */
+ lock_rw_destroy(&p->entry.lock);
+ free(p);
+ p = np;
+ }
+}
+
+void
+alloc_clear_special(struct alloc_cache* alloc)
+{
+ if(!alloc->super) {
+ lock_quick_lock(&alloc->lock);
+ }
+ alloc_clear_special_list(alloc);
+ alloc->quar = 0;
+ alloc->num_quar = 0;
+ if(!alloc->super) {
+ lock_quick_unlock(&alloc->lock);
+ }
+}
+
void
alloc_clear(struct alloc_cache* alloc)
{
- alloc_special_type* p, *np;
+ alloc_special_type* p;
struct regional* r, *nr;
if(!alloc)
return;
alloc->super->num_quar += alloc->num_quar;
lock_quick_unlock(&alloc->super->lock);
} else {
- /* free */
- p = alloc->quar;
- while(p) {
- np = alloc_special_next(p);
- /* deinit special type */
- lock_rw_destroy(&p->entry.lock);
- free(p);
- p = np;
- }
+ alloc_clear_special_list(alloc);
}
alloc->quar = 0;
alloc->num_quar = 0;
*/
void alloc_clear(struct alloc_cache* alloc);
+/**
+ * Free the special alloced items. The rrset and message caches must be
+ * empty, there must be no more references to rrset pointers into the
+ * rrset cache.
+ * @param alloc: the special allocs are freed.
+ */
+void alloc_clear_special(struct alloc_cache* alloc);
+
/**
* Get a new special_type element.
* @param alloc: where to alloc it.
cfg->outgoing_tcp_mss = 0;
cfg->ssl_service_key = NULL;
cfg->ssl_service_pem = NULL;
- cfg->ssl_port = 853;
+ cfg->ssl_port = UNBOUND_DNS_OVER_TLS_PORT;
cfg->ssl_upstream = 0;
cfg->tls_cert_bundle = NULL;
+ cfg->tls_win_cert = 0;
cfg->use_syslog = 1;
cfg->log_identity = NULL; /* changed later with argv[0] */
cfg->log_time_ascii = 0;
if(!(cfg->logfile = strdup(""))) goto error_exit;
if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit;
if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
+ cfg->low_rtt_permil = 0;
+ cfg->low_rtt = 45;
cfg->donotqueryaddrs = NULL;
cfg->donotquery_localhost = 1;
cfg->root_hints = NULL;
cfg->trust_anchor_list = NULL;
cfg->trusted_keys_file_list = NULL;
cfg->trust_anchor_signaling = 0;
+ cfg->root_key_sentinel = 1;
cfg->dlv_anchor_file = NULL;
cfg->dlv_anchor_list = NULL;
cfg->domain_insecure = NULL;
cfg->insecure_lan_zones = 0;
cfg->python_script = NULL;
cfg->remote_control_enable = 0;
- cfg->control_ifs = NULL;
+ cfg->control_ifs.first = NULL;
+ cfg->control_ifs.last = NULL;
cfg->control_port = UNBOUND_CONTROL_PORT;
- cfg->remote_control_use_cert = 1;
+ cfg->control_use_cert = 1;
cfg->minimal_responses = 0;
cfg->rrset_roundrobin = 0;
cfg->max_udp_size = 4096;
cfg->ratelimit_below_domain = NULL;
cfg->ip_ratelimit_factor = 10;
cfg->ratelimit_factor = 10;
- cfg->qname_minimisation = 0;
+ cfg->qname_minimisation = 1;
cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0;
cfg->shm_key = 11777;
#define S_STRLIST_UNIQ(str, var) if(strcmp(opt, str)==0) \
{ if(cfg_strlist_find(cfg->var, val)) { return 0;} \
return cfg_strlist_insert(&cfg->var, strdup(val)); }
+/** append string to strlist */
+#define S_STRLIST_APPEND(str, var) if(strcmp(opt, str)==0) \
+ { return cfg_strlist_append(&cfg->var, strdup(val)); }
int config_set_option(struct config_file* cfg, const char* opt,
const char* val)
{
+ char buf[64];
+ if(!opt) return 0;
+ if(opt[strlen(opt)-1] != ':' && strlen(opt)+2<sizeof(buf)) {
+ snprintf(buf, sizeof(buf), "%s:", opt);
+ opt = buf;
+ }
S_NUMBER_OR_ZERO("verbosity:", verbosity)
else if(strcmp(opt, "statistics-interval:") == 0) {
if(strcmp(val, "0") == 0 || strcmp(val, "") == 0)
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("tls-win-cert:", tls_win_cert)
+ else S_STRLIST("additional-tls-port:", tls_additional_port)
+ else S_STRLIST("tls-additional-ports:", tls_additional_port)
+ else S_STRLIST("tls-additional-port:", tls_additional_port)
else S_YNO("interface-automatic:", if_automatic)
else S_YNO("use-systemd:", use_systemd)
else S_YNO("do-daemonize:", do_daemonize)
else S_YNO("harden-below-nxdomain:", harden_below_nxdomain)
else S_YNO("harden-referral-path:", harden_referral_path)
else S_YNO("harden-algo-downgrade:", harden_algo_downgrade)
- else S_YNO("use-caps-for-id", use_caps_bits_for_id)
+ else S_YNO("use-caps-for-id:", use_caps_bits_for_id)
else S_STRLIST("caps-whitelist:", caps_whitelist)
else S_SIZET_OR_ZERO("unwanted-reply-threshold:", unwanted_threshold)
else S_STRLIST("private-address:", private_address)
else S_STRLIST("trust-anchor:", trust_anchor_list)
else S_STRLIST("trusted-keys-file:", trusted_keys_file_list)
else S_YNO("trust-anchor-signaling:", trust_anchor_signaling)
+ else S_YNO("root-key-sentinel:", root_key_sentinel)
else S_STR("dlv-anchor-file:", dlv_anchor_file)
else S_STRLIST("dlv-anchor:", dlv_anchor_list)
else S_STRLIST("domain-insecure:", domain_insecure)
else S_YNO("unblock-lan-zones:", unblock_lan_zones)
else S_YNO("insecure-lan-zones:", insecure_lan_zones)
else S_YNO("control-enable:", remote_control_enable)
- else S_STRLIST("control-interface:", control_ifs)
+ else S_STRLIST_APPEND("control-interface:", control_ifs)
else S_NUMBER_NONZERO("control-port:", control_port)
else S_STR("server-key-file:", server_key_file)
else S_STR("server-cert-file:", server_cert_file)
else S_POW2("ratelimit-slabs:", ratelimit_slabs)
else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
+ else S_NUMBER_OR_ZERO("low-rtt:", low_rtt)
+ else S_NUMBER_OR_ZERO("low-rtt-pct:", low_rtt_permil)
+ else S_NUMBER_OR_ZERO("low-rtt-permil:", low_rtt_permil)
else S_YNO("qname-minimisation:", qname_minimisation)
else S_YNO("qname-minimisation-strict:", qname_minimisation_strict)
#ifdef USE_IPSECMOD
config_get_option(struct config_file* cfg, const char* opt,
void (*func)(char*,void*), void* arg)
{
- char buf[1024];
+ char buf[1024], nopt[64];
size_t len = sizeof(buf);
+ if(opt && opt[strlen(opt)-1] == ':' && strlen(opt)<sizeof(nopt)) {
+ memmove(nopt, opt, strlen(opt));
+ nopt[strlen(opt)-1] = 0;
+ opt = nopt;
+ }
fptr_ok(fptr_whitelist_print_func(func));
O_DEC(opt, "verbosity", verbosity)
else O_DEC(opt, "statistics-interval", stat_interval)
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, "tls-win-cert", tls_win_cert)
+ else O_LST(opt, "tls-additional-port", tls_additional_port)
else O_YNO(opt, "use-systemd", use_systemd)
else O_YNO(opt, "do-daemonize", do_daemonize)
else O_STR(opt, "chroot", chrootdir)
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, "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)
else O_LST(opt, "trust-anchor", trust_anchor_list)
else O_LST(opt, "trusted-keys-file", trusted_keys_file_list)
else O_YNO(opt, "trust-anchor-signaling", trust_anchor_signaling)
+ else O_YNO(opt, "root-key-sentinel", root_key_sentinel)
else O_LST(opt, "dlv-anchor", dlv_anchor_list)
- else O_LST(opt, "control-interface", control_ifs)
+ else O_LST(opt, "control-interface", control_ifs.first)
else O_LST(opt, "domain-insecure", domain_insecure)
else O_UNS(opt, "val-override-date", val_date_override)
else O_YNO(opt, "minimal-responses", minimal_responses)
else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
+ else O_DEC(opt, "low-rtt", low_rtt)
+ else O_DEC(opt, "low-rtt-pct", low_rtt_permil)
+ else O_DEC(opt, "low-rtt-permil", low_rtt_permil)
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
else O_YNO(opt, "qname-minimisation", qname_minimisation)
free(p->name);
config_delstrlist(p->masters);
config_delstrlist(p->urls);
+ config_delstrlist(p->allow_notify);
free(p->zonefile);
free(p);
}
free(cfg->ssl_service_key);
free(cfg->ssl_service_pem);
free(cfg->tls_cert_bundle);
+ config_delstrlist(cfg->tls_additional_port);
free(cfg->log_identity);
config_del_strarray(cfg->ifs, cfg->num_ifs);
config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
config_del_strbytelist(cfg->respip_tags);
config_deltrplstrlist(cfg->acl_tag_actions);
config_deltrplstrlist(cfg->acl_tag_datas);
- config_delstrlist(cfg->control_ifs);
+ config_delstrlist(cfg->control_ifs.first);
free(cfg->server_key_file);
free(cfg->server_cert_file);
free(cfg->control_key_file);
snprintf(b, sizeof(b), "%s %s", str, buf);
errinf(qstate, b);
}
+
+int options_remote_is_address(struct config_file* cfg)
+{
+ if(!cfg->remote_control_enable) return 0;
+ if(!cfg->control_ifs.first) return 1;
+ if(!cfg->control_ifs.first->str) return 1;
+ if(cfg->control_ifs.first->str[0] == 0) return 1;
+ return (cfg->control_ifs.first->str[0] != '/');
+}
struct ub_packed_rrset_key;
struct regional;
+/** List head for strlist processing, used for append operation. */
+struct config_strlist_head {
+ /** first in list of text items */
+ struct config_strlist* first;
+ /** last in list of text items */
+ struct config_strlist* last;
+};
+
/**
* The configuration options.
* Strings are malloced.
int ssl_upstream;
/** cert bundle for outgoing connections */
char* tls_cert_bundle;
+ /** should the system certificate store get added to the cert bundle */
+ int tls_win_cert;
+ /** additional tls ports */
+ struct config_strlist* tls_additional_port;
/** outgoing port range number of ports (per thread) */
int outgoing_num_ports;
/** the target fetch policy for the iterator */
char* target_fetch_policy;
+ /** percent*10, how many times in 1000 to pick low rtt destinations */
+ int low_rtt_permil;
+ /** what time in msec is a low rtt destination */
+ int low_rtt;
/** automatic interface for incoming messages. Uses ipv6 remapping,
* and recvmsg/sendmsg ancillary data to detect interfaces, boolean */
struct config_strlist* domain_insecure;
/** send key tag query */
int trust_anchor_signaling;
+ /** enable root key sentinel */
+ int root_key_sentinel;
/** if not 0, this value is the validation date for RRSIGs */
int32_t val_date_override;
/** remote control section. enable toggle. */
int remote_control_enable;
/** the interfaces the remote control should listen on */
- struct config_strlist* control_ifs;
+ struct config_strlist_head control_ifs;
+ /** if the use-cert option is set */
+ int control_use_cert;
/** port number for the control port */
int control_port;
- /** use certificates for remote control */
- int remote_control_use_cert;
/** private key file for server */
char* server_key_file;
/** certificate file for server */
char* cachedb_backend;
/** secret seed for hash key calculation */
char* cachedb_secret;
+#ifdef USE_REDIS
+ /** redis server's IP address or host name */
+ char* redis_server_host;
+ /** redis server's TCP port */
+ int redis_server_port;
+ /** timeout (in ms) for communication with the redis server */
+ int redis_timeout;
+#endif
#endif
};
struct config_strlist* masters;
/** list of urls */
struct config_strlist* urls;
+ /** list of allow-notify */
+ struct config_strlist* allow_notify;
/** zonefile (or NULL) */
char* zonefile;
/** provide downstream answers */
size_t str2len;
};
-/** List head for strlist processing, used for append operation. */
-struct config_strlist_head {
- /** first in list of text items */
- struct config_strlist* first;
- /** last in list of text items */
- struct config_strlist* last;
-};
-
/**
* Create config file structure. Filled with default values.
* @return: the new structure or NULL on memory error.
*/
void config_delviews(struct config_view* list);
+/** check if config for remote control turns on IP-address interface
+ * with certificates or a named pipe without certificates. */
+int options_remote_is_address(struct config_file* cfg);
+
/**
* Convert 14digit to time value
* @param str: string of 14 digits
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) }
+tls-win-cert{COLON} { YDVAR(1, VAR_TLS_WIN_CERT) }
+additional-ssl-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
+additional-tls-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
+tls-additional-ports{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
+tls-additional-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) }
url{COLON} { YDVAR(1, VAR_URL) }
+allow-notify{COLON} { YDVAR(1, VAR_ALLOW_NOTIFY) }
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
for-upstream{COLON} { YDVAR(1, VAR_FOR_UPSTREAM) }
fallback-enabled{COLON} { YDVAR(1, VAR_FALLBACK_ENABLED) }
trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) }
trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) }
trust-anchor-signaling{COLON} { YDVAR(1, VAR_TRUST_ANCHOR_SIGNALING) }
+root-key-sentinel{COLON} { YDVAR(1, VAR_ROOT_KEY_SENTINEL) }
val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) }
val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) }
val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }
ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
+low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
+low-rtt-pct{COLON} { YDVAR(1, VAR_LOW_RTT_PERMIL) }
+low-rtt-permil{COLON} { YDVAR(1, VAR_LOW_RTT_PERMIL) }
response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }
cachedb{COLON} { YDVAR(0, VAR_CACHEDB) }
backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) }
secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) }
+redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) }
+redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
+redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
%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_AGGRESSIVE_NSEC VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
+%token VAR_ROOT_KEY_SENTINEL
%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
%token VAR_IPSECMOD_ENABLED VAR_IPSECMOD_HOOK VAR_IPSECMOD_IGNORE_BOGUS
%token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
+%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
%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
+%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
+%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_response_ip_tag | server_response_ip | server_response_ip_data |
server_shm_enable | server_shm_key | server_fake_sha1 |
server_hide_trustanchor | server_trust_anchor_signaling |
+ server_root_key_sentinel |
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_aggressive_nsec |
- server_tls_cert_bundle
+ server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
+ server_low_rtt_permil | server_tls_win_cert
;
stubstart: VAR_STUB_ZONE
{
contents_auth: contents_auth content_auth
| ;
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
- auth_for_downstream | auth_for_upstream | auth_fallback_enabled
+ auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
+ auth_allow_notify
;
server_num_threads: VAR_NUM_THREADS STRING_ARG
{
cfg_parser->cfg->tls_cert_bundle = $2;
}
;
+server_tls_win_cert: VAR_TLS_WIN_CERT STRING_ARG
+ {
+ OUTYY(("P(server_tls_win_cert:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->tls_win_cert = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
+server_tls_additional_port: VAR_TLS_ADDITIONAL_PORT STRING_ARG
+ {
+ OUTYY(("P(server_tls_additional_port:%s)\n", $2));
+ if(!cfg_strlist_insert(&cfg_parser->cfg->tls_additional_port,
+ $2))
+ yyerror("out of memory");
+ }
+ ;
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
{
OUTYY(("P(server_use_systemd:%s)\n", $2));
free($2);
}
;
+server_root_key_sentinel: VAR_ROOT_KEY_SENTINEL STRING_ARG
+ {
+ OUTYY(("P(server_root_key_sentinel:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else
+ cfg_parser->cfg->root_key_sentinel =
+ (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
{
OUTYY(("P(server_domain_insecure:%s)\n", $2));
if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 &&
strcmp($3, "deny_non_local")!=0 &&
strcmp($3, "refuse_non_local")!=0 &&
+ strcmp($3, "allow_setrd")!=0 &&
strcmp($3, "allow")!=0 &&
strcmp($3, "allow_snoop")!=0) {
yyerror("expected deny, refuse, deny_non_local, "
- "refuse_non_local, allow or allow_snoop "
- "in access control action");
+ "refuse_non_local, allow, allow_setrd or "
+ "allow_snoop in access control action");
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
fatal_exit("out of memory adding acl");
free($2);
}
;
+server_low_rtt: VAR_LOW_RTT STRING_ARG
+ {
+ OUTYY(("P(server_low_rtt:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else cfg_parser->cfg->low_rtt = atoi($2);
+ free($2);
+ }
+ ;
+server_low_rtt_permil: VAR_LOW_RTT_PERMIL STRING_ARG
+ {
+ OUTYY(("P(server_low_rtt_permil:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else cfg_parser->cfg->low_rtt_permil = atoi($2);
+ free($2);
+ }
+ ;
server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG
{
OUTYY(("P(server_qname_minimisation:%s)\n", $2));
yyerror("out of memory");
}
;
+auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG
+ {
+ OUTYY(("P(allow-notify:%s)\n", $2));
+ if(!cfg_strlist_insert(&cfg_parser->cfg->auths->allow_notify,
+ $2))
+ yyerror("out of memory");
+ }
+ ;
auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG
{
OUTYY(("P(for-downstream:%s)\n", $2));
rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG
{
OUTYY(("P(control_interface:%s)\n", $2));
- if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, $2))
+ if(!cfg_strlist_append(&cfg_parser->cfg->control_ifs, $2))
yyerror("out of memory");
}
;
rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG
{
OUTYY(("P(control_use_cert:%s)\n", $2));
- if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
- yyerror("expected yes or no.");
- else cfg_parser->cfg->remote_control_use_cert =
- (strcmp($2, "yes")==0);
+ cfg_parser->cfg->control_use_cert = (strcmp($2, "yes")==0);
free($2);
}
;
;
contents_cachedb: contents_cachedb content_cachedb
| ;
-content_cachedb: cachedb_backend_name | cachedb_secret_seed
+content_cachedb: cachedb_backend_name | cachedb_secret_seed |
+ redis_server_host | redis_server_port | redis_timeout
;
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
{
#endif
}
;
+redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG
+ {
+ #if defined(USE_CACHEDB) && defined(USE_REDIS)
+ OUTYY(("P(redis_server_host:%s)\n", $2));
+ free(cfg_parser->cfg->redis_server_host);
+ cfg_parser->cfg->redis_server_host = $2;
+ #else
+ OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
+ free($2);
+ #endif
+ }
+ ;
+redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG
+ {
+ #if defined(USE_CACHEDB) && defined(USE_REDIS)
+ int port;
+ OUTYY(("P(redis_server_port:%s)\n", $2));
+ port = atoi($2);
+ if(port == 0 || port < 0 || port > 65535)
+ yyerror("valid redis server port number expected");
+ else cfg_parser->cfg->redis_server_port = port;
+ #else
+ OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
+ #endif
+ free($2);
+ }
+ ;
+redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
+ {
+ #if defined(USE_CACHEDB) && defined(USE_REDIS)
+ OUTYY(("P(redis_timeout:%s)\n", $2));
+ if(atoi($2) == 0)
+ yyerror("redis timeout value expected");
+ else cfg_parser->cfg->redis_timeout = atoi($2);
+ #else
+ OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
+ #endif
+ free($2);
+ }
+ ;
%%
/* parse helper routines could be here */
return lastdiff;
}
+int
+dname_lab_startswith(uint8_t* label, char* prefix, char** endptr)
+{
+ size_t plen = strlen(prefix);
+ size_t orig_plen = plen;
+ size_t lablen = (size_t)*label;
+ if(plen > lablen)
+ return 0;
+ label++;
+ while(plen--) {
+ if(*prefix != tolower((unsigned char)*label)) {
+ return 0;
+ }
+ prefix++; label++;
+ }
+ if(orig_plen < lablen)
+ *endptr = (char *)label;
+ else
+ /* prefix length == label length */
+ *endptr = NULL;
+ return 1;
+}
+
int
dname_buffer_write(sldns_buffer* pkt, uint8_t* dname)
{
*/
int dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs);
+/**
+ * Check if labels starts with given prefix
+ * @param label: dname label
+ * @param prefix: the string to match label with, null terminated.
+ * @param endptr: pointer to location in label after prefix, only if return
+ * value is 1. NULL if nothing in the label after the prefix, i.e. prefix
+ * and label are the same.
+ * @return: 1 if label starts with prefix, else 0
+ */
+int dname_lab_startswith(uint8_t* label, char* prefix, char** endptr);
+
/**
* See if domain name d1 is a strict subdomain of d2.
* That is a subdomain, but not equal.
return 0;
}
+/** skip RR in packet */
+static int
+skip_pkt_rr(sldns_buffer* pkt)
+{
+ if(sldns_buffer_remaining(pkt) < 1) return 0;
+ if(!pkt_dname_len(pkt))
+ return 0;
+ if(sldns_buffer_remaining(pkt) < 4) return 0;
+ sldns_buffer_skip(pkt, 4); /* type and class */
+ if(!skip_ttl_rdata(pkt))
+ return 0;
+ return 1;
+}
+
+/** skip RRs from packet */
+static int
+skip_pkt_rrs(sldns_buffer* pkt, int num)
+{
+ int i;
+ for(i=0; i<num; i++) {
+ if(!skip_pkt_rr(pkt))
+ return 0;
+ }
+ return 1;
+}
+
int
parse_edns_from_pkt(sldns_buffer* pkt, struct edns_data* edns,
struct regional* region)
size_t rdata_len;
uint8_t* rdata_ptr;
log_assert(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) == 1);
- log_assert(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0);
- log_assert(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) == 0);
+ if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 ||
+ LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
+ if(!skip_pkt_rrs(pkt, ((int)LDNS_ANCOUNT(sldns_buffer_begin(pkt)))+
+ ((int)LDNS_NSCOUNT(sldns_buffer_begin(pkt)))))
+ return 0;
+ }
/* check edns section is present */
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
return LDNS_RCODE_FORMERR;
/* minimum size: header + \0 + qtype + qclass */
if(sldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5)
return 0;
- if(LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY ||
- LDNS_QDCOUNT(q) != 1 || sldns_buffer_position(query) != 0)
+ if((LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY && LDNS_OPCODE_WIRE(q) !=
+ LDNS_PACKET_NOTIFY) || LDNS_QDCOUNT(q) != 1 ||
+ sldns_buffer_position(query) != 0)
return 0;
sldns_buffer_skip(query, LDNS_HEADER_SIZE);
m->qname = sldns_buffer_current(query);
case sec_status_bogus: return "sec_status_bogus";
case sec_status_indeterminate: return "sec_status_indeterminate";
case sec_status_insecure: return "sec_status_insecure";
+ case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
case sec_status_secure: return "sec_status_secure";
}
return "unknown_sec_status_value";
* insecure. Generally this means that this RRset is below a trust
* anchor, but also below a verified, insecure delegation. */
sec_status_insecure,
+ /** SECURE_SENTINEL_FAIL means that the object (RRset or message)
+ * validated according to local policy but did not succeed in the root
+ * KSK sentinel test (draft-ietf-dnsop-kskroll-sentinel). */
+ sec_status_secure_sentinel_fail,
/** SECURE means that the object (RRset or message) validated
* according to local policy. */
sec_status_secure
fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
- uint8_t* zone, size_t zonelen, int ssl_upstream, struct module_qstate* q))
+ uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
+ struct module_qstate* q))
{
if(fptr == &worker_send_query) return 1;
else if(fptr == &libworker_send_query) return 1;
int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
- uint8_t* zone, size_t zonelen, int ssl_upstream, struct module_qstate* q));
+ uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
+ struct module_qstate* q));
/**
* Check function pointer whitelist for module_env detach_subs callback values.
9006,
9007,
9009,
+9011,
9020,
9021,
9022,
* @param zone: delegation point name.
* @param zonelen: length of zone name.
* @param ssl_upstream: use SSL for upstream queries.
+ * @param tls_auth_name: if ssl_upstream, use this name with TLS
+ * authentication.
* @param q: wich query state to reactivate upon return.
* @return: false on failure (memory or socket related). no query was
* sent. Or returns an outbound entry with qsent and qstate set.
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int ssl_upstream,
- struct module_qstate* q);
+ char* tls_auth_name, struct module_qstate* q);
/**
* Detach-subqueries.
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
+#ifdef USE_WINSOCK
+#include <wincrypt.h>
+#endif
/** max length of an IP address (the address portion) that we allow */
#define MAX_ADDR_STRLEN 128 /* characters */
int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net)
{
- char* s = NULL;
+ char buf[64];
+ char* s;
*net = (str_is_ip6(str)?128:32);
if((s=strchr(str, '/'))) {
if(atoi(s+1) > *net) {
log_err("cannot parse netblock: '%s'", str);
return 0;
}
- if(!(s = strdup(str))) {
- log_err("out of memory");
- return 0;
- }
- *strchr(s, '/') = '\0';
+ strlcpy(buf, str, sizeof(buf));
+ s = strchr(buf, '/');
+ if(s) *s = 0;
+ s = buf;
}
if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
- free(s);
log_err("cannot parse ip address: '%s'", str);
return 0;
}
if(s) {
- free(s);
addr_mask(addr, *addrlen, *net);
}
return 1;
}
+int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
+ socklen_t* addrlen, char** auth_name)
+{
+ char* s;
+ int port = UNBOUND_DNS_PORT;
+ if((s=strchr(str, '@'))) {
+ char buf[MAX_ADDR_STRLEN];
+ size_t len = (size_t)(s-str);
+ char* hash = strchr(s+1, '#');
+ if(hash) {
+ *auth_name = hash+1;
+ } else {
+ *auth_name = NULL;
+ }
+ if(len >= MAX_ADDR_STRLEN) {
+ return 0;
+ }
+ (void)strlcpy(buf, str, sizeof(buf));
+ buf[len] = 0;
+ port = atoi(s+1);
+ if(port == 0) {
+ if(!hash && strcmp(s+1,"0")!=0)
+ return 0;
+ if(hash && strncmp(s+1,"0#",2)!=0)
+ return 0;
+ }
+ return ipstrtoaddr(buf, port, addr, addrlen);
+ }
+ if((s=strchr(str, '#'))) {
+ char buf[MAX_ADDR_STRLEN];
+ size_t len = (size_t)(s-str);
+ if(len >= MAX_ADDR_STRLEN) {
+ return 0;
+ }
+ (void)strlcpy(buf, str, sizeof(buf));
+ buf[len] = 0;
+ port = UNBOUND_DNS_OVER_TLS_PORT;
+ *auth_name = s+1;
+ return ipstrtoaddr(buf, port, addr, addrlen);
+ }
+ *auth_name = NULL;
+ return ipstrtoaddr(str, port, addr, addrlen);
+}
+
/** store port number into sockaddr structure */
void
sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port)
#endif
}
-void* connect_sslctx_create(char* key, char* pem, char* verifypem)
+#ifdef USE_WINSOCK
+/* For windows, the CA trust store is not read by openssl.
+ Add code to open the trust store using wincrypt API and add
+ the root certs into openssl trust store */
+static int
+add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx)
+{
+ HCERTSTORE hSystemStore;
+ PCCERT_CONTEXT pTargetCert = NULL;
+ X509_STORE* store;
+
+ verbose(VERB_ALGO, "Adding Windows certificates from system root store to CA store");
+
+ /* load just once per context lifetime for this version
+ TODO: dynamically update CA trust changes as they are available */
+ if (!tls_ctx)
+ return 0;
+
+ /* Call wincrypt's CertOpenStore to open the CA root store. */
+
+ if ((hSystemStore = CertOpenStore(
+ CERT_STORE_PROV_SYSTEM,
+ 0,
+ 0,
+ /* NOTE: mingw does not have this const: replace with 1 << 16 from code
+ CERT_SYSTEM_STORE_CURRENT_USER, */
+ 1 << 16,
+ L"root")) == 0)
+ {
+ return 0;
+ }
+
+ store = SSL_CTX_get_cert_store(tls_ctx);
+ if (!store)
+ return 0;
+
+ /* failure if the CA store is empty or the call fails */
+ if ((pTargetCert = CertEnumCertificatesInStore(
+ hSystemStore, pTargetCert)) == 0) {
+ verbose(VERB_ALGO, "CA certificate store for Windows is empty.");
+ return 0;
+ }
+ /* iterate over the windows cert store and add to openssl store */
+ do
+ {
+ X509 *cert1 = d2i_X509(NULL,
+ (const unsigned char **)&pTargetCert->pbCertEncoded,
+ pTargetCert->cbCertEncoded);
+ if (!cert1) {
+ /* return error if a cert fails */
+ verbose(VERB_ALGO, "%s %d:%s",
+ "Unable to parse certificate in memory",
+ (int)ERR_get_error(), ERR_error_string(ERR_get_error(), NULL));
+ return 0;
+ }
+ else {
+ /* return error if a cert add to store fails */
+ if (X509_STORE_add_cert(store, cert1) == 0) {
+ unsigned long error = ERR_peek_last_error();
+
+ /* Ignore error X509_R_CERT_ALREADY_IN_HASH_TABLE which means the
+ * certificate is already in the store. */
+ if(ERR_GET_LIB(error) != ERR_LIB_X509 ||
+ ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
+ verbose(VERB_ALGO, "%s %d:%s\n",
+ "Error adding certificate", (int)ERR_get_error(),
+ ERR_error_string(ERR_get_error(), NULL));
+ X509_free(cert1);
+ return 0;
+ }
+ }
+ X509_free(cert1);
+ }
+ } while ((pTargetCert = CertEnumCertificatesInStore(
+ hSystemStore, pTargetCert)) != 0);
+
+ /* Clean up memory and quit. */
+ if (pTargetCert)
+ CertFreeCertificateContext(pTargetCert);
+ if (hSystemStore)
+ {
+ if (!CertCloseStore(
+ hSystemStore, 0))
+ return 0;
+ }
+ verbose(VERB_ALGO, "Completed adding Windows certificates to CA store successfully");
+ return 1;
+}
+#endif /* USE_WINSOCK */
+
+void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert)
{
#ifdef HAVE_SSL
SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
return NULL;
}
}
- if(verifypem && verifypem[0]) {
- if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
- log_crypto_err("error in SSL_CTX verify");
- SSL_CTX_free(ctx);
- return NULL;
+ if((verifypem && verifypem[0]) || wincert) {
+ if(verifypem && verifypem[0]) {
+ if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
+ log_crypto_err("error in SSL_CTX verify");
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ }
+#ifdef USE_WINSOCK
+ if(wincert) {
+ if(!add_WIN_cacerts_to_openssl_store(ctx)) {
+ log_crypto_err("error in add_WIN_cacerts_to_openssl_store");
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
}
+#else
+ (void)wincert;
+#endif
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
}
return ctx;
#else
- (void)key; (void)pem; (void)verifypem;
+ (void)key; (void)pem; (void)verifypem; (void)wincert;
return NULL;
#endif
}
/** set RCODE bits in uint16 flags */
#define FLAGS_SET_RCODE(f, r) (f = (((f) & 0xfff0) | (r)))
-/** timeout in seconds for UDP queries to auth servers. */
-#define UDP_AUTH_QUERY_TIMEOUT 4
-/** timeout in seconds for TCP queries to auth servers. */
-#define TCP_AUTH_QUERY_TIMEOUT 30
+/** timeout in milliseconds for UDP queries to auth servers. */
+#define UDP_AUTH_QUERY_TIMEOUT 3000
+/** timeout in milliseconds for TCP queries to auth servers. */
+#define TCP_AUTH_QUERY_TIMEOUT 3000
/** Advertised version of EDNS capabilities */
#define EDNS_ADVERTISED_VERSION 0
/** Advertised size of EDNS capabilities */
/**
* Convert ip netblock (ip/netsize) string and port to sockaddr.
- * *SLOW*, does a malloc internally to avoid writing over 'ip' string.
+ * performs a copy internally to avoid writing over 'ip' string.
* @param ip: ip4 or ip6 address string.
* @param port: port number, host format.
* @param addr: where to store sockaddr.
int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net);
+/**
+ * Convert address string, with "@port" appendix, to sockaddr.
+ * It can also have an "#tls-auth-name" appendix (after the port).
+ * The returned tls-auth-name string is a pointer into the input string.
+ * Uses DNS port by default.
+ * @param str: the string
+ * @param addr: where to store sockaddr.
+ * @param addrlen: length of stored sockaddr is returned.
+ * @param auth_name: returned pointer to tls_auth_name, or NULL if none.
+ * @return 0 on error.
+ */
+int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
+ socklen_t* addrlen, char** auth_name);
+
/**
* Store port number into sockaddr structure
* @param addr: sockaddr structure, ip4 or ip6.
* @param key: if nonNULL (also pem nonNULL), the client private key.
* @param pem: client public key (or NULL if key is NULL).
* @param verifypem: if nonNULL used for verifylocation file.
+ * @param wincert: add system certificate store to ctx (add to verifypem ca
+ * certs).
* @return SSL_CTX* or NULL on failure (logged).
*/
-void* connect_sslctx_create(char* key, char* pem, char* verifypem);
+void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert);
/**
* accept a new fd and wrap it in a BIO in SSL
#include "util/fptr_wlist.h"
#include "sldns/pkthdr.h"
#include "sldns/sbuffer.h"
+#include "sldns/str2wire.h"
#include "dnstap/dnstap.h"
#include "dnscrypt/dnscrypt.h"
#ifdef HAVE_OPENSSL_SSL_H
{
int new_fd;
*addrlen = (socklen_t)sizeof(*addr);
+#ifndef HAVE_ACCEPT4
new_fd = accept(c->fd, (struct sockaddr*)addr, addrlen);
+#else
+ /* SOCK_NONBLOCK saves extra calls to fcntl for the same result */
+ new_fd = accept4(c->fd, (struct sockaddr*)addr, addrlen, SOCK_NONBLOCK);
+#endif
if(new_fd == -1) {
#ifndef USE_WINSOCK
/* EINTR is signal interrupt. others are closed connection. */
#endif
return -1;
}
+#ifndef HAVE_ACCEPT4
fd_set_nonblock(new_fd);
+#endif
return new_fd;
}
static long win_bio_cb(BIO *b, int oper, const char* ATTR_UNUSED(argp),
int ATTR_UNUSED(argi), long argl, long retvalue)
{
+ int wsa_err = WSAGetLastError(); /* store errcode before it is gone */
verbose(VERB_ALGO, "bio_cb %d, %s %s %s", oper,
(oper&BIO_CB_RETURN)?"return":"before",
(oper&BIO_CB_READ)?"read":((oper&BIO_CB_WRITE)?"write":"other"),
- WSAGetLastError()==WSAEWOULDBLOCK?"wsawb":"");
+ wsa_err==WSAEWOULDBLOCK?"wsawb":"");
/* on windows, check if previous operation caused EWOULDBLOCK */
if( (oper == (BIO_CB_READ|BIO_CB_RETURN) && argl == 0) ||
(oper == (BIO_CB_GETS|BIO_CB_RETURN) && argl == 0)) {
- if(WSAGetLastError() == WSAEWOULDBLOCK)
+ if(wsa_err == WSAEWOULDBLOCK)
ub_winsock_tcp_wouldblock((struct ub_event*)
BIO_get_callback_arg(b), UB_EV_READ);
}
if( (oper == (BIO_CB_WRITE|BIO_CB_RETURN) && argl == 0) ||
(oper == (BIO_CB_PUTS|BIO_CB_RETURN) && argl == 0)) {
- if(WSAGetLastError() == WSAEWOULDBLOCK)
+ if(wsa_err == WSAEWOULDBLOCK)
ub_winsock_tcp_wouldblock((struct ub_event*)
BIO_get_callback_arg(b), UB_EV_WRITE);
}
if(want == SSL_ERROR_ZERO_RETURN) {
return 0; /* shutdown, closed */
} else if(want == SSL_ERROR_WANT_READ) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return 1; /* read more later */
} else if(want == SSL_ERROR_WANT_WRITE) {
c->ssl_shake_state = comm_ssl_shake_hs_write;
return 0;
}
c->tcp_byte_count += r;
- if(c->tcp_byte_count != sizeof(uint16_t))
+ if(c->tcp_byte_count < sizeof(uint16_t))
return 1;
if(sldns_buffer_read_u16_at(c->buffer, 0) >
sldns_buffer_capacity(c->buffer)) {
verbose(VERB_QUERY, "ssl: dropped bogus too short.");
return 0;
}
+ sldns_buffer_skip(c->buffer, (ssize_t)(c->tcp_byte_count-sizeof(uint16_t)));
verbose(VERB_ALGO, "Reading ssl tcp query of length %d",
(int)sldns_buffer_limit(c->buffer));
}
- 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));
+ if(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) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_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;
}
- log_crypto_err("could not SSL_read");
- return 0;
+ sldns_buffer_skip(c->buffer, (ssize_t)r);
}
- sldns_buffer_skip(c->buffer, (ssize_t)r);
if(sldns_buffer_remaining(c->buffer) <= 0) {
tcp_callback_reader(c);
}
if(c->tcp_byte_count < sizeof(uint16_t)) {
uint16_t len = htons(sldns_buffer_limit(c->buffer));
ERR_clear_error();
- r = SSL_write(c->ssl,
- (void*)(((uint8_t*)&len)+c->tcp_byte_count),
- (int)(sizeof(uint16_t)-c->tcp_byte_count));
+ if(sizeof(uint16_t)+sldns_buffer_remaining(c->buffer) <
+ LDNS_RR_BUF_SIZE) {
+ /* combine the tcp length and the query for write,
+ * this emulates writev */
+ uint8_t buf[LDNS_RR_BUF_SIZE];
+ memmove(buf, &len, sizeof(uint16_t));
+ memmove(buf+sizeof(uint16_t),
+ sldns_buffer_current(c->buffer),
+ sldns_buffer_remaining(c->buffer));
+ r = SSL_write(c->ssl, (void*)(buf+c->tcp_byte_count),
+ (int)(sizeof(uint16_t)+
+ sldns_buffer_remaining(c->buffer)
+ - c->tcp_byte_count));
+ } else {
+ r = SSL_write(c->ssl,
+ (void*)(((uint8_t*)&len)+c->tcp_byte_count),
+ (int)(sizeof(uint16_t)-c->tcp_byte_count));
+ }
if(r <= 0) {
int want = SSL_get_error(c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
if(errno != 0)
comm_point_listen_for_rw(c, 1, 0);
return 1; /* wait for read condition */
} else if(want == SSL_ERROR_WANT_WRITE) {
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1; /* write more later */
} else if(want == SSL_ERROR_SYSCALL) {
if(errno != 0)
{
if(!c)
return;
- if(c->fd != -1)
+ if(c->fd != -1) {
if(ub_event_del(c->ev->ev) != 0) {
log_err("could not event_del on close");
}
+ }
/* close fd after removing from event lists, or epoll.. is messed up */
if(c->fd != -1 && !c->do_not_close) {
+ if(c->type == comm_tcp || c->type == comm_http) {
+ /* delete sticky events for the fd, it gets closed */
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
+ }
verbose(VERB_ALGO, "close fd %d", c->fd);
#ifndef USE_WINSOCK
close(c->fd);
int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len)
{
- struct tube_res_list* item =
- (struct tube_res_list*)malloc(sizeof(*item));
+ struct tube_res_list* item;
+ if(!tube || !tube->res_com) return 0;
+ item = (struct tube_res_list*)malloc(sizeof(*item));
if(!item) {
free(msg);
log_err("out of memory for async answer");
int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len)
{
- struct tube_res_list* item =
- (struct tube_res_list*)malloc(sizeof(*item));
+ struct tube_res_list* item;
+ if(!tube) return 0;
+ item = (struct tube_res_list*)malloc(sizeof(*item));
verbose(VERB_ALGO, "tube queue_item len %d", (int)len);
if(!item) {
free(msg);
UB_EV_BITS_CB(comm_signal_callback)
UB_EV_BITS_CB(comm_point_local_handle_callback)
UB_EV_BITS_CB(comm_point_raw_handle_callback)
+UB_EV_BITS_CB(comm_point_http_handle_callback)
UB_EV_BITS_CB(tube_handle_signal)
UB_EV_BITS_CB(comm_base_handle_slow_accept)
return my_comm_point_local_handle_callback;
else if(cb == comm_point_raw_handle_callback)
return my_comm_point_raw_handle_callback;
+ else if(cb == comm_point_http_handle_callback)
+ return my_comm_point_http_handle_callback;
else if(cb == tube_handle_signal)
return my_tube_handle_signal;
else if(cb == comm_base_handle_slow_accept)
return my_comm_base_handle_slow_accept;
- else
+ else {
+ log_assert(0); /* this NULL callback pointer should not happen,
+ we should have the necessary routine listed above */
return NULL;
+ }
}
#else
# define NATIVE_BITS(b) (b)
qsort(list, ret, sizeof(*list), keytag_compare);
return ret;
}
+
+int
+anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs,
+ size_t namelen, uint16_t dclass, uint16_t keytag)
+{
+ uint16_t* taglist;
+ uint16_t* tl;
+ size_t numtag, i;
+ struct trust_anchor* anchor = anchor_find(anchors,
+ name, namelabs, namelen, dclass);
+ if(!anchor)
+ return 0;
+ if(!anchor->numDS && !anchor->numDNSKEY) {
+ lock_basic_unlock(&anchor->lock);
+ return 0;
+ }
+
+ taglist = calloc(anchor->numDS + anchor->numDNSKEY, sizeof(*taglist));
+ if(!taglist) {
+ lock_basic_unlock(&anchor->lock);
+ return 0;
+ }
+
+ numtag = anchor_list_keytags(anchor, taglist,
+ anchor->numDS+anchor->numDNSKEY);
+ lock_basic_unlock(&anchor->lock);
+ if(!numtag) {
+ free(taglist);
+ return 0;
+ }
+ tl = taglist;
+ for(i=0; i<numtag; i++) {
+ if(*tl == keytag) {
+ free(taglist);
+ return 1;
+ }
+ tl++;
+ }
+ free(taglist);
+ return 0;
+}
*/
size_t anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num);
+/**
+ * Check if there is a trust anchor for given zone with this keytag.
+ *
+ * @param anchors: anchor storage
+ * @param name: name of trust anchor (wireformat)
+ * @param namelabs: labels in name
+ * @param namelen: length of name
+ * @param dclass: class of trust anchor
+ * @param keytag: keytag
+ * @return 1 if there is a trust anchor in the trustachor store for this zone
+ * and keytag, else 0.
+ */
+int anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs,
+ size_t namelen, uint16_t dclass, uint16_t keytag);
+
#endif /* VALIDATOR_VAL_ANCHOR_H */
return NULL;
if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
return NULL;
+
+ lock_basic_lock(&neg->lock);
+ neg->num_neg_cache_noerror++;
+ lock_basic_unlock(&neg->lock);
return msg;
} else if(nsec && val_nsec_proves_name_error(nsec, qinfo->qname)) {
if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
rcode = LDNS_RCODE_NXDOMAIN;
else if(!nsec_proves_nodata(wcrr, &wc_qinfo,
&nodata_wc) || nodata_wc)
- /* &nodata_wc shoudn't be set, wc_qinfo
+ /* &nodata_wc shouldn't be set, wc_qinfo
* already contains wildcard domain. */
/* NSEC doesn't prove anything for
* wildcard. */
if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
return NULL;
+ /* Increment statistic counters */
+ lock_basic_lock(&neg->lock);
+ if(rcode == LDNS_RCODE_NOERROR)
+ neg->num_neg_cache_noerror++;
+ else if(rcode == LDNS_RCODE_NXDOMAIN)
+ neg->num_neg_cache_nxdomain++;
+ lock_basic_unlock(&neg->lock);
+
FLAGS_SET_RCODE(msg->rep->flags, rcode);
return msg;
}
size_t max;
/** max nsec3 iterations allowed */
size_t nsec3_max_iter;
+ /** number of times neg cache records were used to generate NOERROR
+ * responses. */
+ size_t num_neg_cache_noerror;
+ /** number of times neg cache records were used to generate NXDOMAIN
+ * responses. */
+ size_t num_neg_cache_nxdomain;
};
/**
#ifdef USE_ED25519
case LDNS_ED25519:
#endif
-#if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA)
+#ifdef USE_ED448
+ case LDNS_ED448:
+#endif
+#if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448)
return 1;
#endif
*digest_type = NULL;
break;
#endif /* USE_ED25519 */
+#ifdef USE_ED448
+ case LDNS_ED448:
+ *evp_key = sldns_ed4482pkey_raw(key, keylen);
+ if(!*evp_key) {
+ verbose(VERB_QUERY, "verify: "
+ "sldns_ed4482pkey_raw failed");
+ return 0;
+ }
+ *digest_type = NULL;
+ break;
+#endif /* USE_ED448 */
default:
verbose(VERB_QUERY, "verify: unknown algorithm %d",
algo);
* According to RFC 4034.
*/
#include "config.h"
+#include <ctype.h>
#include "validator/validator.h"
#include "validator/val_anchor.h"
#include "validator/val_kcache.h"
return 1;
}
+/**
+ * Get keytag as uint16_t from string
+ *
+ * @param start: start of string containing keytag
+ * @param keytag: pointer where to store the extracted keytag
+ * @return: 1 if keytag was extracted, else 0.
+ */
+static int
+sentinel_get_keytag(char* start, uint16_t* keytag) {
+ char* keytag_str;
+ char* e = NULL;
+ keytag_str = calloc(1, SENTINEL_KEYTAG_LEN + 1 /* null byte */);
+ if(!keytag_str)
+ return 0;
+ memmove(keytag_str, start, SENTINEL_KEYTAG_LEN);
+ keytag_str[SENTINEL_KEYTAG_LEN] = '\0';
+ *keytag = (uint16_t)strtol(keytag_str, &e, 10);
+ if(!e || *e != '\0') {
+ free(keytag_str);
+ return 0;
+ }
+ free(keytag_str);
+ return 1;
+}
+
/**
* Prime trust anchor for use.
* Generate and dispatch a priming query for the given trust anchor.
vq->orig_msg->rep->security = sec_status_indeterminate;
}
+ if(vq->orig_msg->rep->security == sec_status_secure &&
+ qstate->env->cfg->root_key_sentinel &&
+ (qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
+ qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)) {
+ char* keytag_start;
+ uint16_t keytag;
+ if(*qstate->qinfo.qname == strlen(SENTINEL_IS) +
+ SENTINEL_KEYTAG_LEN &&
+ dname_lab_startswith(qstate->qinfo.qname, SENTINEL_IS,
+ &keytag_start)) {
+ if(sentinel_get_keytag(keytag_start, &keytag) &&
+ !anchor_has_keytag(qstate->env->anchors,
+ (uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) {
+ vq->orig_msg->rep->security =
+ sec_status_secure_sentinel_fail;
+ }
+ } else if(*qstate->qinfo.qname == strlen(SENTINEL_NOT) +
+ SENTINEL_KEYTAG_LEN &&
+ dname_lab_startswith(qstate->qinfo.qname, SENTINEL_NOT,
+ &keytag_start)) {
+ if(sentinel_get_keytag(keytag_start, &keytag) &&
+ anchor_has_keytag(qstate->env->anchors,
+ (uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) {
+ vq->orig_msg->rep->security =
+ sec_status_secure_sentinel_fail;
+ }
+ }
+ }
/* store results in cache */
if(qstate->query_flags&BIT_RD) {
/* if secure, this will override cache anyway, no need
/** max number of query restarts, number of IPs to probe */
#define VAL_MAX_RESTART_COUNT 5
+/** Root key sentinel is ta preamble */
+#define SENTINEL_IS "root-key-sentinel-is-ta-"
+/** Root key sentinel is not ta preamble */
+#define SENTINEL_NOT "root-key-sentinel-not-ta-"
+/** Root key sentinal keytag length */
+#define SENTINEL_KEYTAG_LEN 5
+
/**
* Global state for the validator.
*/