Compare commits

..
Author SHA1 Message Date
Wouter Wijngaards b0a1e50452 1.6.0rc1 tag
git-svn-id: file:///svn/unbound/tags/release-1.6.0rc1@3958 be551aaa-1e26-0410-a405-d3ace91eadb9
2016-12-08 09:39:25 +00:00
441 changed files with 5040 additions and 31833 deletions
-1
View File
@@ -7,7 +7,6 @@
/config.log
/config.status
/dnstap/dnstap_config.h
/dnscrypt/dnscrypt_config.h
/doc/example.conf
/doc/libunbound.3
/doc/unbound-anchor.8
+199 -393
View File
@@ -23,8 +23,6 @@ CHECKLOCK_SRC=testcode/checklocks.c
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
DNSTAP_SRC=@DNSTAP_SRC@
DNSTAP_OBJ=@DNSTAP_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
WITH_PYUNBOUND=@WITH_PYUNBOUND@
PY_MAJOR_VERSION=@PY_MAJOR_VERSION@
@@ -97,12 +95,6 @@ PYTHONMOD_HEADER=@PYTHONMOD_HEADER@
PYUNBOUND_SRC=
# libunbound_wrap.lo if python libunbound wrapper enabled.
PYUNBOUND_OBJ=@PYUNBOUND_OBJ@
SUBNET_SRC=edns-subnet/edns-subnet.c edns-subnet/subnetmod.c edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c
SUBNET_OBJ=@SUBNET_OBJ@
SUBNET_HEADER=@SUBNET_HEADER@
IPSECMOD_SRC=ipsecmod/ipsecmod.c ipsecmod/ipsecmod-whitelist.c
IPSECMOD_OBJ=@IPSECMOD_OBJ@
IPSECMOD_HEADER=@IPSECMOD_HEADER@
COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \
util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \
util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \
@@ -112,7 +104,6 @@ iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
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/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 \
@@ -121,11 +112,8 @@ util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
validator/autotrust.c validator/val_anchor.c validator/validator.c \
validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
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) \
$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c cachedb/cachedb.c $(CHECKLOCK_SRC) \
$(DNSTAP_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 \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
@@ -135,10 +123,8 @@ fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo authzone.lo\
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ)
COMMON_OBJ_WITHOUT_NETCALL+=respip.lo
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo \
$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@@ -162,16 +148,15 @@ str2wire.lo
UNITTEST_SRC=testcode/unitanchor.c testcode/unitdname.c \
testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \
testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \
testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \
testcode/unitecs.c testcode/unitauth.c
testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c
UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \
unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \
readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo
readhex.lo testpkts.lo unitldns.lo
UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
$(COMPAT_OBJ)
DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
daemon/remote.c daemon/stats.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@
DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo shm_main.lo remote.lo stats.lo unbound.lo \
DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo remote.lo stats.lo unbound.lo \
worker.lo @WIN_DAEMON_OBJ@
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
$(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
@@ -195,7 +180,7 @@ daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
testcode/replay.c testcode/fake_event.c
TESTBOUND_OBJ=testbound.lo replay.lo fake_event.lo
TESTBOUND_OBJ_LINK=$(TESTBOUND_OBJ) testpkts.lo worker.lo acl_list.lo \
daemon.lo stats.lo shm_main.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
daemon.lo stats.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
$(COMPAT_OBJ)
LOCKVERIFY_SRC=testcode/lock_verify.c
LOCKVERIFY_OBJ=lock_verify.lo
@@ -394,13 +379,6 @@ dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
# dnscrypt
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
dnscrypt/dnscrypt_config.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h
# Python Module
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
pythonmod/interface.h \
@@ -606,10 +584,7 @@ depend:
-e 's?$$(srcdir)/util/configparser.c?util/configparser.c?g' \
-e 's?$$(srcdir)/util/configparser.h?util/configparser.h?g' \
-e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \
-e 's?$$(srcdir)/dnscrypt/dnscrypt_config.h??g' \
-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
-e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP)
cp $(DEPEND_TARGET) $(DEPEND_TMP2)
@@ -627,19 +602,17 @@ depend:
# Dependencies
dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/dns.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
$(srcdir)/sldns/sbuffer.h
$(srcdir)/util/locks.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/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/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h
rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
@@ -661,8 +634,7 @@ msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/d
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/util/module.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
@@ -679,12 +651,10 @@ iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterato
$(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_donotq.h \
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h $(srcdir)/iterator/iter_priv.h \
$(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
$(srcdir)/util/config_file.h $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
$(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/config_file.h $(srcdir)/util/random.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
@@ -725,17 +695,15 @@ iter_utils.lo iter_utils.o: $(srcdir)/iterator/iter_utils.c config.h $(srcdir)/i
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_priv.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/str2wire.h
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
$(srcdir)/services/modstack.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/services/outside_network.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
$(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h
localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
@@ -744,31 +712,23 @@ localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/serv
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/as112.h
$(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.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/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h
$(srcdir)/services/view.h $(srcdir)/util/data/dname.h
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(PYTHONMOD_HEADER) \
$(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h \
$(srcdir)/util/alloc.h $(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h
$(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER)
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
@@ -776,107 +736,73 @@ view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(s
$(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/netevent.h
outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/rtt.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h
alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/configyyrename.h $(srcdir)/util/config_file.h util/configparser.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/iana_ports.inc
$(srcdir)/util/iana_ports.inc
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h \
$(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/config_file.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h
authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/validator/val_nsec3.h \
$(srcdir)/validator/val_secalgo.h
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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
$(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/services/authzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h \
$(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h \
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/edns-subnet.h
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
$(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
$(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(PYTHONMOD_HEADER)
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(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/ub_event.h $(srcdir)/util/log.h \
$(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/util/ub_event.h \
$(srcdir)/util/log.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/dnstap/dnstap.h \
$(srcdir)/dnstap/dnstap.h
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/wire2str.h \
$(srcdir)/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/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
@@ -887,26 +813,22 @@ dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/s
$(srcdir)/util/log.h $(srcdir)/util/net_help.h
lookup3.lo lookup3.o: $(srcdir)/util/storage/lookup3.c config.h $(srcdir)/util/storage/lookup3.h
lruhash.lo lruhash.o: $(srcdir)/util/storage/lruhash.c config.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h
slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.h $(srcdir)/util/log.h
tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/netevent.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h \
$(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(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/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
$(srcdir)/util/netevent.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/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
@@ -918,11 +840,9 @@ autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/val
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
$(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/modstack.h \
$(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/services/modstack.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \
@@ -937,9 +857,8 @@ validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/val
$(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)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
$(srcdir)/sldns/wire2str.h
val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
@@ -948,15 +867,13 @@ val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/
val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \
$(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h
val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \
@@ -972,16 +889,14 @@ val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/valida
val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/sbuffer.h
val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
@@ -989,72 +904,17 @@ val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/val
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/parseutil.h
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h \
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h $(srcdir)/edns-subnet/subnetmod.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/outbound_list.h $(srcdir)/util/alloc.h \
$(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/services/modstack.h $(srcdir)/services/cache/dns.h $(srcdir)/util/regional.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h
subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h \
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h \
$(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/sbuffer.h
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h \
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/config_file.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/testcode/checklocks.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
ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h $(srcdir)/ipsecmod/ipsecmod.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h \
$(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/wire2str.h
ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h \
$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h \
$(srcdir)/ipsecmod/ipsecmod-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/regional.h \
$(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
@@ -1063,15 +923,11 @@ unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/random.h $(srcdir)/respip/respip.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h
$(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/random.h
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
$(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
@@ -1102,74 +958,55 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/services/outbound_list.h $(srcdir)/util/alloc.h \
$(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/edns-subnet.h
unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/dns.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
$(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/regional.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
$(srcdir)/daemon/remote.h \
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \
$(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h \
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
$(srcdir)/services/mesh.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/wire2str.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
@@ -1179,42 +1016,37 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
$(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h \
$(srcdir)/util/ub_event.h
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/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)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
$(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/libworker.h
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/rbtree.h \
$(srcdir)/testcode/fake_event.h $(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/util/log.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
$(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \
$(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
$(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
@@ -1223,45 +1055,40 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
$(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/libworker.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
@@ -1270,12 +1097,10 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h \
@@ -1285,8 +1110,7 @@ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/t
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
@@ -1297,8 +1121,7 @@ pktview.lo pktview.o: $(srcdir)/testcode/pktview.c config.h $(srcdir)/util/log.h
readhex.lo readhex.o: $(srcdir)/testcode/readhex.c config.h $(srcdir)/testcode/readhex.h $(srcdir)/util/log.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
@@ -1309,12 +1132,11 @@ unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/respip/respip.h $(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER)
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER)
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h
context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \
@@ -1324,8 +1146,7 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
$(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/sldns/sbuffer.h
$(srcdir)/sldns/sbuffer.h
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
@@ -1334,21 +1155,19 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
$(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/sldns/sbuffer.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/mesh.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h \
$(srcdir)/util/random.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
$(srcdir)/util/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 \
@@ -1361,40 +1180,32 @@ streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \
$(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h
unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/regional.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
$(srcdir)/winrc/w_inst.h
@@ -1402,14 +1213,11 @@ unbound-service-remove.lo unbound-service-remove.o: $(srcdir)/winrc/unbound-serv
$(srcdir)/winrc/w_inst.h
anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/rrdef.h \
keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/rrdef.h
sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h
wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/keyraw.h
parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/sbuffer.h
parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h
@@ -1429,11 +1237,9 @@ snprintf.lo snprintf.o: $(srcdir)/compat/snprintf.c config.h
strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h \
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h \
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h
+3 -14
View File
@@ -103,20 +103,9 @@ AC_DEFUN([AC_PROG_SWIG],[
if test -z "$available_patch" ; then
[available_patch=0]
fi
[badversion=0]
if test $available_major -lt $required_major ; then
[badversion=1]
fi
if test $available_major -eq $required_major \
-a $available_minor -lt $required_minor ; then
[badversion=1]
fi
if test $available_major -eq $required_major \
-a $available_minor -eq $required_minor \
-a $available_patch -lt $required_patch ; then
[badversion=1]
fi
if test $badversion -eq 1 ; then
if test $available_major -ne $required_major \
-o $available_minor -ne $required_minor \
-o $available_patch -lt $required_patch ; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
else
Vendored
-326
View File
@@ -9044,329 +9044,3 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29.1)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ([2.52])dnl
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
m4_define([_AM_COND_VALUE_$1], [$2])dnl
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+2 -1
View File
@@ -22,7 +22,8 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
if test -z "$ac_distutils_result"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
+17 -42
View File
@@ -171,13 +171,12 @@ static int
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
{
const char* backend_str = "testframe"; /* TODO get from cfg */
(void)cfg; /* need this until the TODO is implemented */
if(backend_str && backend_str[0]) {
cachedb_env->backend = cachedb_find_backend(backend_str);
if(!cachedb_env->backend) {
log_err("cachedb: cannot find backend name '%s",
backend_str);
return 0;
return NULL;
}
}
/* TODO see if more configuration needs to be applied or not */
@@ -375,36 +374,6 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
return 1;
}
static void
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
{
size_t i;
size_t total = data->count + data->rrsig_count;
if(data->ttl > subtract)
data->ttl -= subtract;
else data->ttl = 0;
for(i=0; i<total; i++) {
if(data->rr_ttl[i] > subtract)
data->rr_ttl[i] -= subtract;
else data->rr_ttl[i] = 0;
}
}
static void
adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
{
size_t i;
if(msg->rep->ttl > adjust)
msg->rep->ttl -= adjust;
else msg->rep->ttl = 0;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, adjust);
}
}
/** convert dns message in buffer to return_msg */
static int
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
@@ -451,18 +420,24 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
qstate->return_rcode = LDNS_RCODE_NOERROR;
/* see how much of the TTL expired, and remove it */
if(*qstate->env->now <= (time_t)timestamp) {
verbose(VERB_ALGO, "cachedb msg adjust by zero");
return 1; /* message from the future (clock skew?) */
}
adjust = *qstate->env->now - (time_t)timestamp;
if(qstate->return_msg->rep->ttl < adjust) {
verbose(VERB_ALGO, "cachedb msg expired");
return 0; /* message expired */
}
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust);
return 1;
/*adjust_msg(qstate->return_msg, adjust);*/
/* TODO:
msg->rep->ttl = r->ttl - adjust;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
for(i=0; i<d->count + d->rrsig_count; i++) {
if(d->rr_ttl[i] < adjust)
d->rr_ttl[i] = 0;
else d->rr_ttl[i] -= adjust;
}
if(d->ttl < adjust)
d->ttl = 0;
else d->ttl -= adjust;
*/
/* TODO */
return 0;
}
/**
+1 -1
View File
@@ -48,7 +48,7 @@ void _ARC4_UNLOCK(void)
}
#else /* !THREADS_DISABLED */
static lock_quick_type arc4lock;
static lock_quick_t arc4lock;
static int arc4lockinit = 0;
void _ARC4_LOCK(void)
+1 -1
View File
@@ -6,7 +6,7 @@
#include "util/locks.h"
/** the lock for ctime buffer */
static lock_basic_type ctime_lock;
static lock_basic_t ctime_lock;
/** has it been inited */
static int ctime_r_init = 0;
-53
View File
@@ -3,9 +3,6 @@
/* Directory to chroot to */
#undef CHROOT_DIR
/* Define this to enable client subnet option. */
#undef CLIENT_SUBNET
/* Do sha512 definitions in config.h */
#undef COMPAT_SHA512
@@ -71,18 +68,6 @@
if you don't. */
#undef HAVE_DECL_ARC4RANDOM_UNIFORM
/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
don't. */
#undef HAVE_DECL_INET_NTOP
/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
don't. */
#undef HAVE_DECL_INET_PTON
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */
#undef HAVE_DECL_NID_ED25519
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
don't. */
#undef HAVE_DECL_NID_SECP384R1
@@ -161,9 +146,6 @@
/* Define to 1 if you have the `EVP_cleanup' function. */
#undef HAVE_EVP_CLEANUP
/* Define to 1 if you have the `EVP_DigestVerify' function. */
#undef HAVE_EVP_DIGESTVERIFY
/* Define to 1 if you have the `EVP_dss1' function. */
#undef HAVE_EVP_DSS1
@@ -395,9 +377,6 @@
/* Define to 1 if you have the `SHA512_Update' function. */
#undef HAVE_SHA512_UPDATE
/* Define to 1 if you have the `shmget' function. */
#undef HAVE_SHMGET
/* Define to 1 if you have the `sigprocmask' function. */
#undef HAVE_SIGPROCMASK
@@ -467,12 +446,6 @@
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if systemd should be used */
#undef HAVE_SYSTEMD
/* Define to 1 if you have the <sys/ipc.h> header file. */
#undef HAVE_SYS_IPC_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
@@ -482,9 +455,6 @@
/* Define to 1 if you have the <sys/sha2.h> header file. */
#undef HAVE_SYS_SHA2_H
/* Define to 1 if you have the <sys/shm.h> header file. */
#undef HAVE_SYS_SHM_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
@@ -670,12 +640,6 @@
/* Define to 1 to use cachedb support */
#undef USE_CACHEDB
/* Define to 1 to enable dnscrypt support */
#undef USE_DNSCRYPT
/* Define to 1 to enable dnscrypt with xchacha20 support */
#undef USE_DNSCRYPT_XCHACHA20
/* Define to 1 to enable dnstap support */
#undef USE_DNSTAP
@@ -688,15 +652,9 @@
/* Define this to enable an EVP workaround for older openssl */
#undef USE_ECDSA_EVP_WORKAROUND
/* Define this to enable ED25519 support. */
#undef USE_ED25519
/* Define this to enable GOST support. */
#undef USE_GOST
/* Define to 1 to use ipsecmod support. */
#undef USE_IPSECMOD
/* Define if you want to use internal select based events */
#undef USE_MINI_EVENT
@@ -706,9 +664,6 @@
/* Define this to enable client TCP Fast Open. */
#undef USE_OSX_MSG_FASTOPEN
/* Define this to enable SHA1 support. */
#undef USE_SHA1
/* Define this to enable SHA256 and SHA512 support. */
#undef USE_SHA2
@@ -1106,14 +1061,6 @@ char *strsep(char **stringp, const char *delim);
int isblank(int c);
#endif
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
int inet_pton(int af, const char* src, void* dst);
#endif
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
#define strptime unbound_strptime
struct tm;
Vendored
+35 -764
View File
File diff suppressed because it is too large Load Diff
+15 -133
View File
@@ -6,20 +6,19 @@ sinclude(ax_pthread.m4)
sinclude(acx_python.m4)
sinclude(ac_pkg_swig.m4)
sinclude(dnstap/dnstap.m4)
sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[6])
m4_define([VERSION_MICRO],[4])
m4_define([VERSION_MICRO],[0])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=7
LIBUNBOUND_CURRENT=6
LIBUNBOUND_REVISION=3
LIBUNBOUND_AGE=5
LIBUNBOUND_AGE=4
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.0.2 had 0:14:0
@@ -69,10 +68,6 @@ LIBUNBOUND_AGE=5
# 1.5.9 had 6:1:4
# 1.5.10 had 6:2:4
# 1.6.0 had 6:3:4
# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type
# 1.6.2 had 7:1:5
# 1.6.3 had 7:2:5
# 1.6.4 had 7:3:5
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -110,11 +105,6 @@ case "$prefix" in
prefix="/usr/local"
;;
esac
case "$exec_prefix" in
NONE)
exec_prefix="$prefix"
;;
esac
# are we on MinGW?
if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
@@ -126,16 +116,10 @@ fi
#
# Determine configuration file
# the eval is to evaluate shell expansion twice
UNBOUND_SBIN_DIR=`eval echo "${sbindir}"`
AC_SUBST(UNBOUND_SBIN_DIR)
UNBOUND_SYSCONF_DIR=`eval echo "${sysconfdir}"`
AC_SUBST(UNBOUND_SYSCONF_DIR)
UNBOUND_LOCALSTATE_DIR=`eval echo "${localstatedir}"`
AC_SUBST(UNBOUND_LOCALSTATE_DIR)
if test $on_mingw = "no"; then
ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
else
ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
fi
AC_ARG_WITH([conf_file],
AC_HELP_STRING([--with-conf-file=path],
@@ -205,7 +189,7 @@ AC_ARG_WITH(rootkey-file,
if test $on_mingw = no; then
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
else
UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key"
fi
)
AC_SUBST(UNBOUND_ROOTKEY_FILE)
@@ -219,7 +203,7 @@ AC_ARG_WITH(rootcert-file,
if test $on_mingw = no; then
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
else
UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem"
fi
)
AC_SUBST(UNBOUND_ROOTCERT_FILE)
@@ -319,7 +303,7 @@ AC_CHECK_TOOL(STRIP, strip)
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],,, [AC_INCLUDES_DEFAULT])
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
@@ -565,7 +549,7 @@ if test x_$ub_test_python != x_no; then
# Check for SWIG
ub_have_swig=no
AC_PROG_SWIG(2.0.1)
AC_PROG_SWIG
AC_MSG_CHECKING(SWIG)
if test ! -x "$SWIG"; then
AC_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound])
@@ -692,7 +676,7 @@ else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
@@ -724,16 +708,6 @@ fi
AC_SUBST(SSLLIB)
AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support]))
case "$enable_sha1" in
no)
;;
yes|*)
AC_DEFINE([USE_SHA1], [1], [Define this to enable SHA1 support.])
;;
esac
AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support]))
case "$enable_sha2" in
no)
@@ -743,19 +717,6 @@ case "$enable_sha2" in
;;
esac
AC_ARG_ENABLE(subnet, AC_HELP_STRING([--enable-subnet], [Enable client subnet]))
case "$enable_subnet" in
yes)
AC_DEFINE([CLIENT_SUBNET], [1], [Define this to enable client subnet option.])
SUBNET_OBJ="edns-subnet.lo subnetmod.lo addrtree.lo subnet-whitelist.lo"
AC_SUBST(SUBNET_OBJ)
SUBNET_HEADER='$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/addrtree.h'
AC_SUBST(SUBNET_HEADER)
;;
no|*)
;;
esac
# check wether gost also works
AC_DEFUN([AC_CHECK_GOST_WORKS],
[AC_REQUIRE([AC_PROG_CC])
@@ -918,23 +879,6 @@ case "$enable_dsa" in
;;
esac
AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support]))
use_ed25519="no"
case "$enable_ed25519" in
no)
;;
*)
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
AC_CHECK_DECLS([NID_ED25519], [
AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.])
use_ed25519="yes"
], [ if test "x$enable_ed25519" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED25519 and you used --enable-ed25519.])
fi ], [AC_INCLUDES_DEFAULT
#include <openssl/evp.h>
])
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
@@ -1109,10 +1053,6 @@ if test x_$enable_static_exe = x_yes; then
fi
fi
# Include systemd.m4 - begin
sinclude(systemd.m4)
# Include systemd.m4 - end
# set lock checking if requested
AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
[ enable to check lock and unlock calls, for debug purposes ]),
@@ -1203,7 +1143,7 @@ AC_INCLUDES_DEFAULT
#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])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
@@ -1211,28 +1151,6 @@ AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
if echo $build_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], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
])
AC_REPLACE_FUNCS(inet_aton)
AC_REPLACE_FUNCS(inet_pton)
AC_REPLACE_FUNCS(inet_ntop)
@@ -1270,11 +1188,11 @@ if test "$USE_NSS" = "no"; then
if test "$USE_WINSOCK" = 1; then
AC_LIBOBJ(getentropy_win)
else
case "$host" in
Darwin|*darwin*)
case `uname` in
Darwin)
AC_LIBOBJ(getentropy_osx)
;;
*solaris*|*sunos*|SunOS)
SunOS)
AC_LIBOBJ(getentropy_solaris)
AC_CHECK_HEADERS([sys/sha2.h],, [
AC_CHECK_FUNCS([SHA512_Update],,[
@@ -1287,7 +1205,7 @@ if test "$USE_NSS" = "no"; then
fi
AC_SEARCH_LIBS([clock_gettime], [rt])
;;
*linux*|Linux|*)
Linux|*)
AC_LIBOBJ(getentropy_linux)
AC_CHECK_FUNCS([SHA512_Update],,[
AC_DEFINE([COMPAT_SHA512], [1], [Do sha512 definitions in config.h])
@@ -1358,19 +1276,6 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
]
)
# check for dnscrypt if requested
dnsc_DNSCRYPT([
AC_DEFINE([USE_DNSCRYPT], [1], [Define to 1 to enable dnscrypt support])
AC_SUBST([ENABLE_DNSCRYPT], [1])
AC_SUBST([DNSCRYPT_SRC], ["dnscrypt/dnscrypt.c"])
AC_SUBST([DNSCRYPT_OBJ], ["dnscrypt.lo"])
],
[
AC_SUBST([ENABLE_DNSCRYPT], [0])
]
)
# check for cachedb if requested
AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage]))
case "$enable_cachedb" in
@@ -1382,21 +1287,6 @@ case "$enable_cachedb" in
;;
esac
# check for ipsecmod if requested
AC_ARG_ENABLE(ipsecmod, AC_HELP_STRING([--enable-ipsecmod], [Enable ipsecmod module that facilitates opportunistic IPsec]))
case "$enable_ipsecmod" in
yes)
AC_DEFINE([USE_IPSECMOD], [1], [Define to 1 to use ipsecmod support.])
IPSECMOD_OBJ="ipsecmod.lo ipsecmod-whitelist.lo"
AC_SUBST(IPSECMOD_OBJ)
IPSECMOD_HEADER='$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h'
AC_SUBST(IPSECMOD_HEADER)
;;
no|*)
# nothing
;;
esac
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# on openBSD, the implicit rule make $< work.
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
@@ -1573,14 +1463,6 @@ char *strsep(char **stringp, const char *delim);
int isblank(int c);
#endif
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
int inet_pton(int af, const char* src, void* dst);
#endif
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
#define strptime unbound_strptime
struct tm;
@@ -1689,6 +1571,6 @@ dnl if this is a distro tarball, that was already done by makedist.sh
AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
AC_SUBST(date, [`date +'%b %e, %Y'`])
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service])
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc])
AC_CONFIG_HEADER([config.h])
AC_OUTPUT
-5
View File
@@ -29,8 +29,3 @@ distribution but may be helpful.
Patch from Stephane Lapie for ASAHI Net.
* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
Contributed by Yuri Voinov.
* unbound.socket and unbound.service: systemd files for unbound, install them
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
* redirect-bogus.patch: Return configured address for bogus A and AAAA answers,
instead of SERVFAIL. Contributed by SIDN.
* fastrpz.patch: fastrpz support from Farsight Security.
File diff suppressed because it is too large Load Diff
-344
View File
@@ -1,344 +0,0 @@
Index: daemon/worker.c
===================================================================
--- daemon/worker.c (revision 4191)
+++ daemon/worker.c (working copy)
@@ -663,8 +663,21 @@
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
goto bail_out;
- error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
- qinfo, id, flags, edns);
+ if (qinfo->qtype == LDNS_RR_TYPE_A &&
+ worker->env.cfg->redirect_bogus_ipv4) {
+ /* BAD cached */
+ fixed_address_encode(repinfo->c->buffer,
+ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
+ worker->env.cfg->redirect_bogus_ipv4);
+ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA &&
+ worker->env.cfg->redirect_bogus_ipv6) {
+ fixed_address_encode(repinfo->c->buffer,
+ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
+ worker->env.cfg->redirect_bogus_ipv6);
+ } else {
+ error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
+ qinfo, id, flags, edns);
+ }
rrset_array_unlock_touch(worker->env.rrset_cache,
worker->scratchpad, rep->ref, rep->rrset_count);
if(worker->stats.extended) {
Index: doc/unbound.conf.5.in
===================================================================
--- doc/unbound.conf.5.in (revision 4191)
+++ doc/unbound.conf.5.in (working copy)
@@ -1244,6 +1244,18 @@
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 redirect-bogus-ipv4: \fI<IPv4 address>
+Set a fixed address for DNSSEC failures that are cached
+Instead of responding to A queries with SERVFAIL, respond
+with NOERROR and the address specified here
+The TTL of the response will be 5 seconds
+.TP 5
+.B redirect-bogus-ipv6: \fI<IPv4 address>
+Set a fixed address for DNSSEC failures that are cached
+Instead of responding to AAAA queries with SERVFAIL, respond
+with NOERROR and the address specified here
+The TTL of the response will be 5 seconds
.SS "Remote Control Options"
In the
.B remote\-control:
Index: services/mesh.c
===================================================================
--- services/mesh.c (revision 4191)
+++ services/mesh.c (working copy)
@@ -1006,6 +1006,7 @@
struct timeval end_time;
struct timeval duration;
int secure;
+ int bogus_override = 0;
/* Copy the client's EDNS for later restore, to make sure the edns
* compare is with the correct edns options. */
struct edns_data edns_bak = r->edns;
@@ -1016,6 +1017,7 @@
rcode = LDNS_RCODE_SERVFAIL;
if(m->s.env->cfg->stat_extended)
m->s.env->mesh->ans_bogus++;
+ bogus_override = 1;
}
if(rep && rep->security == sec_status_secure)
secure = 1;
@@ -1047,17 +1049,34 @@
} else if(rcode) {
m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias;
- if(rcode == LDNS_RCODE_SERVFAIL) {
- if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
- rep, rcode, &r->edns, m->s.region))
- r->edns.opt_list = NULL;
- } else {
- if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
- &r->edns, m->s.region))
- r->edns.opt_list = NULL;
+ if(bogus_override && m->s.qinfo.qtype == LDNS_RR_TYPE_A &&
+ m->s.env->cfg->redirect_bogus_ipv4) {
+ fixed_address_encode(r->query_reply.c->buffer,
+ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
+ r->qflags, &r->edns,
+ m->s.env->cfg->redirect_bogus_ipv4);
+ } else if(bogus_override &&
+ m->s.qinfo.qtype == LDNS_RR_TYPE_AAAA &&
+ m->s.env->cfg->redirect_bogus_ipv6) {
+ fixed_address_encode(r->query_reply.c->buffer,
+ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
+ r->qflags, &r->edns,
+ m->s.env->cfg->redirect_bogus_ipv6);
+ } else {
+ if(rcode == LDNS_RCODE_SERVFAIL) {
+ if(!inplace_cb_reply_servfail_call(m->s.env,
+ &m->s.qinfo, &m->s,
+ rep, rcode, &r->edns, m->s.region))
+ r->edns.opt_list = NULL;
+ } else {
+ if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo,
+ &m->s, rep, rcode, &r->edns,
+ m->s.region))
+ r->edns.opt_list = NULL;
+ }
+ error_encode(r->query_reply.c->buffer, rcode,
+ &m->s.qinfo, r->qid, r->qflags, &r->edns);
}
- error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
- r->qid, r->qflags, &r->edns);
comm_point_send_reply(&r->query_reply);
} else {
size_t udp_size = r->edns.udp_size;
Index: util/config_file.c
===================================================================
--- util/config_file.c (revision 4191)
+++ util/config_file.c (working copy)
@@ -273,6 +273,8 @@
cfg->ratelimit_factor = 10;
cfg->qname_minimisation = 0;
cfg->qname_minimisation_strict = 0;
+ cfg->redirect_bogus_ipv4 = NULL;
+ cfg->redirect_bogus_ipv6 = NULL;
cfg->shm_enable = 0;
cfg->shm_key = 11777;
cfg->dnscrypt = 0;
@@ -602,6 +604,10 @@
}
oi[cfg->num_out_ifs++] = d;
cfg->out_ifs = oi;
+ } else if (strcmp(opt, "redirect-bogus-ipv4:") == 0) {
+ cfg->redirect_bogus_ipv4 = strdup(val);
+ } else if (strcmp(opt, "redirect-bogus-ipv6:") == 0) {
+ cfg->redirect_bogus_ipv6 = strdup(val);
} else {
/* unknown or unsupported (from the set_option interface):
* interface, outgoing-interface, access-control,
@@ -1250,6 +1256,12 @@
free(cfg->dnstap_version);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
+ if (cfg->redirect_bogus_ipv4) {
+ free(cfg->redirect_bogus_ipv4);
+ }
+ if (cfg->redirect_bogus_ipv6) {
+ free(cfg->redirect_bogus_ipv6);
+ }
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);
Index: util/config_file.h
===================================================================
--- util/config_file.h (revision 4191)
+++ util/config_file.h (working copy)
@@ -444,6 +444,9 @@
/** minimise QNAME in strict mode, minimise according to RFC.
* Do not apply fallback */
int qname_minimisation_strict;
+ /** construct fake responses for DNSSEC failures */
+ char *redirect_bogus_ipv4;
+ char *redirect_bogus_ipv6;
/** SHM data - true if shm is enabled */
int shm_enable;
/** SHM data - key for the shm */
Index: util/configlexer.lex
===================================================================
--- util/configlexer.lex (revision 4191)
+++ util/configlexer.lex (working copy)
@@ -410,6 +410,8 @@
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) }
+redirect-bogus-ipv4{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV4) }
+redirect-bogus-ipv6{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV6) }
dnscrypt{COLON} { YDVAR(0, VAR_DNSCRYPT) }
dnscrypt-enable{COLON} { YDVAR(1, VAR_DNSCRYPT_ENABLE) }
dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) }
Index: util/configparser.y
===================================================================
--- util/configparser.y (revision 4191)
+++ util/configparser.y (working copy)
@@ -44,6 +44,7 @@
#include <stdlib.h>
#include <assert.h>
+#include "sldns/str2wire.h"
#include "util/configyyrename.h"
#include "util/config_file.h"
#include "util/net_help.h"
@@ -141,6 +142,7 @@
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
+%token VAR_REDIRECT_BOGUS_IPV4 VAR_REDIRECT_BOGUS_IPV6
%token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
@@ -228,6 +230,7 @@
server_access_control_tag_data | server_access_control_view |
server_qname_minimisation_strict | server_serve_expired |
server_fake_dsa | server_log_identity | server_use_systemd |
+ server_redirect_bogus_ipv4 | server_redirect_bogus_ipv6 |
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 |
@@ -1873,6 +1876,34 @@
#endif
}
;
+server_redirect_bogus_ipv4: VAR_REDIRECT_BOGUS_IPV4 STRING_ARG
+ {
+ uint8_t data[4];
+ size_t data_len = 4;
+ OUTYY(("P(name:%s)\n", $2));
+ if(cfg_parser->cfg->redirect_bogus_ipv4) {
+ yyerror("redirect-bogus-ipv4, can only use one address");
+ }
+ if(sldns_str2wire_a_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
+ yyerror("redirect-bogus-ipv4, not a valid IPv4 address");
+ }
+ free(cfg_parser->cfg->redirect_bogus_ipv4);
+ cfg_parser->cfg->redirect_bogus_ipv4 = $2;
+ }
+server_redirect_bogus_ipv6: VAR_REDIRECT_BOGUS_IPV6 STRING_ARG
+ {
+ uint8_t data[16];
+ size_t data_len = 16;
+ OUTYY(("P(name:%s)\n", $2));
+ if(cfg_parser->cfg->redirect_bogus_ipv6) {
+ yyerror("redirect-bogus-ipv6, can only use one address");
+ }
+ if(sldns_str2wire_aaaa_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
+ yyerror("redirect-bogus-ipv6, not a valid IPv6 address");
+ }
+ free(cfg_parser->cfg->redirect_bogus_ipv6);
+ cfg_parser->cfg->redirect_bogus_ipv6 = $2;
+ }
stub_name: VAR_NAME STRING_ARG
{
OUTYY(("P(name:%s)\n", $2));
Index: util/data/msgencode.c
===================================================================
--- util/data/msgencode.c (revision 4191)
+++ util/data/msgencode.c (working copy)
@@ -48,6 +48,7 @@
#include "util/regional.h"
#include "util/net_help.h"
#include "sldns/sbuffer.h"
+#include "sldns/str2wire.h"
#include "services/localzone.h"
/** return code that means the function ran out of memory. negative so it does
@@ -914,3 +915,63 @@
attach_edns_record(buf, &es);
}
}
+
+void
+fixed_address_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
+ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* data)
+{
+ uint16_t flags;
+ uint8_t addr_data[16];
+ size_t addr_len = 16;
+ if (qinfo->qtype == LDNS_RR_TYPE_A) {
+ sldns_str2wire_a_buf(data, addr_data, &addr_len);
+ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA) {
+ sldns_str2wire_aaaa_buf(data, addr_data, &addr_len);
+ } else {
+ return error_encode(buf, LDNS_RCODE_NOERROR, qinfo, qid, qflags, edns);
+ }
+ sldns_buffer_clear(buf);
+ sldns_buffer_write(buf, &qid, sizeof(uint16_t));
+ flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/
+ flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */
+ sldns_buffer_write_u16(buf, flags);
+ if(qinfo) flags = 1;
+ else flags = 0;
+ sldns_buffer_write_u16(buf, flags);
+ sldns_buffer_write_u16(buf, 1);
+ flags = 0;
+ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
+ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
+ if(qinfo) {
+ // query
+ if(sldns_buffer_current(buf) == qinfo->qname)
+ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
+ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
+ sldns_buffer_write_u16(buf, qinfo->qtype);
+ sldns_buffer_write_u16(buf, qinfo->qclass);
+ // faked answer
+ if(sldns_buffer_current(buf) == qinfo->qname)
+ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
+ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
+ sldns_buffer_write_u16(buf, qinfo->qtype);
+ sldns_buffer_write_u16(buf, qinfo->qclass);
+ sldns_buffer_write_u16(buf, 0);
+ // TTL. Should we make this configurable too?
+ sldns_buffer_write_u16(buf, 5);
+ sldns_buffer_write_u16(buf, addr_len);
+ sldns_buffer_write(buf, addr_data, addr_len);
+ fflush(stderr);
+ }
+ sldns_buffer_flip(buf);
+ if(edns) {
+ struct edns_data es = *edns;
+ es.edns_version = EDNS_ADVERTISED_VERSION;
+ es.udp_size = EDNS_ADVERTISED_SIZE;
+ es.ext_rcode = 0;
+ es.bits &= EDNS_DO;
+ if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
+ edns->udp_size)
+ return;
+ attach_edns_record(buf, &es);
+ }
+}
Index: util/data/msgencode.h
===================================================================
--- util/data/msgencode.h (revision 4191)
+++ util/data/msgencode.h (working copy)
@@ -128,4 +128,20 @@
void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
uint16_t qid, uint16_t qflags, struct edns_data* edns);
+/**
+ * Encode a fixed address response.
+ * This is a fake answer to either an A or AAA query
+ *
+ * It will answer with that address
+ *
+ * @param pkt: where to store the packet.
+ * @param r: RCODE value to encode.
+ * @param qinfo: if not NULL, the query is included.
+ * @param qid: query ID to set in packet. network order.
+ * @param qflags: original query flags (to copy RD and CD bits). host order.
+ * @param edns: if not NULL, this is the query edns info,
+ * and an edns reply is attached. Only attached if EDNS record fits reply.
+ */
+void fixed_address_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
+ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* address);
#endif /* UTIL_DATA_MSGENCODE_H */
-28
View File
@@ -1,28 +0,0 @@
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
[Install]
WantedBy=multi-user.target
[Service]
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
ProtectHome=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
RestrictAddressFamilies=AF_INET AF_UNIX
RestrictRealtime=true
SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
-6
View File
@@ -1,6 +0,0 @@
[Socket]
ListenDatagram=127.0.0.1:1153
ListenStream=127.0.0.1:1153
# ListenStream=@UNBOUND_RUN_DIR@/control
[Install]
WantedBy=sockets.target
+1 -1
View File
@@ -76,7 +76,7 @@ struct acl_list {
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
rbtree_type tree;
rbtree_t tree;
};
/**
+2 -59
View File
@@ -73,7 +73,6 @@
#include "util/log.h"
#include "util/config_file.h"
#include "util/data/msgreply.h"
#include "util/shm_side/shm_main.h"
#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "services/listen_dnsport.h"
@@ -87,13 +86,8 @@
#include "util/tube.h"
#include "util/net_help.h"
#include "sldns/keyraw.h"
#include "respip/respip.h"
#include <signal.h>
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
/** How many quit requests happened. */
static int sig_record_quit = 0;
/** How many reload requests happened. */
@@ -181,15 +175,8 @@ static void
signal_handling_playback(struct worker* wrk)
{
#ifdef SIGHUP
if(sig_record_reload) {
# ifdef HAVE_SYSTEMD
sd_notify(0, "RELOADING=1");
# endif
if(sig_record_reload)
worker_sighandler(SIGHUP, wrk);
# ifdef HAVE_SYSTEMD
sd_notify(0, "READY=1");
# endif
}
#endif
if(sig_record_quit)
worker_sighandler(SIGTERM, wrk);
@@ -563,8 +550,6 @@ daemon_stop_others(struct daemon* daemon)
void
daemon_fork(struct daemon* daemon)
{
int have_view_respip_cfg = 0;
log_assert(daemon);
if(!(daemon->views = views_create()))
fatal_exit("Could not create views: out of memory");
@@ -574,44 +559,15 @@ daemon_fork(struct daemon* daemon)
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
fatal_exit("Could not setup access control list");
if(daemon->cfg->dnscrypt) {
#ifdef USE_DNSCRYPT
daemon->dnscenv = dnsc_create();
if (!daemon->dnscenv)
fatal_exit("dnsc_create failed");
dnsc_apply_cfg(daemon->dnscenv, daemon->cfg);
#else
fatal_exit("dnscrypt enabled in config but unbound was not built with "
"dnscrypt support");
#endif
}
/* create global local_zones */
if(!(daemon->local_zones = local_zones_create()))
fatal_exit("Could not create local zones: out of memory");
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
fatal_exit("Could not set up local zones");
/* process raw response-ip configuration data */
if(!(daemon->respip_set = respip_set_create()))
fatal_exit("Could not create response IP set");
if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
fatal_exit("Could not set up response IP set");
if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
&have_view_respip_cfg))
fatal_exit("Could not set up per-view response IP sets");
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
have_view_respip_cfg;
/* setup modules */
daemon_setup_modules(daemon);
/* response-ip-xxx options don't work as expected without the respip
* module. To avoid run-time operational surprise we reject such
* configuration. */
if(daemon->use_response_ip &&
modstack_find(&daemon->mods, "respip") < 0)
fatal_exit("response-ip options require respip module");
/* first create all the worker structures, so we can pass
* them to the newly created threads.
*/
@@ -638,26 +594,14 @@ daemon_fork(struct daemon* daemon)
#endif
signal_handling_playback(daemon->workers[0]);
if (!shm_main_init(daemon))
log_warn("SHM has failed");
/* Start resolver service on main thread. */
#ifdef HAVE_SYSTEMD
sd_notify(0, "READY=1");
#endif
log_info("start of service (%s).", PACKAGE_STRING);
worker_work(daemon->workers[0]);
#ifdef HAVE_SYSTEMD
sd_notify(0, "STOPPING=1");
#endif
log_info("service stopped (%s).", PACKAGE_STRING);
/* we exited! a signal happened! Stop other threads */
daemon_stop_others(daemon);
/* Shutdown SHM */
shm_main_shutdown(daemon);
daemon->need_to_exit = daemon->workers[0]->need_to_exit;
}
@@ -677,8 +621,6 @@ daemon_cleanup(struct daemon* daemon)
slabhash_clear(daemon->env->msg_cache);
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
respip_set_delete(daemon->respip_set);
daemon->respip_set = NULL;
views_delete(daemon->views);
daemon->views = NULL;
/* key cache is cleared by module desetup during next daemon_fork() */
@@ -711,6 +653,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env);
inplace_cb_lists_delete(daemon->env);
}
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
-16
View File
@@ -56,19 +56,12 @@ struct local_zones;
struct views;
struct ub_randstate;
struct daemon_remote;
struct respip_set;
struct shm_main_info;
#include "dnstap/dnstap_config.h"
#ifdef USE_DNSTAP
struct dt_env;
#endif
#include "dnscrypt/dnscrypt_config.h"
#ifdef USE_DNSCRYPT
struct dnsc_env;
#endif
/**
* Structure holding worker list.
* Holds globally visible information.
@@ -124,15 +117,6 @@ struct daemon {
#ifdef USE_DNSTAP
/** the dnstap environment master value, copied and changed by threads*/
struct dt_env* dtenv;
#endif
struct shm_main_info* shm_info;
/** response-ip set with associated actions and tags. */
struct respip_set* respip_set;
/** some response-ip tags or actions are configured if true */
int use_response_ip;
#ifdef USE_DNSCRYPT
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
};
+37 -161
View File
@@ -124,7 +124,7 @@ timeval_subtract(struct timeval* d, const struct timeval* end,
/** divide sum of timers to get average */
static void
timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
{
#ifndef S_SPLINT_S
size_t leftover;
@@ -242,29 +242,6 @@ daemon_remote_create(struct config_file* cfg)
daemon_remote_delete(rc);
return NULL;
}
#if defined(SSL_OP_NO_TLSv1) && defined(SSL_OP_NO_TLSv1_1)
/* if we have tls 1.1 disable 1.0 */
if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1)
!= SSL_OP_NO_TLSv1){
log_crypto_err("could not set SSL_OP_NO_TLSv1");
daemon_remote_delete(rc);
return NULL;
}
#endif
#if defined(SSL_OP_NO_TLSv1_1) && defined(SSL_OP_NO_TLSv1_2)
/* if we have tls 1.2 disable 1.1 */
if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1)
!= SSL_OP_NO_TLSv1_1){
log_crypto_err("could not set SSL_OP_NO_TLSv1_1");
daemon_remote_delete(rc);
return NULL;
}
#endif
#if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA)
/* if we have sha256, set the cipher list to have no known vulns */
if(!SSL_CTX_set_cipher_list(rc->ctx, "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"))
log_crypto_err("could not set cipher list with SSL_CTX_set_cipher_list");
#endif
if (cfg->remote_control_use_cert == 0) {
/* No certificates are requested */
@@ -404,7 +381,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
if(ip[0] == '/') {
/* This looks like a local socket */
fd = create_local_accept_sock(ip, &noproto, cfg->use_systemd);
fd = create_local_accept_sock(ip, &noproto);
/*
* Change socket ownership and permissions so users other
* than root can access it provided they are in the same
@@ -447,7 +424,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* open fd */
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd);
cfg->ip_transparent, 0, cfg->ip_freebind);
freeaddrinfo(res);
}
@@ -780,13 +757,11 @@ do_verbosity(SSL* ssl, char* str)
/** print stats from statinfo */
static int
print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s)
print_stats(SSL* ssl, const char* nm, struct stats_info* s)
{
struct timeval sumwait, avg;
struct timeval avg;
if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_ip_ratelimited"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_ip_ratelimited)) return 0;
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
(unsigned long)(s->svr.num_queries
- s->svr.num_queries_missed_cache))) return 0;
@@ -798,20 +773,10 @@ print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s)
(unsigned long)s->svr.zero_ttl_responses)) return 0;
if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm,
(unsigned long)s->mesh_replies_sent)) return 0;
#ifdef USE_DNSCRYPT
if(!ssl_printf(ssl, "%s.num.dnscrypt.crypted"SQ"%lu\n", nm,
(unsigned long)s->svr.num_query_dnscrypt_crypted)) return 0;
if(!ssl_printf(ssl, "%s.num.dnscrypt.cert"SQ"%lu\n", nm,
(unsigned long)s->svr.num_query_dnscrypt_cert)) return 0;
if(!ssl_printf(ssl, "%s.num.dnscrypt.cleartext"SQ"%lu\n", nm,
(unsigned long)s->svr.num_query_dnscrypt_cleartext)) return 0;
if(!ssl_printf(ssl, "%s.num.dnscrypt.malformed"SQ"%lu\n", nm,
(unsigned long)s->svr.num_query_dnscrypt_crypted_malformed)) return 0;
#endif
if(!ssl_printf(ssl, "%s.requestlist.avg"SQ"%g\n", nm,
(s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)?
(double)s->svr.sum_query_list_size/
(double)(s->svr.num_queries_missed_cache+
(s->svr.num_queries_missed_cache+
s->svr.num_queries_prefetch) : 0.0)) return 0;
if(!ssl_printf(ssl, "%s.requestlist.max"SQ"%lu\n", nm,
(unsigned long)s->svr.max_query_list_size)) return 0;
@@ -823,11 +788,7 @@ print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s)
(unsigned long)s->mesh_num_states)) return 0;
if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm,
(unsigned long)s->mesh_num_reply_states)) return 0;
#ifndef S_SPLINT_S
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
#endif
timeval_divide(&avg, &sumwait, s->mesh_replies_sent);
timeval_divide(&avg, &s->mesh_replies_sum_wait, s->mesh_replies_sent);
if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ ARG_LL "d.%6.6d\n", nm,
(long long)avg.tv_sec, (int)avg.tv_usec)) return 0;
if(!ssl_printf(ssl, "%s.recursion.time.median"SQ"%g\n", nm,
@@ -839,7 +800,7 @@ print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s)
/** print stats for one thread */
static int
print_thread_stats(SSL* ssl, int i, struct ub_stats_info* s)
print_thread_stats(SSL* ssl, int i, struct stats_info* s)
{
char nm[16];
snprintf(nm, sizeof(nm), "thread%d", i);
@@ -866,24 +827,26 @@ print_longnum(SSL* ssl, const char* desc, size_t x)
static int
print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
{
size_t msg, rrset, val, iter, respip;
#ifdef CLIENT_SUBNET
size_t subnet = 0;
#endif /* CLIENT_SUBNET */
#ifdef USE_IPSECMOD
size_t ipsecmod = 0;
#endif /* USE_IPSECMOD */
int m;
size_t msg, rrset, val, iter;
msg = slabhash_get_mem(daemon->env->msg_cache);
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
val = mod_get_mem(&worker->env, "validator");
iter = mod_get_mem(&worker->env, "iterator");
respip = mod_get_mem(&worker->env, "respip");
#ifdef CLIENT_SUBNET
subnet = mod_get_mem(&worker->env, "subnet");
#endif /* CLIENT_SUBNET */
#ifdef USE_IPSECMOD
ipsecmod = mod_get_mem(&worker->env, "ipsecmod");
#endif /* USE_IPSECMOD */
val=0;
iter=0;
m = modstack_find(&worker->env.mesh->mods, "validator");
if(m != -1) {
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
mods.mod[m]->get_mem));
val = (*worker->env.mesh->mods.mod[m]->get_mem)
(&worker->env, m);
}
m = modstack_find(&worker->env.mesh->mods, "iterator");
if(m != -1) {
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
mods.mod[m]->get_mem));
iter = (*worker->env.mesh->mods.mod[m]->get_mem)
(&worker->env, m);
}
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
return 0;
@@ -893,16 +856,6 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
return 0;
if(!print_longnum(ssl, "mem.mod.validator"SQ, val))
return 0;
if(!print_longnum(ssl, "mem.mod.respip"SQ, respip))
return 0;
#ifdef CLIENT_SUBNET
if(!print_longnum(ssl, "mem.mod.subnet"SQ, subnet))
return 0;
#endif /* CLIENT_SUBNET */
#ifdef USE_IPSECMOD
if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, ipsecmod))
return 0;
#endif /* USE_IPSECMOD */
return 1;
}
@@ -927,7 +880,7 @@ print_uptime(SSL* ssl, struct worker* worker, int reset)
/** print extended histogram */
static int
print_hist(SSL* ssl, struct ub_stats_info* s)
print_hist(SSL* ssl, struct stats_info* s)
{
struct timehist* hist;
size_t i;
@@ -955,14 +908,14 @@ print_hist(SSL* ssl, struct ub_stats_info* s)
/** print extended stats */
static int
print_ext(SSL* ssl, struct ub_stats_info* s)
print_ext(SSL* ssl, struct stats_info* s)
{
int i;
char nm[16];
const sldns_rr_descriptor* desc;
const sldns_lookup_table* lt;
/* TYPE */
for(i=0; i<UB_STATS_QTYPE_NUM; i++) {
for(i=0; i<STATS_QTYPE_NUM; i++) {
if(inhibit_zero && s->svr.qtype[i] == 0)
continue;
desc = sldns_rr_descript((uint16_t)i);
@@ -989,7 +942,7 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
(unsigned long)s->svr.qtype_big)) return 0;
}
/* CLASS */
for(i=0; i<UB_STATS_QCLASS_NUM; i++) {
for(i=0; i<STATS_QCLASS_NUM; i++) {
if(inhibit_zero && s->svr.qclass[i] == 0)
continue;
lt = sldns_lookup_by_id(sldns_rr_classes, i);
@@ -1006,7 +959,7 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
(unsigned long)s->svr.qclass_big)) return 0;
}
/* OPCODE */
for(i=0; i<UB_STATS_OPCODE_NUM; i++) {
for(i=0; i<STATS_OPCODE_NUM; i++) {
if(inhibit_zero && s->svr.qopcode[i] == 0)
continue;
lt = sldns_lookup_by_id(sldns_opcodes, i);
@@ -1048,7 +1001,7 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
(unsigned long)s->svr.qEDNS_DO)) return 0;
/* RCODE */
for(i=0; i<UB_STATS_RCODE_NUM; i++) {
for(i=0; i<STATS_RCODE_NUM; i++) {
/* Always include RCODEs 0-5 */
if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0)
continue;
@@ -1094,8 +1047,8 @@ static void
do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
{
struct daemon* daemon = rc->worker->daemon;
struct ub_stats_info total;
struct ub_stats_info s;
struct stats_info total;
struct stats_info s;
int i;
log_assert(daemon->num > 0);
/* gather all thread statistics in one place */
@@ -1387,21 +1340,6 @@ do_view_zone_add(SSL* ssl, struct worker* worker, char* arg)
ssl_printf(ssl,"no view with name: %s\n", arg);
return;
}
if(!v->local_zones) {
if(!(v->local_zones = local_zones_create())){
lock_rw_unlock(&v->lock);
ssl_printf(ssl,"error out of memory\n");
return;
}
if(!v->isfirst) {
/* Global local-zone is not used for this view,
* therefore add defaults to this view-specic
* local-zone. */
struct config_file lz_cfg;
memset(&lz_cfg, 0, sizeof(lz_cfg));
local_zone_enter_defaults(v->local_zones, &lz_cfg);
}
}
do_zone_add(ssl, v->local_zones, arg2);
lock_rw_unlock(&v->lock);
}
@@ -1420,11 +1358,6 @@ do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg)
ssl_printf(ssl,"no view with name: %s\n", arg);
return;
}
if(!v->local_zones) {
lock_rw_unlock(&v->lock);
send_ok(ssl);
return;
}
do_zone_remove(ssl, v->local_zones, arg2);
lock_rw_unlock(&v->lock);
}
@@ -1443,13 +1376,6 @@ do_view_data_add(SSL* ssl, struct worker* worker, char* arg)
ssl_printf(ssl,"no view with name: %s\n", arg);
return;
}
if(!v->local_zones) {
if(!(v->local_zones = local_zones_create())){
lock_rw_unlock(&v->lock);
ssl_printf(ssl,"error out of memory\n");
return;
}
}
do_data_add(ssl, v->local_zones, arg2);
lock_rw_unlock(&v->lock);
}
@@ -1468,11 +1394,6 @@ do_view_data_remove(SSL* ssl, struct worker* worker, char* arg)
ssl_printf(ssl,"no view with name: %s\n", arg);
return;
}
if(!v->local_zones) {
lock_rw_unlock(&v->lock);
send_ok(ssl);
return;
}
do_data_remove(ssl, v->local_zones, arg2);
lock_rw_unlock(&v->lock);
}
@@ -1495,7 +1416,7 @@ static void
do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
uint16_t t, uint16_t c)
{
hashvalue_type h;
hashvalue_t h;
struct query_info k;
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0);
if(t == LDNS_RR_TYPE_SOA)
@@ -2608,9 +2529,7 @@ do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg)
ssl_printf(ssl,"no view with name: %s\n", arg);
return;
}
if(v->local_zones) {
do_list_local_zones(ssl, v->local_zones);
}
do_list_local_zones(ssl, v->local_zones);
lock_rw_unlock(&v->lock);
}
@@ -2624,9 +2543,7 @@ do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg)
ssl_printf(ssl,"no view with name: %s\n", arg);
return;
}
if(v->local_zones) {
do_list_local_data(ssl, worker, v->local_zones);
}
do_list_local_data(ssl, worker, v->local_zones);
lock_rw_unlock(&v->lock);
}
@@ -2642,8 +2559,6 @@ struct ratelimit_list_arg {
time_t now;
};
#define ip_ratelimit_list_arg ratelimit_list_arg
/** list items in the ratelimit table */
static void
rate_list(struct lruhash_entry* e, void* arg)
@@ -2662,24 +2577,6 @@ rate_list(struct lruhash_entry* e, void* arg)
ssl_printf(a->ssl, "%s %d limit %d\n", buf, max, lim);
}
/** list items in the ip_ratelimit table */
static void
ip_rate_list(struct lruhash_entry* e, void* arg)
{
char ip[128];
struct ip_ratelimit_list_arg* a = (struct ip_ratelimit_list_arg*)arg;
struct ip_rate_key* k = (struct ip_rate_key*)e->key;
struct ip_rate_data* d = (struct ip_rate_data*)e->data;
int lim = infra_ip_ratelimit;
int max = infra_rate_max(d, a->now);
if(a->all == 0) {
if(max < lim)
return;
}
addr_to_str(&k->addr, k->addrlen, ip, sizeof(ip));
ssl_printf(a->ssl, "%s %d limit %d\n", ip, max, lim);
}
/** do the ratelimit_list command */
static void
do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
@@ -2698,24 +2595,6 @@ do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
slabhash_traverse(a.infra->domain_rates, 0, rate_list, &a);
}
/** do the ip_ratelimit_list command */
static void
do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
{
struct ip_ratelimit_list_arg a;
a.all = 0;
a.infra = worker->env.infra_cache;
a.now = *worker->env.now;
a.ssl = ssl;
arg = skipwhite(arg);
if(strcmp(arg, "+a") == 0)
a.all = 1;
if(a.infra->client_ip_rates==NULL ||
(a.all == 0 && infra_ip_ratelimit == 0))
return;
slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a);
}
/** tell other processes to execute the command */
static void
distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
@@ -2794,9 +2673,6 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
} else if(cmdcmp(p, "ratelimit_list", 14)) {
do_ratelimit_list(ssl, worker, p+14);
return;
} else if(cmdcmp(p, "ip_ratelimit_list", 17)) {
do_ip_ratelimit_list(ssl, worker, p+17);
return;
} else if(cmdcmp(p, "stub_add", 8)) {
/* must always distribute this cmd */
if(rc) distribute_cmd(rc, ssl, cmd);
+48 -60
View File
@@ -63,59 +63,57 @@
/** add timers and the values do not overflow or become negative */
static void
stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec)
timeval_add(struct timeval* d, const struct timeval* add)
{
#ifndef S_SPLINT_S
(*d_sec) += add_sec;
(*d_usec) += add_usec;
if((*d_usec) > 1000000) {
(*d_usec) -= 1000000;
(*d_sec)++;
d->tv_sec += add->tv_sec;
d->tv_usec += add->tv_usec;
if(d->tv_usec > 1000000) {
d->tv_usec -= 1000000;
d->tv_sec++;
}
#endif
}
void server_stats_init(struct ub_server_stats* stats, struct config_file* cfg)
void server_stats_init(struct server_stats* stats, struct config_file* cfg)
{
memset(stats, 0, sizeof(*stats));
stats->extended = cfg->stat_extended;
}
void server_stats_querymiss(struct ub_server_stats* stats, struct worker* worker)
void server_stats_querymiss(struct server_stats* stats, struct worker* worker)
{
stats->num_queries_missed_cache++;
stats->sum_query_list_size += worker->env.mesh->all.count;
if((long long)worker->env.mesh->all.count > stats->max_query_list_size)
stats->max_query_list_size = (long long)worker->env.mesh->all.count;
if(worker->env.mesh->all.count > stats->max_query_list_size)
stats->max_query_list_size = worker->env.mesh->all.count;
}
void server_stats_prefetch(struct ub_server_stats* stats, struct worker* worker)
void server_stats_prefetch(struct server_stats* stats, struct worker* worker)
{
stats->num_queries_prefetch++;
/* changes the query list size so account that, like a querymiss */
stats->sum_query_list_size += worker->env.mesh->all.count;
if((long long)worker->env.mesh->all.count > stats->max_query_list_size)
stats->max_query_list_size = (long long)worker->env.mesh->all.count;
if(worker->env.mesh->all.count > stats->max_query_list_size)
stats->max_query_list_size = worker->env.mesh->all.count;
}
void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
void server_stats_log(struct server_stats* stats, struct worker* worker,
int threadnum)
{
log_info("server stats for thread %d: %u queries, "
"%u answers from cache, %u recursions, %u prefetch, %u rejected by "
"ip ratelimiting",
"%u answers from cache, %u recursions, %u prefetch",
threadnum, (unsigned)stats->num_queries,
(unsigned)(stats->num_queries -
stats->num_queries_missed_cache),
(unsigned)stats->num_queries_missed_cache,
(unsigned)stats->num_queries_prefetch,
(unsigned)stats->num_queries_ip_ratelimited);
(unsigned)stats->num_queries_prefetch);
log_info("server stats for thread %d: requestlist max %u avg %g "
"exceeded %u jostled %u", threadnum,
(unsigned)stats->max_query_list_size,
(stats->num_queries_missed_cache+stats->num_queries_prefetch)?
(double)stats->sum_query_list_size/
(double)(stats->num_queries_missed_cache+
(stats->num_queries_missed_cache+
stats->num_queries_prefetch) : 0.0,
(unsigned)worker->env.mesh->stats_dropped,
(unsigned)worker->env.mesh->stats_jostled);
@@ -140,50 +138,49 @@ get_rrset_bogus(struct worker* worker)
}
void
server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
server_stats_compile(struct worker* worker, struct stats_info* s, int reset)
{
int i;
struct listen_list* lp;
s->svr = worker->stats;
s->mesh_num_states = (long long)worker->env.mesh->all.count;
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
s->mesh_replies_sum_wait_sec = (long long)worker->env.mesh->replies_sum_wait.tv_sec;
s->mesh_replies_sum_wait_usec = (long long)worker->env.mesh->replies_sum_wait.tv_usec;
s->mesh_num_states = worker->env.mesh->all.count;
s->mesh_num_reply_states = worker->env.mesh->num_reply_states;
s->mesh_jostled = worker->env.mesh->stats_jostled;
s->mesh_dropped = worker->env.mesh->stats_dropped;
s->mesh_replies_sent = worker->env.mesh->replies_sent;
s->mesh_replies_sum_wait = worker->env.mesh->replies_sum_wait;
s->mesh_time_median = timehist_quartile(worker->env.mesh->histogram,
0.50);
/* add in the values from the mesh */
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
s->svr.ans_secure += worker->env.mesh->ans_secure;
s->svr.ans_bogus += worker->env.mesh->ans_bogus;
s->svr.ans_rcode_nodata += worker->env.mesh->ans_nodata;
for(i=0; i<16; i++)
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
s->svr.ans_rcode[i] += worker->env.mesh->ans_rcode[i];
timehist_export(worker->env.mesh->histogram, s->svr.hist,
NUM_BUCKETS_HIST);
/* values from outside network */
s->svr.unwanted_replies = (long long)worker->back->unwanted_replies;
s->svr.qtcp_outgoing = (long long)worker->back->num_tcp_outgoing;
s->svr.unwanted_replies = worker->back->unwanted_replies;
s->svr.qtcp_outgoing = worker->back->num_tcp_outgoing;
/* get and reset validator rrset bogus number */
s->svr.rrset_bogus = (long long)get_rrset_bogus(worker);
s->svr.rrset_bogus = get_rrset_bogus(worker);
/* get cache sizes */
s->svr.msg_cache_count = (long long)count_slabhash_entries(worker->env.msg_cache);
s->svr.rrset_cache_count = (long long)count_slabhash_entries(&worker->env.rrset_cache->table);
s->svr.infra_cache_count = (long long)count_slabhash_entries(worker->env.infra_cache->hosts);
s->svr.msg_cache_count = count_slabhash_entries(worker->env.msg_cache);
s->svr.rrset_cache_count = count_slabhash_entries(&worker->env.rrset_cache->table);
s->svr.infra_cache_count = count_slabhash_entries(worker->env.infra_cache->hosts);
if(worker->env.key_cache)
s->svr.key_cache_count = (long long)count_slabhash_entries(worker->env.key_cache->slab);
s->svr.key_cache_count = count_slabhash_entries(worker->env.key_cache->slab);
else s->svr.key_cache_count = 0;
/* get tcp accept usage */
s->svr.tcp_accept_usage = 0;
for(lp = worker->front->cps; lp; lp = lp->next) {
if(lp->com->type == comm_tcp_accept)
s->svr.tcp_accept_usage += (long long)lp->com->cur_tcp_count;
s->svr.tcp_accept_usage += lp->com->cur_tcp_count;
}
if(reset && !worker->env.cfg->stat_cumulative) {
@@ -192,7 +189,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
}
void server_stats_obtain(struct worker* worker, struct worker* who,
struct ub_stats_info* s, int reset)
struct stats_info* s, int reset)
{
uint8_t *reply = NULL;
uint32_t len = 0;
@@ -218,7 +215,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
void server_stats_reply(struct worker* worker, int reset)
{
struct ub_stats_info s;
struct stats_info s;
server_stats_compile(worker, &s, reset);
verbose(VERB_ALGO, "write stats replymsg");
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
@@ -226,21 +223,12 @@ void server_stats_reply(struct worker* worker, int reset)
fatal_exit("could not write stat values over cmd channel");
}
void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
void server_stats_add(struct stats_info* total, struct stats_info* a)
{
total->svr.num_queries += a->svr.num_queries;
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
#ifdef USE_DNSCRYPT
total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
total->svr.num_query_dnscrypt_cleartext += \
a->svr.num_query_dnscrypt_cleartext;
total->svr.num_query_dnscrypt_crypted_malformed += \
a->svr.num_query_dnscrypt_crypted_malformed;
#endif
/* the max size reached is upped to higher of both */
if(a->svr.max_query_list_size > total->svr.max_query_list_size)
total->svr.max_query_list_size = a->svr.max_query_list_size;
@@ -270,13 +258,13 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.unwanted_replies += a->svr.unwanted_replies;
total->svr.unwanted_queries += a->svr.unwanted_queries;
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
for(i=0; i<UB_STATS_QTYPE_NUM; i++)
for(i=0; i<STATS_QTYPE_NUM; i++)
total->svr.qtype[i] += a->svr.qtype[i];
for(i=0; i<UB_STATS_QCLASS_NUM; i++)
for(i=0; i<STATS_QCLASS_NUM; i++)
total->svr.qclass[i] += a->svr.qclass[i];
for(i=0; i<UB_STATS_OPCODE_NUM; i++)
for(i=0; i<STATS_OPCODE_NUM; i++)
total->svr.qopcode[i] += a->svr.qopcode[i];
for(i=0; i<UB_STATS_RCODE_NUM; i++)
for(i=0; i<STATS_RCODE_NUM; i++)
total->svr.ans_rcode[i] += a->svr.ans_rcode[i];
for(i=0; i<NUM_BUCKETS_HIST; i++)
total->svr.hist[i] += a->svr.hist[i];
@@ -287,22 +275,22 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->mesh_jostled += a->mesh_jostled;
total->mesh_dropped += a->mesh_dropped;
total->mesh_replies_sent += a->mesh_replies_sent;
stats_timeval_add(&total->mesh_replies_sum_wait_sec, &total->mesh_replies_sum_wait_usec, a->mesh_replies_sum_wait_sec, a->mesh_replies_sum_wait_usec);
timeval_add(&total->mesh_replies_sum_wait, &a->mesh_replies_sum_wait);
/* the medians are averaged together, this is not as accurate as
* taking the median over all of the data, but is good and fast
* added up here, division later*/
total->mesh_time_median += a->mesh_time_median;
}
void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
struct comm_reply* repinfo)
{
uint16_t flags = sldns_buffer_read_u16_at(c->buffer, 2);
if(qtype < UB_STATS_QTYPE_NUM)
if(qtype < STATS_QTYPE_NUM)
stats->qtype[qtype]++;
else stats->qtype_big++;
if(qclass < UB_STATS_QCLASS_NUM)
if(qclass < STATS_QCLASS_NUM)
stats->qclass[qclass]++;
else stats->qclass_big++;
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
@@ -333,7 +321,7 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
}
}
void server_stats_insrcode(struct ub_server_stats* stats, sldns_buffer* buf)
void server_stats_insrcode(struct server_stats* stats, sldns_buffer* buf)
{
if(stats->extended && sldns_buffer_limit(buf) != 0) {
int r = (int)LDNS_RCODE_WIRE( sldns_buffer_begin(buf) );
+131 -11
View File
@@ -50,24 +50,144 @@ struct comm_reply;
struct edns_data;
struct sldns_buffer;
/* stats struct */
#include "libunbound/unbound.h"
/** number of qtype that is stored for in array */
#define STATS_QTYPE_NUM 256
/** number of qclass that is stored for in array */
#define STATS_QCLASS_NUM 256
/** number of rcodes in stats */
#define STATS_RCODE_NUM 16
/** number of opcodes in stats */
#define STATS_OPCODE_NUM 16
/** per worker statistics */
struct server_stats {
/** number of queries from clients received. */
size_t num_queries;
/** number of queries that had a cache-miss. */
size_t num_queries_missed_cache;
/** number of prefetch queries - cachehits with prefetch */
size_t num_queries_prefetch;
/**
* Sum of the querylistsize of the worker for
* every query that missed cache. To calculate average.
*/
size_t sum_query_list_size;
/** max value of query list size reached. */
size_t max_query_list_size;
/** Extended stats below (bool) */
int extended;
/** qtype stats */
size_t qtype[STATS_QTYPE_NUM];
/** bigger qtype values not in array */
size_t qtype_big;
/** qclass stats */
size_t qclass[STATS_QCLASS_NUM];
/** bigger qclass values not in array */
size_t qclass_big;
/** query opcodes */
size_t qopcode[STATS_OPCODE_NUM];
/** number of queries over TCP */
size_t qtcp;
/** number of outgoing queries over TCP */
size_t qtcp_outgoing;
/** number of queries over IPv6 */
size_t qipv6;
/** number of queries with QR bit */
size_t qbit_QR;
/** number of queries with AA bit */
size_t qbit_AA;
/** number of queries with TC bit */
size_t qbit_TC;
/** number of queries with RD bit */
size_t qbit_RD;
/** number of queries with RA bit */
size_t qbit_RA;
/** number of queries with Z bit */
size_t qbit_Z;
/** number of queries with AD bit */
size_t qbit_AD;
/** number of queries with CD bit */
size_t qbit_CD;
/** number of queries with EDNS OPT record */
size_t qEDNS;
/** number of queries with EDNS with DO flag */
size_t qEDNS_DO;
/** answer rcodes */
size_t ans_rcode[STATS_RCODE_NUM];
/** answers with pseudo rcode 'nodata' */
size_t ans_rcode_nodata;
/** answers that were secure (AD) */
size_t ans_secure;
/** answers that were bogus (withheld as SERVFAIL) */
size_t ans_bogus;
/** rrsets marked bogus by validator */
size_t rrset_bogus;
/** unwanted traffic received on server-facing ports */
size_t unwanted_replies;
/** unwanted traffic received on client-facing ports */
size_t unwanted_queries;
/** usage of tcp accept list */
size_t tcp_accept_usage;
/** answers served from expired cache */
size_t zero_ttl_responses;
/** histogram data exported to array
* if the array is the same size, no data is lost, and
* if all histograms are same size (is so by default) then
* adding up works well. */
size_t hist[NUM_BUCKETS_HIST];
/** number of message cache entries */
size_t msg_cache_count;
/** number of rrset cache entries */
size_t rrset_cache_count;
/** number of infra cache entries */
size_t infra_cache_count;
/** number of key cache entries */
size_t key_cache_count;
};
/**
* Statistics to send over the control pipe when asked
* This struct is made to be memcpied, sent in binary.
*/
struct stats_info {
/** the thread stats */
struct server_stats svr;
/** mesh stats: current number of states */
size_t mesh_num_states;
/** mesh stats: current number of reply (user) states */
size_t mesh_num_reply_states;
/** mesh stats: number of reply states overwritten with a new one */
size_t mesh_jostled;
/** mesh stats: number of incoming queries dropped */
size_t mesh_dropped;
/** mesh stats: replies sent */
size_t mesh_replies_sent;
/** mesh stats: sum of waiting times for the replies */
struct timeval mesh_replies_sum_wait;
/** mesh stats: median of waiting times for replies (in sec) */
double mesh_time_median;
};
/**
* Initialize server stats to 0.
* @param stats: what to init (this is alloced by the caller).
* @param cfg: with extended statistics option.
*/
void server_stats_init(struct ub_server_stats* stats, struct config_file* cfg);
void server_stats_init(struct server_stats* stats, struct config_file* cfg);
/** add query if it missed the cache */
void server_stats_querymiss(struct ub_server_stats* stats, struct worker* worker);
void server_stats_querymiss(struct server_stats* stats, struct worker* worker);
/** add query if was cached and also resulted in a prefetch */
void server_stats_prefetch(struct ub_server_stats* stats, struct worker* worker);
void server_stats_prefetch(struct server_stats* stats, struct worker* worker);
/** display the stats to the log */
void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
void server_stats_log(struct server_stats* stats, struct worker* worker,
int threadnum);
/**
@@ -78,7 +198,7 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
* @param reset: if stats can be reset.
*/
void server_stats_obtain(struct worker* worker, struct worker* who,
struct ub_stats_info* s, int reset);
struct stats_info* s, int reset);
/**
* Compile stats into structure for this thread worker.
@@ -88,7 +208,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
* @param reset: if true, depending on config stats are reset.
* if false, statistics are not reset.
*/
void server_stats_compile(struct worker* worker, struct ub_stats_info* s,
void server_stats_compile(struct worker* worker, struct stats_info* s,
int reset);
/**
@@ -104,7 +224,7 @@ void server_stats_reply(struct worker* worker, int reset);
* @param total: sum of the two entries.
* @param a: to add to it.
*/
void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a);
void server_stats_add(struct stats_info* total, struct stats_info* a);
/**
* Add stats for this query
@@ -115,7 +235,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a);
* @param edns: edns record
* @param repinfo: reply info with remote address
*/
void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
struct comm_reply* repinfo);
@@ -124,6 +244,6 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
* @param stats: the stats
* @param buf: buffer with rcode. If buffer is length0: not counted.
*/
void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf);
void server_stats_insrcode(struct server_stats* stats, struct sldns_buffer* buf);
#endif /* DAEMON_STATS_H */
-5
View File
@@ -264,11 +264,6 @@ apply_settings(struct daemon* daemon, struct config_file* cfg,
}
daemon_apply_cfg(daemon, cfg);
checkrlimits(cfg);
if (cfg->use_systemd && cfg->do_daemonize) {
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
}
log_ident_set_fromdefault(cfg, log_default_identity);
}
+34 -408
View File
@@ -69,13 +69,9 @@
#include "iterator/iter_hints.h"
#include "validator/autotrust.h"
#include "validator/val_anchor.h"
#include "respip/respip.h"
#include "libunbound/context.h"
#include "libunbound/libworker.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -117,9 +113,6 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
size_t total, front, back, mesh, msg, rrset, infra, ac, superac;
size_t me, iter, val, anch;
int i;
#ifdef CLIENT_SUBNET
size_t subnet = 0;
#endif /* CLIENT_SUBNET */
if(verbosity < VERB_ALGO)
return;
front = listen_get_mem(worker->front);
@@ -139,12 +132,6 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
val += (*worker->env.mesh->mods.mod[i]->get_mem)
(&worker->env, i);
#ifdef CLIENT_SUBNET
else if(strcmp(worker->env.mesh->mods.mod[i]->name,
"subnet")==0)
subnet += (*worker->env.mesh->mods.mod[i]->get_mem)
(&worker->env, i);
#endif /* CLIENT_SUBNET */
else iter += (*worker->env.mesh->mods.mod[i]->get_mem)
(&worker->env, i);
}
@@ -162,17 +149,6 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
me += serviced_get_mem(cur_serv);
}
total = front+back+mesh+msg+rrset+infra+iter+val+ac+superac+me;
#ifdef CLIENT_SUBNET
total += subnet;
log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
"rrset=%u infra=%u iter=%u val=%u subnet=%u anchors=%u "
"alloccache=%u globalalloccache=%u me=%u",
(unsigned)total, (unsigned)front, (unsigned)back,
(unsigned)mesh, (unsigned)msg, (unsigned)rrset, (unsigned)infra,
(unsigned)iter, (unsigned)val,
(unsigned)subnet, (unsigned)anch, (unsigned)ac,
(unsigned)superac, (unsigned)me);
#else /* no CLIENT_SUBNET */
log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
"rrset=%u infra=%u iter=%u val=%u anchors=%u "
"alloccache=%u globalalloccache=%u me=%u",
@@ -180,15 +156,11 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
(unsigned)mesh, (unsigned)msg, (unsigned)rrset,
(unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch,
(unsigned)ac, (unsigned)superac, (unsigned)me);
#endif /* CLIENT_SUBNET */
log_info("Total heap memory estimate: %u total-alloc: %u "
"total-free: %u", (unsigned)total,
(unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed);
#else /* no UNBOUND_ALLOC_STATS */
size_t val = 0;
#ifdef CLIENT_SUBNET
size_t subnet = 0;
#endif /* CLIENT_SUBNET */
int i;
if(verbosity < VERB_QUERY)
return;
@@ -198,27 +170,12 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
val += (*worker->env.mesh->mods.mod[i]->get_mem)
(&worker->env, i);
#ifdef CLIENT_SUBNET
else if(strcmp(worker->env.mesh->mods.mod[i]->name,
"subnet")==0)
subnet += (*worker->env.mesh->mods.mod[i]->get_mem)
(&worker->env, i);
#endif /* CLIENT_SUBNET */
}
#ifdef CLIENT_SUBNET
verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u "
"subnet=%u",
(unsigned)slabhash_get_mem(worker->env.msg_cache),
(unsigned)slabhash_get_mem(&worker->env.rrset_cache->table),
(unsigned)infra_get_mem(worker->env.infra_cache),
(unsigned)val, (unsigned)subnet);
#else /* no CLIENT_SUBNET */
verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u",
(unsigned)slabhash_get_mem(worker->env.msg_cache),
(unsigned)slabhash_get_mem(&worker->env.rrset_cache->table),
(unsigned)infra_get_mem(worker->env.infra_cache),
(unsigned)val);
#endif /* CLIENT_SUBNET */
#endif /* UNBOUND_ALLOC_STATS */
}
@@ -553,70 +510,17 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
return 1;
}
/** Apply, if applicable, a response IP action to a cached answer.
* If the answer is rewritten as a result of an action, '*encode_repp' will
* point to the reply info containing the modified answer. '*encode_repp' will
* be intact otherwise.
* It returns 1 on success, 0 otherwise. */
static int
apply_respip_action(struct worker* worker, const struct query_info* qinfo,
struct respip_client_info* cinfo, struct reply_info* rep,
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
struct reply_info** encode_repp)
{
struct respip_action_info actinfo = {respip_none, NULL};
if(qinfo->qtype != LDNS_RR_TYPE_A &&
qinfo->qtype != LDNS_RR_TYPE_AAAA &&
qinfo->qtype != LDNS_RR_TYPE_ANY)
return 1;
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
alias_rrset, 0, worker->scratchpad))
return 0;
/* xxx_deny actions mean dropping the reply, unless the original reply
* was redirected to response-ip data. */
if((actinfo.action == respip_deny ||
actinfo.action == respip_inform_deny) &&
*encode_repp == rep)
*encode_repp = NULL;
/* If address info is returned, it means the action should be an
* 'inform' variant and the information should be logged. */
if(actinfo.addrinfo) {
respip_inform_print(actinfo.addrinfo, qinfo->qname,
qinfo->qtype, qinfo->qclass, qinfo->local_alias,
repinfo);
}
return 1;
}
/** answer query from the cache.
* Normally, the answer message will be built in repinfo->c->buffer; if the
* answer is supposed to be suppressed or the answer is supposed to be an
* incomplete CNAME chain, the buffer is explicitly cleared to signal the
* caller as such. In the latter case *partial_rep will point to the incomplete
* reply, and this function is (possibly) supposed to be called again with that
* *partial_rep value to complete the chain. In addition, if the query should
* be completely dropped, '*need_drop' will be set to 1. */
/** answer query from the cache */
static int
answer_from_cache(struct worker* worker, struct query_info* qinfo,
struct respip_client_info* cinfo, int* need_drop,
struct ub_packed_rrset_key** alias_rrset,
struct reply_info** partial_repp,
struct reply_info* rep, uint16_t id, uint16_t flags,
struct comm_reply* repinfo, struct edns_data* edns)
{
time_t timenow = *worker->env.now;
uint16_t udpsize = edns->udp_size;
struct reply_info* encode_rep = rep;
struct reply_info* partial_rep = *partial_repp;
int secure;
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
&& worker->env.need_to_validate;
*partial_repp = NULL; /* avoid accidental further pass */
if(worker->env.cfg->serve_expired) {
/* always lock rrsets, rep->ttl is ignored */
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
@@ -662,7 +566,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
goto bail_out;
return 0;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
rrset_array_unlock_touch(worker->env.rrset_cache,
@@ -695,34 +599,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
goto bail_out;
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
if(worker->daemon->use_response_ip && !partial_rep &&
!apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset,
&encode_rep)) {
goto bail_out;
} else if(partial_rep &&
!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
must_validate, &encode_rep, worker->scratchpad)) {
goto bail_out;
}
if(encode_rep != rep)
secure = 0; /* if rewritten, it can't be considered "secure" */
if(!encode_rep || *alias_rrset) {
sldns_buffer_clear(repinfo->c->buffer);
sldns_buffer_flip(repinfo->c->buffer);
if(!encode_rep)
*need_drop = 1;
else {
/* If a partial CNAME chain is found, we first need to
* make a copy of the reply in the scratchpad so we
* can release the locks and lookup the cache again. */
*partial_repp = reply_info_copy(encode_rep, NULL,
worker->scratchpad);
if(!*partial_repp)
goto bail_out;
}
} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
return 0;
if(!reply_info_answer_encode(qinfo, rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
@@ -743,18 +621,14 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
return 1;
}
/** Reply to client and perform prefetch to keep cache up to date.
* If the buffer for the reply is empty, it indicates that only prefetch is
* necessary and the reply should be suppressed (because it's dropped or
* being deferred). */
/** Reply to client and perform prefetch to keep cache up to date */
static void
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
uint16_t flags, struct comm_reply* repinfo, time_t leeway)
{
/* first send answer to client to keep its latency
* as small as a cachereply */
if(sldns_buffer_limit(repinfo->c->buffer) != 0)
comm_point_send_reply(repinfo);
comm_point_send_reply(repinfo);
server_stats_prefetch(&worker->stats, worker);
/* create the prefetch in the mesh as a normal lookup without
@@ -769,41 +643,36 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
* Fill CH class answer into buffer. Keeps query.
* @param pkt: buffer
* @param str: string to put into text record (<255).
* array of strings, every string becomes a text record.
* @param num: number of strings in array.
* @param edns: edns reply information.
* @param worker: worker with scratch region.
*/
static void
chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
chaos_replystr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
struct worker* worker)
{
int i;
size_t len = strlen(str);
unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt));
unsigned int cd = LDNS_CD_WIRE(sldns_buffer_begin(pkt));
if(len>255) len=255; /* cap size of TXT record */
sldns_buffer_clear(pkt);
sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */
sldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA));
if(rd) LDNS_RD_SET(sldns_buffer_begin(pkt));
if(cd) LDNS_CD_SET(sldns_buffer_begin(pkt));
sldns_buffer_write_u16(pkt, 1); /* qdcount */
sldns_buffer_write_u16(pkt, (uint16_t)num); /* ancount */
sldns_buffer_write_u16(pkt, 1); /* ancount */
sldns_buffer_write_u16(pkt, 0); /* nscount */
sldns_buffer_write_u16(pkt, 0); /* arcount */
(void)query_dname_len(pkt); /* skip qname */
sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */
sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */
for(i=0; i<num; i++) {
size_t len = strlen(str[i]);
if(len>255) len=255; /* cap size of TXT record */
sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */
sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT);
sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH);
sldns_buffer_write_u32(pkt, 0); /* TTL */
sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len);
sldns_buffer_write_u8(pkt, len);
sldns_buffer_write(pkt, str[i], len);
}
sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */
sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT);
sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH);
sldns_buffer_write_u32(pkt, 0); /* TTL */
sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len);
sldns_buffer_write_u8(pkt, len);
sldns_buffer_write(pkt, str, len);
sldns_buffer_flip(pkt);
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
@@ -811,73 +680,7 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
LDNS_RCODE_NOERROR, edns, worker->scratchpad))
edns->opt_list = NULL;
if(sldns_buffer_capacity(pkt) >=
sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
attach_edns_record(pkt, edns);
}
/** Reply with one string */
static void
chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
struct worker* worker)
{
chaos_replystr(pkt, (char**)&str, 1, edns, worker);
}
/**
* Create CH class trustanchor answer.
* @param pkt: buffer
* @param edns: edns reply information.
* @param w: worker with scratch region.
*/
static void
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
{
#define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */
#define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */
char* str_array[TA_RESPONSE_MAX_TXT];
uint16_t tags[TA_RESPONSE_MAX_TAGS];
int num = 0;
struct trust_anchor* ta;
if(!w->env.need_to_validate) {
/* no validator module, reply no trustanchors */
chaos_replystr(pkt, NULL, 0, edns, w);
return;
}
/* fill the string with contents */
lock_basic_lock(&w->env.anchors->lock);
RBTREE_FOR(ta, struct trust_anchor*, w->env.anchors->tree) {
char* str;
size_t i, numtag, str_len = 255;
if(num == TA_RESPONSE_MAX_TXT) continue;
str = (char*)regional_alloc(w->scratchpad, str_len);
if(!str) continue;
lock_basic_lock(&ta->lock);
numtag = anchor_list_keytags(ta, tags, TA_RESPONSE_MAX_TAGS);
if(numtag == 0) {
/* empty, insecure point */
lock_basic_unlock(&ta->lock);
continue;
}
str_array[num] = str;
num++;
/* spool name of anchor */
(void)sldns_wire2str_dname_buf(ta->name, ta->namelen, str, str_len);
str_len -= strlen(str); str += strlen(str);
/* spool tags */
for(i=0; i<numtag; i++) {
snprintf(str, str_len, " %u", (unsigned)tags[i]);
str_len -= strlen(str); str += strlen(str);
}
lock_basic_unlock(&ta->lock);
}
lock_basic_unlock(&w->env.anchors->lock);
chaos_replystr(pkt, str_array, num, edns, w);
regional_free_all(w->scratchpad);
attach_edns_record(pkt, edns);
}
/**
@@ -906,13 +709,13 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
char buf[MAXHOSTNAMELEN+1];
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
buf[MAXHOSTNAMELEN] = 0;
chaos_replyonestr(pkt, buf, edns, w);
chaos_replystr(pkt, buf, edns, w);
} else {
log_err("gethostname: %s", strerror(errno));
chaos_replyonestr(pkt, "no hostname", edns, w);
chaos_replystr(pkt, "no hostname", edns, w);
}
}
else chaos_replyonestr(pkt, cfg->identity, edns, w);
else chaos_replystr(pkt, cfg->identity, edns, w);
return 1;
}
if(query_dname_compare(qinfo->qname,
@@ -923,19 +726,10 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
if(cfg->hide_version)
return 0;
if(cfg->version==NULL || cfg->version[0]==0)
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w);
else chaos_replyonestr(pkt, cfg->version, edns, w);
chaos_replystr(pkt, PACKAGE_STRING, edns, w);
else chaos_replystr(pkt, cfg->version, edns, w);
return 1;
}
if(query_dname_compare(qinfo->qname,
(uint8_t*)"\013trustanchor\007unbound") == 0)
{
if(cfg->hide_trustanchor)
return 0;
chaos_trustanchor(pkt, edns, w);
return 1;
}
return 0;
}
@@ -993,72 +787,19 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
{
struct worker* worker = (struct worker*)arg;
int ret;
hashvalue_type h;
hashvalue_t h;
struct lruhash_entry* e;
struct query_info qinfo;
struct edns_data edns;
enum acl_access acl;
struct acl_addr* acladdr;
int rc = 0;
int need_drop = 0;
/* We might have to chase a CNAME chain internally, in which case
* we'll have up to two replies and combine them to build a complete
* answer. These variables control this case. */
struct ub_packed_rrset_key* alias_rrset = NULL;
struct reply_info* partial_rep = NULL;
struct query_info* lookup_qinfo = &qinfo;
struct query_info qinfo_tmp; /* placeholdoer for lookup_qinfo */
struct respip_client_info* cinfo = NULL, cinfo_tmp;
if(error != NETEVENT_NOERROR) {
/* some bad tcp query DNS formats give these error calls */
verbose(VERB_ALGO, "handle request called with err=%d", error);
return 0;
}
#ifdef USE_DNSCRYPT
repinfo->max_udp_size = worker->daemon->cfg->max_udp_size;
if(!dnsc_handle_curved_request(worker->daemon->dnscenv, repinfo)) {
worker->stats.num_query_dnscrypt_crypted_malformed++;
return 0;
}
if(c->dnscrypt && !repinfo->is_dnscrypted) {
char buf[LDNS_MAX_DOMAINLEN+1];
/* Check if this is unencrypted and asking for certs */
if(worker_check_request(c->buffer, worker) != 0) {
verbose(VERB_ALGO,
"dnscrypt: worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->addr,
repinfo->addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
if(!query_info_parse(&qinfo, c->buffer)) {
verbose(VERB_ALGO,
"dnscrypt: worker parse request: formerror.");
log_addr(VERB_CLIENT, "from", &repinfo->addr,
repinfo->addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
dname_str(qinfo.qname, buf);
if(!(qinfo.qtype == LDNS_RR_TYPE_TXT &&
strcasecmp(buf,
worker->daemon->dnscenv->provider_name) == 0)) {
verbose(VERB_ALGO,
"dnscrypt: not TXT %s. Receive: %s %s",
worker->daemon->dnscenv->provider_name,
sldns_rr_descript(qinfo.qtype)->_name,
buf);
comm_point_drop_reply(repinfo);
worker->stats.num_query_dnscrypt_cleartext++;
return 0;
}
worker->stats.num_query_dnscrypt_cert++;
sldns_buffer_rewind(c->buffer);
} else if(c->dnscrypt && repinfo->is_dnscrypted) {
worker->stats.num_query_dnscrypt_crypted++;
}
#endif
#ifdef USE_DNSTAP
if(worker->dtenv.log_client_query_messages)
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
@@ -1084,29 +825,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
worker->stats.num_queries++;
/* check if this query should be dropped based on source ip rate limiting */
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
*worker->env.now)) {
/* See if we are passed through with slip factor */
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
ub_random_max(worker->env.rnd,
worker->env.cfg->ip_ratelimit_factor) == 1) {
char addrbuf[128];
addr_to_str(&repinfo->addr, repinfo->addrlen,
addrbuf, sizeof(addrbuf));
verbose(VERB_OPS, "ip_ratelimit allowed through for ip address %s ",
addrbuf);
} else {
worker->stats.num_queries_ip_ratelimited++;
comm_point_drop_reply(repinfo);
return 0;
}
}
/* see if query is in the cache */
if(!query_info_parse(&qinfo, c->buffer)) {
verbose(VERB_ALGO, "worker parse request: formerror.");
@@ -1141,28 +860,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
goto send_reply;
}
if(qinfo.qtype == LDNS_RR_TYPE_OPT ||
qinfo.qtype == LDNS_RR_TYPE_TSIG ||
qinfo.qtype == LDNS_RR_TYPE_TKEY ||
qinfo.qtype == LDNS_RR_TYPE_MAILA ||
qinfo.qtype == LDNS_RR_TYPE_MAILB ||
(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
verbose(VERB_ALGO, "worker request: formerror for meta-type.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
comm_point_drop_reply(repinfo);
return 0;
}
sldns_buffer_rewind(c->buffer);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
server_stats_insrcode(&worker->stats, c->buffer);
}
goto send_reply;
}
if((ret=parse_edns_from_pkt(c->buffer, &edns, worker->scratchpad)) != 0) {
struct edns_data reply_edns;
verbose(VERB_ALGO, "worker parse edns: formerror.");
@@ -1189,9 +886,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
@@ -1297,43 +992,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
qinfo.qname_len = d->rr_len[0] - 2;
}
/* If we may apply IP-based actions to the answer, build the client
* information. As this can be expensive, skip it if there is
* absolutely no possibility of it. */
if(worker->daemon->use_response_ip &&
(qinfo.qtype == LDNS_RR_TYPE_A ||
qinfo.qtype == LDNS_RR_TYPE_AAAA ||
qinfo.qtype == LDNS_RR_TYPE_ANY)) {
cinfo_tmp.taglist = acladdr->taglist;
cinfo_tmp.taglen = acladdr->taglen;
cinfo_tmp.tag_actions = acladdr->tag_actions;
cinfo_tmp.tag_actions_size = acladdr->tag_actions_size;
cinfo_tmp.tag_datas = acladdr->tag_datas;
cinfo_tmp.tag_datas_size = acladdr->tag_datas_size;
cinfo_tmp.view = acladdr->view;
cinfo_tmp.respip_set = worker->daemon->respip_set;
cinfo = &cinfo_tmp;
}
lookup_cache:
/* Lookup the cache. In case we chase an intermediate CNAME chain
* this is a two-pass operation, and lookup_qinfo is different for
* each pass. We should still pass the original qinfo to
* answer_from_cache(), however, since it's used to build the reply. */
if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) {
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
if(answer_from_cache(worker, &qinfo,
cinfo, &need_drop, &alias_rrset, &partial_rep,
(struct reply_info*)e->data,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
&edns)) {
/* prefetch it if the prefetch TTL expired.
* Note that if there is more than one pass
* its qname must be that used for cache
* lookup. */
/* prefetch it if the prefetch TTL expired */
if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
&& *worker->env.now >=
((struct reply_info*)e->data)->prefetch_ttl) {
@@ -1343,38 +1011,16 @@ lookup_cache:
< *worker->env.now)
leeway = 0;
lock_rw_unlock(&e->lock);
reply_and_prefetch(worker, lookup_qinfo,
reply_and_prefetch(worker, &qinfo,
sldns_buffer_read_u16_at(c->buffer, 2),
repinfo, leeway);
if(!partial_rep) {
rc = 0;
regional_free_all(worker->scratchpad);
goto send_reply_rc;
}
} else if(!partial_rep) {
lock_rw_unlock(&e->lock);
rc = 0;
regional_free_all(worker->scratchpad);
goto send_reply;
goto send_reply_rc;
}
/* We've found a partial reply ending with an
* alias. Replace the lookup qinfo for the
* alias target and lookup the cache again to
* (possibly) complete the reply. As we're
* passing the "base" reply, there will be no
* more alias chasing. */
lock_rw_unlock(&e->lock);
memset(&qinfo_tmp, 0, sizeof(qinfo_tmp));
get_cname_target(alias_rrset, &qinfo_tmp.qname,
&qinfo_tmp.qname_len);
if(!qinfo_tmp.qname) {
log_err("unexpected: invalid answer alias");
regional_free_all(worker->scratchpad);
return 0; /* drop query */
}
qinfo_tmp.qtype = qinfo.qtype;
qinfo_tmp.qclass = qinfo.qclass;
lookup_qinfo = &qinfo_tmp;
goto lookup_cache;
regional_free_all(worker->scratchpad);
goto send_reply;
}
verbose(VERB_ALGO, "answer from the cache failed");
lock_rw_unlock(&e->lock);
@@ -1403,7 +1049,7 @@ lookup_cache:
}
/* grab a work request structure for this new request */
mesh_new_client(worker->env.mesh, &qinfo, cinfo,
mesh_new_client(worker->env.mesh, &qinfo,
sldns_buffer_read_u16_at(c->buffer, 2),
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer));
regional_free_all(worker->scratchpad);
@@ -1413,25 +1059,10 @@ lookup_cache:
send_reply:
rc = 1;
send_reply_rc:
if(need_drop) {
comm_point_drop_reply(repinfo);
return 0;
}
#ifdef USE_DNSTAP
if(worker->dtenv.log_client_response_messages)
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
c->type, c->buffer);
#endif
if(worker->env.cfg->log_replies)
{
struct timeval tv = {0, 0};
log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
tv, 1, c->buffer);
}
#ifdef USE_DNSCRYPT
if(!dnsc_handle_uncurved_request(repinfo)) {
return 0;
}
#endif
return rc;
}
@@ -1488,10 +1119,6 @@ void worker_stat_timer_cb(void* arg)
server_stats_log(&worker->stats, worker, worker->thread_num);
mesh_stats(worker->env.mesh, "mesh has");
worker_mem_report(worker, NULL);
/* SHM is enabled, process data to SHM */
if (worker->daemon->cfg->shm_enable) {
shm_main_run(worker);
}
if(!worker->daemon->cfg->stat_cumulative) {
worker_stats_clear(worker);
}
@@ -1673,7 +1300,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
worker->env.detach_subs = &mesh_detach_subs;
worker->env.attach_sub = &mesh_attach_sub;
worker->env.add_sub = &mesh_add_sub;
worker->env.kill_sub = &mesh_state_delete;
worker->env.detect_cycle = &mesh_detect_cycle;
worker->env.scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
+2 -2
View File
@@ -85,7 +85,7 @@ struct worker {
/** global shared daemon structure */
struct daemon* daemon;
/** thread id */
ub_thread_type thr_id;
ub_thread_t thr_id;
/** pipe, for commands for this worker */
struct tube* cmd;
/** the event base this worker works with */
@@ -116,7 +116,7 @@ struct worker {
/** allocation cache for this thread */
struct alloc_cache alloc;
/** per thread statistics */
struct ub_server_stats stats;
struct server_stats stats;
/** thread scratch regional */
struct regional* scratchpad;
+26 -1
View File
@@ -411,6 +411,31 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
return module_wait_subquery;
}
/** allocate (special) rrset keys, return 0 on error */
static int
repinfo_alloc_rrset_keys(struct reply_info* rep,
struct regional* region)
{
size_t i;
for(i=0; i<rep->rrset_count; i++) {
if(region) {
rep->rrsets[i] = (struct ub_packed_rrset_key*)
regional_alloc(region,
sizeof(struct ub_packed_rrset_key));
if(rep->rrsets[i]) {
memset(rep->rrsets[i], 0,
sizeof(struct ub_packed_rrset_key));
rep->rrsets[i]->entry.key = rep->rrsets[i];
}
}
else return 0;/* rep->rrsets[i] = alloc_special_obtain(alloc);*/
if(!rep->rrsets[i])
return 0;
rep->rrsets[i]->entry.data = NULL;
}
return 1;
}
static enum module_ext_state
generate_type_A_query(struct module_qstate* qstate, int id)
{
@@ -682,7 +707,7 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
return;
/* allocate ub_key structures special or not */
if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) {
if(!repinfo_alloc_rrset_keys(cp, super->region)) {
return;
}
-32
View File
@@ -1,32 +0,0 @@
#ifndef UNBOUND_DNSCRYPT_CERT_H
#define UNBOUND_DNSCRYPT_CERT_H
/**
* \file
* certificate type for dnscrypt for use in other header files
*/
#include <sodium.h>
#define CERT_MAGIC_CERT "DNSC"
#define CERT_MAJOR_VERSION 1
#define CERT_MINOR_VERSION 0
#define CERT_OLD_MAGIC_HEADER "7PYqwfzt"
#define CERT_FILE_EXPIRE_DAYS 365
struct SignedCert {
uint8_t magic_cert[4];
uint8_t version_major[2];
uint8_t version_minor[2];
// Signed Content
uint8_t signed_content[64];
uint8_t server_publickey[crypto_box_PUBLICKEYBYTES];
uint8_t magic_query[8];
uint8_t serial[4];
uint8_t ts_begin[4];
uint8_t ts_end[4];
};
#endif
-651
View File
@@ -1,651 +0,0 @@
#include "config.h"
#include <stdlib.h>
#include <fcntl.h>
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#include "sldns/sbuffer.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/netevent.h"
#include "util/log.h"
#include "dnscrypt/cert.h"
#include "dnscrypt/dnscrypt.h"
#include "dnscrypt/dnscrypt_config.h"
#include <ctype.h>
/**
* \file
* dnscrypt functions for encrypting DNS packets.
*/
#define DNSCRYPT_QUERY_BOX_OFFSET \
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES)
// 8 bytes: magic header (CERT_MAGIC_HEADER)
// 12 bytes: the client's nonce
// 12 bytes: server nonce extension
// 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
#define DNSCRYPT_REPLY_BOX_OFFSET \
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES + crypto_box_HALF_NONCEBYTES)
/**
* Decrypt a query using the dnsccert that was found using dnsc_find_cert.
* The client nonce will be extracted from the encrypted query and stored in
* client_nonce, a shared secret will be computed and stored in nmkey and the
* buffer will be decrypted inplace.
* \param[in] cert the cert that matches this encrypted query.
* \param[in] client_nonce where the client nonce will be stored.
* \param[in] nmkey where the shared secret key will be written.
* \param[in] buffer the encrypted buffer.
* \return 0 on success.
*/
static int
dnscrypt_server_uncurve(const dnsccert *cert,
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
uint8_t nmkey[crypto_box_BEFORENMBYTES],
struct sldns_buffer* buffer)
{
size_t len = sldns_buffer_limit(buffer);
uint8_t *const buf = sldns_buffer_begin(buffer);
uint8_t nonce[crypto_box_NONCEBYTES];
struct dnscrypt_query_header *query_header;
if (len <= DNSCRYPT_QUERY_HEADER_SIZE) {
return -1;
}
query_header = (struct dnscrypt_query_header *)buf;
memcpy(nmkey, query_header->publickey, crypto_box_PUBLICKEYBYTES);
if(cert->es_version[1] == 2) {
#ifdef USE_DNSCRYPT_XCHACHA20
if (crypto_box_curve25519xchacha20poly1305_beforenm(
nmkey, nmkey, cert->keypair->crypt_secretkey) != 0) {
return -1;
}
#else
return -1;
#endif
} else {
if (crypto_box_beforenm(nmkey, nmkey, cert->keypair->crypt_secretkey) != 0) {
return -1;
}
}
memcpy(nonce, query_header->nonce, crypto_box_HALF_NONCEBYTES);
memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES);
if(cert->es_version[1] == 2) {
#ifdef USE_DNSCRYPT_XCHACHA20
if (crypto_box_curve25519xchacha20poly1305_open_easy_afternm
(buf,
buf + DNSCRYPT_QUERY_BOX_OFFSET,
len - DNSCRYPT_QUERY_BOX_OFFSET, nonce,
nmkey) != 0) {
return -1;
}
#else
return -1;
#endif
} else {
if (crypto_box_open_easy_afternm
(buf,
buf + DNSCRYPT_QUERY_BOX_OFFSET,
len - DNSCRYPT_QUERY_BOX_OFFSET, nonce,
nmkey) != 0) {
return -1;
}
}
len -= DNSCRYPT_QUERY_HEADER_SIZE;
while (*sldns_buffer_at(buffer, --len) == 0)
;
if (*sldns_buffer_at(buffer, len) != 0x80) {
return -1;
}
memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
sldns_buffer_set_position(buffer, 0);
sldns_buffer_set_limit(buffer, len);
return 0;
}
/**
* Add random padding to a buffer, according to a client nonce.
* The length has to depend on the query in order to avoid reply attacks.
*
* @param buf a buffer
* @param len the initial size of the buffer
* @param max_len the maximum size
* @param nonce a nonce, made of the client nonce repeated twice
* @param secretkey
* @return the new size, after padding
*/
size_t
dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len,
const uint8_t *nonce, const uint8_t *secretkey)
{
uint8_t *buf_padding_area = buf + len;
size_t padded_len;
uint32_t rnd;
// no padding
if (max_len < len + DNSCRYPT_MIN_PAD_LEN)
return len;
assert(nonce[crypto_box_HALF_NONCEBYTES] == nonce[0]);
crypto_stream((unsigned char *)&rnd, (unsigned long long)sizeof(rnd), nonce,
secretkey);
padded_len =
len + DNSCRYPT_MIN_PAD_LEN + rnd % (max_len - len -
DNSCRYPT_MIN_PAD_LEN + 1);
padded_len += DNSCRYPT_BLOCK_SIZE - padded_len % DNSCRYPT_BLOCK_SIZE;
if (padded_len > max_len)
padded_len = max_len;
memset(buf_padding_area, 0, padded_len - len);
*buf_padding_area = 0x80;
return padded_len;
}
uint64_t
dnscrypt_hrtime(void)
{
struct timeval tv;
uint64_t ts = (uint64_t)0U;
int ret;
ret = gettimeofday(&tv, NULL);
if (ret == 0) {
ts = (uint64_t)tv.tv_sec * 1000000U + (uint64_t)tv.tv_usec;
} else {
log_err("gettimeofday: %s", strerror(errno));
}
return ts;
}
/**
* Add the server nonce part to once.
* The nonce is made half of client nonce and the seconf half of the server
* nonce, both of them of size crypto_box_HALF_NONCEBYTES.
* \param[in] nonce: a uint8_t* of size crypto_box_NONCEBYTES
*/
static void
add_server_nonce(uint8_t *nonce)
{
uint64_t ts;
uint64_t tsn;
uint32_t suffix;
ts = dnscrypt_hrtime();
// TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
// unclear if we really need it, so skipping it for now.
tsn = (ts << 10) | (randombytes_random() & 0x3ff);
#if (BYTE_ORDER == LITTLE_ENDIAN)
tsn =
(((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
#endif
memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
suffix = randombytes_random();
memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
}
/**
* Encrypt a reply using the dnsccert that was used with the query.
* The client nonce will be extracted from the encrypted query and stored in
* The buffer will be encrypted inplace.
* \param[in] cert the dnsccert that matches this encrypted query.
* \param[in] client_nonce client nonce used during the query
* \param[in] nmkey shared secret key used during the query.
* \param[in] buffer the buffer where to encrypt the reply.
* \param[in] udp if whether or not it is a UDP query.
* \param[in] max_udp_size configured max udp size.
* \return 0 on success.
*/
static int
dnscrypt_server_curve(const dnsccert *cert,
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
uint8_t nmkey[crypto_box_BEFORENMBYTES],
struct sldns_buffer* buffer,
uint8_t udp,
size_t max_udp_size)
{
size_t dns_reply_len = sldns_buffer_limit(buffer);
size_t max_len = dns_reply_len + DNSCRYPT_MAX_PADDING + DNSCRYPT_REPLY_HEADER_SIZE;
size_t max_reply_size = max_udp_size - 20U - 8U;
uint8_t nonce[crypto_box_NONCEBYTES];
uint8_t *boxed;
uint8_t *const buf = sldns_buffer_begin(buffer);
size_t len = sldns_buffer_limit(buffer);
if(udp){
if (max_len > max_reply_size)
max_len = max_reply_size;
}
memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
memcpy(nonce + crypto_box_HALF_NONCEBYTES, client_nonce,
crypto_box_HALF_NONCEBYTES);
boxed = buf + DNSCRYPT_REPLY_BOX_OFFSET;
memmove(boxed + crypto_box_MACBYTES, buf, len);
len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
max_len - DNSCRYPT_REPLY_HEADER_SIZE, nonce,
cert->keypair->crypt_secretkey);
sldns_buffer_set_at(buffer,
DNSCRYPT_REPLY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
0, crypto_box_ZEROBYTES);
// add server nonce extension
add_server_nonce(nonce);
if(cert->es_version[1] == 2) {
#ifdef USE_DNSCRYPT_XCHACHA20
if (crypto_box_curve25519xchacha20poly1305_easy_afternm
(boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
return -1;
}
#else
return -1;
#endif
} else {
if (crypto_box_easy_afternm
(boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
return -1;
}
}
sldns_buffer_write_at(buffer, 0, DNSCRYPT_MAGIC_RESPONSE, DNSCRYPT_MAGIC_HEADER_LEN);
sldns_buffer_write_at(buffer, DNSCRYPT_MAGIC_HEADER_LEN, nonce, crypto_box_NONCEBYTES);
sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
return 0;
}
/**
* Read the content of fname into buf.
* \param[in] fname name of the file to read.
* \param[in] buf the buffer in which to read the content of the file.
* \param[in] count number of bytes to read.
* \return 0 on success.
*/
static int
dnsc_read_from_file(char *fname, char *buf, size_t count)
{
int fd;
fd = open(fname, O_RDONLY);
if (fd == -1) {
return -1;
}
if (read(fd, buf, count) != (ssize_t)count) {
close(fd);
return -2;
}
close(fd);
return 0;
}
/**
* Given an absolute path on the original root, returns the absolute path
* within the chroot. If chroot is disabled, the path is not modified.
* No char * is malloced so there is no need to free this.
* \param[in] cfg the configuration.
* \param[in] path the path from the original root.
* \return the path from inside the chroot.
*/
static char *
dnsc_chroot_path(struct config_file *cfg, char *path)
{
char *nm;
nm = path;
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
nm += strlen(cfg->chrootdir);
return nm;
}
/**
* Parse certificates files provided by the configuration and load them into
* dnsc_env.
* \param[in] env the dnsc_env structure to load the certs into.
* \param[in] cfg the configuration.
* \return the number of certificates loaded.
*/
static int
dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
{
struct config_strlist *head;
size_t signed_cert_id;
char *nm;
env->signed_certs_count = 0U;
for (head = cfg->dnscrypt_provider_cert; head; head = head->next) {
env->signed_certs_count++;
}
env->signed_certs = sodium_allocarray(env->signed_certs_count,
sizeof *env->signed_certs);
signed_cert_id = 0U;
for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) {
nm = dnsc_chroot_path(cfg, head->str);
if(dnsc_read_from_file(
nm,
(char *)(env->signed_certs + signed_cert_id),
sizeof(struct SignedCert)) != 0) {
fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno));
}
verbose(VERB_OPS, "Loaded cert %s", head->str);
}
return signed_cert_id;
}
/**
* Helper function to convert a binary key into a printable fingerprint.
* \param[in] fingerprint the buffer in which to write the printable key.
* \param[in] key the key to convert.
*/
void
dnsc_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key)
{
const size_t fingerprint_size = 80U;
size_t fingerprint_pos = (size_t) 0U;
size_t key_pos = (size_t) 0U;
for (;;) {
assert(fingerprint_size > fingerprint_pos);
snprintf(&fingerprint[fingerprint_pos],
fingerprint_size - fingerprint_pos, "%02X%02X",
key[key_pos], key[key_pos + 1U]);
key_pos += 2U;
if (key_pos >= crypto_box_PUBLICKEYBYTES) {
break;
}
fingerprint[fingerprint_pos + 4U] = ':';
fingerprint_pos += 5U;
}
}
/**
* Find the cert matching a DNSCrypt query.
* \param[in] dnscenv The DNSCrypt enviroment, which contains the list of certs
* supported by the server.
* \param[in] buffer The encrypted DNS query.
* \return a dnsccert * if we found a cert matching the magic_number of the
* query, NULL otherwise.
*/
static const dnsccert *
dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
{
const dnsccert *certs = dnscenv->certs;
struct dnscrypt_query_header *dnscrypt_header;
size_t i;
if (sldns_buffer_limit(buffer) < DNSCRYPT_QUERY_HEADER_SIZE) {
return NULL;
}
dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
for (i = 0U; i < dnscenv->signed_certs_count; i++) {
if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query,
DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
return &certs[i];
}
}
return NULL;
}
/**
* Insert local-zone and local-data into configuration.
* In order to be able to serve certs over TXT, we can reuse the local-zone and
* local-data config option. The zone and qname are infered from the
* provider_name and the content of the TXT record from the certificate content.
* returns the number of certtificate TXT record that were loaded.
* < 0 in case of error.
*/
static int
dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
{
size_t i, j;
// Insert 'local-zone: "2.dnscrypt-cert.example.com" deny'
if(!cfg_str2list_insert(&cfg->local_zones,
strdup(dnscenv->provider_name),
strdup("deny"))) {
log_err("Could not load dnscrypt local-zone: %s deny",
dnscenv->provider_name);
return -1;
}
// Add local data entry of type:
// 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......"
for(i=0; i<dnscenv->signed_certs_count; i++) {
const char *ttl_class_type = " 86400 IN TXT \"";
struct SignedCert *cert = dnscenv->signed_certs + i;
uint16_t rrlen = strlen(dnscenv->provider_name) +
strlen(ttl_class_type) +
4 * sizeof(struct SignedCert) + // worst case scenario
1 + // trailing double quote
1;
char *rr = malloc(rrlen);
if(!rr) {
log_err("Could not allocate memory");
return -2;
}
snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name);
for(j=0; j<sizeof(struct SignedCert); j++) {
int c = (int)*((const uint8_t *) cert + j);
if (isprint(c) && c != '"' && c != '\\') {
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
} else {
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
}
}
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
cfg_strlist_insert(&cfg->local_data, strdup(rr));
free(rr);
}
return dnscenv->signed_certs_count;
}
static const char *
key_get_es_version(uint8_t version[2])
{
struct es_version {
uint8_t es_version[2];
const char *name;
};
struct es_version es_versions[] = {
{{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
{{0x00, 0x02}, "X25519-XChacha20Poly1305"},
};
int i;
for(i=0; i < (int)sizeof(es_versions); i++){
if(es_versions[i].es_version[0] == version[0] &&
es_versions[i].es_version[1] == version[1]){
return es_versions[i].name;
}
}
return NULL;
}
/**
* Parse the secret key files from `dnscrypt-secret-key` config and populates
* a list of dnsccert with es_version, magic number and secret/public keys
* supported by dnscrypt listener.
* \param[in] env The dnsc_env structure which will hold the keypairs.
* \param[in] cfg The config with the secret key file paths.
*/
static int
dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
{
struct config_strlist *head;
size_t cert_id, keypair_id;
size_t c;
char *nm;
env->keypairs_count = 0U;
for (head = cfg->dnscrypt_secret_key; head; head = head->next) {
env->keypairs_count++;
}
env->keypairs = sodium_allocarray(env->keypairs_count,
sizeof *env->keypairs);
env->certs = sodium_allocarray(env->signed_certs_count,
sizeof *env->certs);
cert_id = 0U;
keypair_id = 0U;
for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) {
char fingerprint[80];
int found_cert = 0;
KeyPair *current_keypair = &env->keypairs[keypair_id];
nm = dnsc_chroot_path(cfg, head->str);
if(dnsc_read_from_file(
nm,
(char *)(current_keypair->crypt_secretkey),
crypto_box_SECRETKEYBYTES) != 0) {
fatal_exit("dnsc_parse_keys: failed to load %s: %s", head->str, strerror(errno));
}
verbose(VERB_OPS, "Loaded key %s", head->str);
if (crypto_scalarmult_base(current_keypair->crypt_publickey,
current_keypair->crypt_secretkey) != 0) {
fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str);
}
dnsc_key_to_fingerprint(fingerprint, current_keypair->crypt_publickey);
verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint);
// find the cert matching this key
for(c = 0; c < env->signed_certs_count; c++) {
if(memcmp(current_keypair->crypt_publickey,
env->signed_certs[c].server_publickey,
crypto_box_PUBLICKEYBYTES) == 0) {
dnsccert *current_cert = &env->certs[cert_id++];
found_cert = 1;
current_cert->keypair = current_keypair;
memcpy(current_cert->magic_query,
env->signed_certs[c].magic_query,
sizeof env->signed_certs[c].magic_query);
memcpy(current_cert->es_version,
env->signed_certs[c].version_major,
sizeof env->signed_certs[c].version_major
);
dnsc_key_to_fingerprint(fingerprint,
current_cert->keypair->crypt_publickey);
verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s",
head->str, fingerprint);
verbose(VERB_OPS, "Using %s",
key_get_es_version(current_cert->es_version));
#ifndef USE_DNSCRYPT_XCHACHA20
if (current_cert->es_version[1] == 0x02) {
fatal_exit("Certificate for XChacha20 but libsodium does not support it.");
}
#endif
}
}
if (!found_cert) {
fatal_exit("dnsc_parse_keys: could not match certificate for key "
"%s. Unable to determine ES version.",
head->str);
}
}
return cert_id;
}
/**
* #########################################################
* ############# Publicly accessible functions #############
* #########################################################
*/
int
dnsc_handle_curved_request(struct dnsc_env* dnscenv,
struct comm_reply* repinfo)
{
struct comm_point* c = repinfo->c;
repinfo->is_dnscrypted = 0;
if( !c->dnscrypt ) {
return 1;
}
// Attempt to decrypt the query. If it is not crypted, we may still need
// to serve the certificate.
verbose(VERB_ALGO, "handle request called on DNSCrypt socket");
if ((repinfo->dnsc_cert = dnsc_find_cert(dnscenv, c->buffer)) != NULL) {
if(dnscrypt_server_uncurve(repinfo->dnsc_cert,
repinfo->client_nonce,
repinfo->nmkey,
c->buffer) != 0){
verbose(VERB_ALGO, "dnscrypt: Failed to uncurve");
comm_point_drop_reply(repinfo);
return 0;
}
repinfo->is_dnscrypted = 1;
sldns_buffer_rewind(c->buffer);
}
return 1;
}
int
dnsc_handle_uncurved_request(struct comm_reply *repinfo)
{
if(!repinfo->c->dnscrypt) {
return 1;
}
sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
if(!repinfo->is_dnscrypted) {
return 1;
}
if(dnscrypt_server_curve(repinfo->dnsc_cert,
repinfo->client_nonce,
repinfo->nmkey,
repinfo->c->dnscrypt_buffer,
repinfo->c->type == comm_udp,
repinfo->max_udp_size) != 0){
verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer");
comm_point_drop_reply(repinfo);
return 0;
}
return 1;
}
struct dnsc_env *
dnsc_create(void)
{
struct dnsc_env *env;
if (sodium_init() == -1) {
fatal_exit("dnsc_create: could not initialize libsodium.");
}
env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
return env;
}
int
dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
{
if(dnsc_parse_certs(env, cfg) <= 0) {
fatal_exit("dnsc_apply_cfg: no cert file loaded");
}
if(dnsc_parse_keys(env, cfg) <= 0) {
fatal_exit("dnsc_apply_cfg: no key file loaded");
}
randombytes_buf(env->hash_key, sizeof env->hash_key);
env->provider_name = cfg->dnscrypt_provider;
if(dnsc_load_local_data(env, cfg) <= 0) {
fatal_exit("dnsc_apply_cfg: could not load local data");
}
return 0;
}
-109
View File
@@ -1,109 +0,0 @@
#ifndef UNBOUND_DNSCRYPT_H
#define UNBOUND_DNSCRYPT_H
/**
* \file
* dnscrypt functions for encrypting DNS packets.
*/
#include "dnscrypt/dnscrypt_config.h"
#ifdef USE_DNSCRYPT
#define DNSCRYPT_MAGIC_HEADER_LEN 8U
#define DNSCRYPT_MAGIC_RESPONSE "r6fnvWj8"
#ifndef DNSCRYPT_MAX_PADDING
# define DNSCRYPT_MAX_PADDING 256U
#endif
#ifndef DNSCRYPT_BLOCK_SIZE
# define DNSCRYPT_BLOCK_SIZE 64U
#endif
#ifndef DNSCRYPT_MIN_PAD_LEN
# define DNSCRYPT_MIN_PAD_LEN 8U
#endif
#define crypto_box_HALF_NONCEBYTES (crypto_box_NONCEBYTES / 2U)
#include "config.h"
#include "dnscrypt/cert.h"
#define DNSCRYPT_QUERY_HEADER_SIZE \
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + crypto_box_MACBYTES)
#define DNSCRYPT_RESPONSE_HEADER_SIZE \
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_NONCEBYTES + crypto_box_MACBYTES)
#define DNSCRYPT_REPLY_HEADER_SIZE \
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES * 2 + crypto_box_MACBYTES)
struct sldns_buffer;
struct config_file;
struct comm_reply;
typedef struct KeyPair_ {
uint8_t crypt_publickey[crypto_box_PUBLICKEYBYTES];
uint8_t crypt_secretkey[crypto_box_SECRETKEYBYTES];
} KeyPair;
typedef struct cert_ {
uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
uint8_t es_version[2];
KeyPair *keypair;
} dnsccert;
struct dnsc_env {
struct SignedCert *signed_certs;
dnsccert *certs;
size_t signed_certs_count;
uint8_t provider_publickey[crypto_sign_ed25519_PUBLICKEYBYTES];
uint8_t provider_secretkey[crypto_sign_ed25519_SECRETKEYBYTES];
KeyPair *keypairs;
size_t keypairs_count;
uint64_t nonce_ts_last;
unsigned char hash_key[crypto_shorthash_KEYBYTES];
char * provider_name;
};
struct dnscrypt_query_header {
uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
uint8_t publickey[crypto_box_PUBLICKEYBYTES];
uint8_t nonce[crypto_box_HALF_NONCEBYTES];
uint8_t mac[crypto_box_MACBYTES];
};
/**
* Initialize DNSCrypt enviroment.
* Initialize sodium library and allocate the dnsc_env structure.
* \return an uninitialized struct dnsc_env.
*/
struct dnsc_env * dnsc_create(void);
/**
* Apply configuration.
* Read certificates and secret keys from configuration. Initialize hashkey and
* provider name as well as loading cert TXT records.
* In case of issue applying configuration, this function fatals.
* \param[in] env the struct dnsc_env to populate.
* \param[in] cfg the config_file struct with dnscrypt options.
* \return 0 on success.
*/
int dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg);
/**
* handle a crypted dnscrypt request.
* Determine wether or not a query is coming over the dnscrypt listener and
* attempt to uncurve it or detect if it is a certificate query.
* return 0 in case of failure.
*/
int dnsc_handle_curved_request(struct dnsc_env* dnscenv,
struct comm_reply* repinfo);
/**
* handle an unencrypted dnscrypt request.
* Determine wether or not a query is going over the dnscrypt channel and
* attempt to curve it unless it was not crypted like when it is a
* certificate query.
* \return 0 in case of failure.
*/
int dnsc_handle_uncurved_request(struct comm_reply *repinfo);
#endif /* USE_DNSCRYPT */
#endif
-36
View File
@@ -1,36 +0,0 @@
# dnscrypt.m4
# dnsc_DNSCRYPT([action-if-true], [action-if-false])
# --------------------------------------------------------------------------
# Check for required dnscrypt libraries and add dnscrypt configure args.
AC_DEFUN([dnsc_DNSCRYPT],
[
AC_ARG_ENABLE([dnscrypt],
AS_HELP_STRING([--enable-dnscrypt],
[Enable dnscrypt support (requires libsodium)]),
[opt_dnscrypt=$enableval], [opt_dnscrypt=no])
if test "x$opt_dnscrypt" != "xno"; then
AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path],
[Path where libsodium is installed, for dnscrypt]), [
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
])
AC_SEARCH_LIBS([sodium_init], [sodium], [],
AC_MSG_ERROR([The sodium library was not found. Please install sodium!]))
AC_SEARCH_LIBS([crypto_box_curve25519xchacha20poly1305_beforenm], [sodium],
[
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [1])
AC_DEFINE(
[USE_DNSCRYPT_XCHACHA20], [1],
[Define to 1 to enable dnscrypt with xchacha20 support])
],
[
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0])
])
$1
else
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0])
$2
fi
])
-17
View File
@@ -1,17 +0,0 @@
#ifndef UNBOUND_DNSCRYPT_CONFIG_H
#define UNBOUND_DNSCRYPT_CONFIG_H
/*
* Process this file (dnscrypt_config.h.in) with AC_CONFIG_FILES to generate
* dnscrypt_config.h.
*
* This file exists so that USE_DNSCRYPT can be used without including config.h.
*/
#if @ENABLE_DNSCRYPT@ /* ENABLE_DNSCRYPT */
# ifndef USE_DNSCRYPT
# define USE_DNSCRYPT 1
# endif
#endif
#endif /* UNBOUND_DNSCRYPT_CONFIG_H */
+1 -8
View File
@@ -121,9 +121,7 @@ dt_msg_init(const struct dt_env *env,
struct dt_env *
dt_create(const char *socket_path, unsigned num_workers)
{
#ifdef UNBOUND_DEBUG
fstrm_res res;
#endif
struct dt_env *env;
struct fstrm_iothr_options *fopt;
struct fstrm_unix_writer_options *fuwopt;
@@ -140,12 +138,7 @@ dt_create(const char *socket_path, unsigned num_workers)
return NULL;
fwopt = fstrm_writer_options_init();
#ifdef UNBOUND_DEBUG
res =
#else
(void)
#endif
fstrm_writer_options_add_content_type(fwopt,
res = fstrm_writer_options_add_content_type(fwopt,
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
log_assert(res == fstrm_res_success);
Binary file not shown.
-472
View File
@@ -1,477 +1,5 @@
22 June 2017: Wouter
- Tag 1.6.4rc2
22 June 2017: Ralph
- Added fastrpz patch to contrib
21 June 2017: Wouter
- Fix #1316: heap read buffer overflow in parse_edns_options.
20 June 2017: Wouter
- Fix warning in pythonmod under clang compiler.
- Tag 1.6.4rc1
- Fix lintian typo.
16 June 2017: Ralph
- Fix #1277: disable domain ratelimit by setting value to 0.
16 June 2017: Wouter
- Fix #1301: memory leak in respip and tests.
- Free callback in edns-subnetmod on exit and restart.
- Fix memory leak in sldns_buffer_new_frm_data.
- Fix memory leak in dnscrypt config read.
- Fix dnscrypt chacha cert support ifdefs.
- Fix dnscrypt chacha cert unit test escapes in grep.
- Remove asynclook tests that cause test and purifier problems.
- Fix to unlock view in view test.
15 June 2017: Wouter
- Fix stub zone queries leaking to the internet for
harden-referral-path ns checks.
- Fix query for refetch_glue of stub leaking to internet.
13 June 2017: Wouter
- Fix #1279: Memory leak on reload when python module is enabled.
- Fix #1280: Unbound fails assert when response from authoritative
contains malformed qname. When 0x20 caps-for-id is enabled, when
assertions are not enabled the malformed qname is handled correctly.
- 1.6.3 tag created, with only #1280 fix, trunk is 1.6.4 development.
- More fixes in depth for buffer checks in 0x20 qname checks.
12 June 2017: Wouter
- Fix #1278: Incomplete wildcard proof.
8 June 2017: Ralph
- Added domain name based ECS whitelist.
8 June 2017: Wouter
- Detect chacha for dnscrypt at configure time.
- dnscrypt unit tests with chacha.
7 June 2017: Wouter
- Fix that unbound-control can set val_clean_additional and val_permissive_mode.
- Add dnscrypt XChaCha20 tests.
6 June 2017: Wouter
- Add an explicit type cast for TCP FASTOPEN fix.
- renumbering B-Root's IPv6 address to 2001:500:200::b.
- Fix #1275: cached data in cachedb is never used.
- Fix #1276: [dnscrypt] add XChaCha20-Poly1305 cipher.
1 June 2017: Ralph
- Fix #1274: automatically trim chroot path from dnscrypt key/cert paths
(from Manu Bretelle).
1 June 2017: Wouter
- Fix fastopen EPIPE fallthrough to perform connect.
31 May 2017: Ralph
- Also use global local-zones when there is a matching view that does
not have any local-zone specified.
31 May 2017: Wouter
- Fix #1273: cachedb.c doesn't compile with -Wextra.
- If MSG_FASTOPEN gives EPIPE fallthrough to try normal tcp write.
30 May 2017: Ralph
- Fix #1269: inconsistent use of built-in local zones with views.
- Add defaults for new local-zone trees added to views using
unbound-control.
30 May 2017: Wouter
- Support for openssl EVP_DigestVerify.
- Support for the ED25519 algorithm with openssl (from openssl 1.1.1).
29 May 2017: Wouter
- Fix assertion for low buffer size and big edns payload when worker
overrides udpsize.
26 May 2017: Ralph
- Added redirect-bogus.patch to contrib directory.
26 May 2017: Wouter
- Fix #1270: unitauth.c doesn't compile with higher warning level
and optimization
- exec_prefix is by default equal to prefix.
- printout localzone for duplicate local-zone warnings.
24 May 2017: Wouter
- authzone cname chain, no rrset duplicates, wildcard doesn't change
rrsets added for cname chain.
23 May 2017: Wouter
- first services/authzone check in, it compiles and reads and writes
zonefiles.
- iana portlist update
22 May 2017: Wouter
- Fix #1268: SIGSEGV after log_reopen.
18 May 2017: Wouter
- Fix #1265 to use /bin/kill.
- Fix #1267: Libunbound validator/val_secalgo.c uses obsolete APIs,
and compatibility with BoringSSL.
17 May 2017: Wouter
- Fix #1265: contrib/unbound.service contains hardcoded path.
17 May 2017: George
- Use qstate's region for IPSECKEY rrset (ipsecmod).
16 May 2017: George
- Implemented opportunistic IPsec support module (ipsecmod).
- Some whitespace fixup.
16 May 2017: Wouter
- updated dependencies in the makefile.
- document trust-anchor-signaling in example config file.
- updated configure, dependencies and flex output.
- better module memory lookup, fix of unbound-control shm names for
module memory printout of statistics.
- Fix type AVC sldns rrdef.
12 May 2017: Wouter
- Adjust servfail by iterator to not store in cache when serve-expired
is enabled, to avoid overwriting useful information there.
- Fix queries for nameservers under a stub leaking to the internet.
9 May 2017: Ralph
- Add 'c' to getopt() in testbound.
- iana portlist update
8 May 2017: Wouter
- Fix tcp-mss failure printout text.
- Set SO_REUSEADDR on outgoing tcp connections to fix the bind before
connect limited tcp connections. With the option tcp connections
can share the same source port (for different destinations).
2 May 2017: Ralph
- Added mesh_add_sub to add detached mesh entries.
- Use mesh_add_sub for key tag signaling query.
2 May 2017: Wouter
- Added test for leak of stub information.
- Fix sldns wire2str printout of RR type CAA tags.
- Fix sldns int16_data parse.
- Fix sldns parse and printout of TSIG RRs.
- sldns SMIMEA and AVC definitions, same as getdns definitions.
1 May 2017: Wouter
- Fix #1259: "--disable-ecdsa" argument overwritten
by "#ifdef SHA256_DIGEST_LENGTH@daemon/remote.c".
- iana portlist update
- Fix #1258: Windows 10 X64 unbound 1.6.2 service will not start.
and fix that 64bit getting installed in C:\Program Files (x86).
26 April 2017: Ralph
- Implemented trust anchor signaling using key tag query.
26 April 2017: Wouter
- Based on #1257: check parse limit before t increment in sldns RR
string parse routine.
24 April 2017: Wouter
- unbound-checkconf -o allows query of dnstap config variables.
Also unbound-control get_option. Also for dnscrypt.
- trunk contains 1.6.3 version number (changes from 1.6.2 back from
when the 1.6.2rc1 tag has been created).
21 April 2017: Ralph
- Fix #1254: clarify ratelimit-{for,below}-domain (from Manu Bretelle).
- iana portlist update
18 April 2017: Ralph
- Fix #1252: more indentation inconsistencies.
- Fix #1253: unused variable in edns-subnet/addrtree.c:getbit().
13 April 2017: Ralph
- Added ECS unit test (from Manu Bretelle).
- ECS documentation fix (from Manu Bretelle).
13 April 2017: Wouter
- Fix #1250: inconsistent indentation in services/listen_dnsport.c.
- tag for 1.6.2rc1
- (for 1.6.3:) unbound.h exports the shm stats structures. They use
type long long and no ifdefs, and ub_ before the typenames.
12 April 2017: Wouter
- subnet mem value is available in shm, also when not enabled,
to make the struct easier to memmap by other applications,
independent of the configuration of unbound.
12 April 2017: Ralph
- Fix #1247: unbound does not shorten source prefix length when
forwarding ECS.
- Properly check for allocation failure in local_data_find_tag_datas.
- Fix #1249: unbound doesn't return FORMERR to bogus ECS.
- Set SHM ECS memory usage to 0 when module not loaded.
11 April 2017: Ralph
- Display ECS module memory usage.
10 April 2017: Wouter
- harden-algo-downgrade: no also makes unbound more lenient about
digest algorithms in DS records.
10 April 2017: Ralph
- Remove ECS option after REFUSED answer.
- Fix small memory leak in edns_opt_copy_alloc.
- Respip dereference after NULL check.
- Zero initialize addrtree allocation.
- Use correct identifier for SHM destroy.
7 April 2017: George
- Fix pythonmod for cb changes.
- Some whitespace fixup.
7 April 2017: Ralph
- Unlock view in respip unit test
6 April 2017: Ralph
- Generalise inplace callback (de)registration
- (de)register inplace callbacks for module id
- No unbound-control set_option for ECS options
- Deprecated client-subnet-opcode config option
- Introduced client-subnet-always-forward config option
- Changed max-client-subnet-ipv6 default to 56 (as in RFC)
- Removed extern ECS config options
- module_restart_next now calls clear on all following modules
- Also create ECS module qstate on module_event_pass event
- remove malloc from inplace_cb_register
6 April 2017: Wouter
- Small fixup for documentation.
- iana portlist update
- Fix respip for braces when locks arent used.
- Fix pythonmod for cb changes.
4 April 2017: Wouter
- Fix #1244: document that use of chroot requires trust anchor file to
be under chroot.
- iana portlist update
3 April 2017: Ralph
- Do not add current time twice to TTL before ECS cache store.
- Do not touch rrset cache after ECS cache message generation.
- Use LDNS_EDNS_CLIENT_SUBNET as default ECS opcode.
3 April 2017: Wouter
- Fix #1217: Add metrics to unbound-control interface showing
crypted, cert request, plaintext and malformed queries (from
Manu Bretelle).
- iana portlist update
27 March 2017: Wouter
- Remove (now unused) event2 include from dnscrypt code.
24 March 2017: George
- Fix to prevent non-referal query from being cached as referal when the
no_cache_store flag was set.
23 March 2017: Wouter
- Fix #1239: configure fails to find python distutils if python
prints warning.
22 March 2017: Wouter
- Fix #1238: segmentation fault when adding through the remote
interface a per-view local zone to a view with no previous
(configured) local zones.
- Fix #1229: Systemd service sandboxing, options in wrong sections.
21 March 2017: Ralph
- Merge EDNS Client subnet implementation from feature branch into main
branch, using new EDNS processing framework.
21 March 2017: Wouter
- Fix doxygen for dnscrypt files.
20 March 2017: Wouter
- #1217. DNSCrypt support, with --enable-dnscrypt, libsodium and then
enabled in the config file from Manu Bretelle.
- make depend, autoconf, remove warnings about statement before var.
- lru_demote and lruhash_insert_or_retrieve functions for getdns.
- fixup for lruhash (whitespace and header file comment).
- dnscrypt tests.
17 March 2017: Wouter
- Patch for view functionality for local-data-ptr from Björn Ketelaars.
- Fix #1237 - Wrong resolving in chain, for norec queries that get
SERVFAIL returned.
16 March 2017: Wouter
- Fix that SHM is not inited if not enabled.
- Add trustanchor.unbound CH TXT that gets a response with a number
of TXT RRs with a string like "example.com. 2345 1234" with
the trust anchors and their keytags.
- Fix that looped DNAMEs do not cause unbound to spend effort.
- trustanchor tags are sorted. reusable routine to fetch taglist.
13 March 2017: Wouter
- testbound understands Deckard MATCH rcode question answer commands.
- Fix #1235: Fix too long DNAME expansion produces SERVFAIL instead
of YXDOMAIN + query loop, reported by Petr Spacek.
10 March 2017: Wouter
- Fix #1234: shortening DNAME loop produces duplicate DNAME records
in ANSWER section.
9 March 2017: Wouter
- --disable-sha1 disables SHA1 support in RRSIG, so from DNSKEY and
DS records. NSEC3 is not disabled.
- fake-sha1 test option; print warning if used. To make unit tests.
- unbound-control list local zone and data commands listed in the
help output.
8 March 2017: Wouter
- make depend for build dependencies.
- swig version 2.0.1 required.
- fix enum conversion warnings
7 March 2017: Wouter
- Fix #1230: swig version 2.0.0 is required for pythonmod, with
1.3.40 it crashes when running repeatly unbound-control reload.
- Response actions based on IP address from Jinmei Tatuya (Infoblox).
6 March 2017: Wouter
- Fix #1229: Systemd service sandboxing in contrib/unbound.service.
- iana portlist update
28 February 2017: Ralph
- Fix testpkts.c, check if DO bit is set, not only if there is an OPT
record.
28 February 2017: Wouter
- For #1227: if we have sha256, set the cipher list to have no
known vulns.
27 February 2017: Wouter
- Fix #1227: Fix that Unbound control allows weak ciphersuits.
- Fix #1226: provide official 32bit binary for windows.
24 February 2017: Wouter
- include sys/time.h for new shm code on NetBSD.
23 February 2017: Wouter
- Fix doc/CNAME-basedRedirectionDesignNotes.pdf zone static to
redirect.
- Patch from Luiz Fernando Softov for Stats Shared Memory.
- unbound-control stats_shm command prints stats using shared memory,
which uses less cpu.
- make depend, autoconf, doxygen and lint fixed up.
22 February 2017: Wouter
- Fix #1224: Fix that defaults should not fall back to "Program Files
(x86) if Unbound is 64bit by default on windows.
21 February 2017: Wouter
- iana portlist update
16 February 2017: Wouter
- sldns updated for vfixed and buffer resize indication from getdns.
15 February 2017: Wouter
- sldns has ED25519 and ED448 algorithm number and name for display.
14 February 2017: Wouter
- tag 1.6.1rc3. -- which became 1.6.1 on 21feb, trunk has 1.6.2
13 February 2017: Wouter
- Fix autoconf of systemd check for lack of pkg-config.
10 February 2017: Wouter
- Fix pythonmod for typedef changes.
- Fix dnstap for warning of set but not used.
- tag 1.6.1rc2.
9 February 2017: Wouter
- tag 1.6.1rc1.
8 February 2017: Wouter
- Fix for type name change and fix warning on windows compile.
7 February 2017: Wouter
- Include root trust anchor id 20326 in unbound-anchor.
6 February 2017: Wouter
- Fix compile on solaris of the fix to use $host detect.
4 February 2017: Wouter
- fix root_anchor test for updated icannbundle.pem lower certificates.
26 January 2017: Wouter
- Fix 1211: Fix can't enable interface-automatic if no IPv6 with
more helpful error message.
20 January 2017: Wouter
- Increase MAX_MODULE to 16.
19 January 2017: Wouter
- Fix to Rename ub_callback_t to ub_callback_type, because POSIX
reserves _t typedefs.
- Fix to rename internally used types from _t to _type, because _t
type names are reserved by POSIX.
- iana portlist update
12 January 2017: Wouter
- Fix to also block meta types 128 through to 248 with formerr.
- Fix #1206: Some view-related commands are missing from 'unbound-control -h'
9 January 2017: Wouter
- Fix #1202: Fix code comment that packed_rrset_data is not always
'packed'.
6 January 2017: Wouter
- Fix #1201: Fix missing unlock in answer_from_cache error condition.
5 January 2017: Wouter
- Fix to return formerr for queries for meta-types, to avoid
packet amplification if this meta-type is sent on to upstream.
- Fix #1184: Log DNS replies. This includes the same logging
information that DNS queries and response code and response size,
patch from Larissa Feng.
- Fix #1187: Source IP rate limiting, patch from Larissa Feng.
3 January 2017: Wouter
- configure --enable-systemd and lets unbound use systemd sockets if
you enable use-systemd: yes in unbound.conf.
Also there are contrib/unbound.socket and contrib/unbound.service:
systemd files for unbound, install them in /usr/lib/systemd/system.
Contributed by Sami Kerola and Pavel Odintsov.
- Fix reload chdir failure when also chrooted to that directory.
2 January 2017: Wouter
- Fix #1194: Cross build fails when $host isn't `uname` for getentropy.
23 December 2016: Ralph
- Fix #1190: Do not echo back EDNS options in local-zone error response.
- iana portlist update
21 December 2016: Ralph
- Fix #1188: Unresolved symbol 'fake_dsa' in libunbound.so when built
with Nettle
19 December 2016: Ralph
- Fix #1191: remove comment about view deletion.
15 December 2016: Wouter
- iana portlist update
- 64bit is default for windows builds.
- Fix inet_ntop and inet_pton warnings in windows compile.
14 December 2016: Wouter
- Fix #1178: attempt to fix setup error at end, pop result values
at end of install.
13 December 2016: Wouter
- Fix #1182: Fix Resource leak (socket), at startup.
- Fix unbound-control and ipv6 only.
9 December 2016: Wouter
- Fix #1176: stack size too small for Alpine Linux.
8 December 2016: Wouter
- Fix downcast warnings from visual studio in sldns code.
- tag 1.6.0rc1 which became 1.6.0 on 15 dec, and trunk is 1.6.1.
7 December 2016: Ralph
- Add DSA support for OpenSSL 1.1.0
Binary file not shown.
-85
View File
@@ -19,14 +19,6 @@ server:
# Set to "" or 0 to disable. Default is disabled.
# statistics-interval: 0
# enable shm for stats, default no. if you enable also enable
# statistics-interval, every time it also writes stats to the
# shared memory segment keyed with shm-key.
# shm-enable: no
# shm for stats uses this key, and key+1 for the shared mem segment.
# shm-key: 11777
# enable cumulative statistics, without clearing them after printing.
# statistics-cumulative: no
@@ -208,11 +200,7 @@ server:
# Default is 0, system default MSS.
# outgoing-tcp-mss: 0
# Use systemd socket activation for UDP, TCP, and control sockets.
# use-systemd: no
# Detach from the terminal, run in background, "yes" or "no".
# Set the value to "no" when unbound runs as systemd service.
# do-daemonize: yes
# control which clients are allowed to make (recursive) queries
@@ -300,10 +288,6 @@ server:
# print one line with time, IP, name, type, class for every query.
# log-queries: no
# print one line per reply, with time, IP, name, type, class, rcode,
# timetoresolve, fromcache and responsesize.
# log-replies: no
# the pid file. Can be an absolute path outside of chroot/work dir.
# pidfile: "@UNBOUND_PIDFILE@"
@@ -316,9 +300,6 @@ server:
# enable to not answer version.server and version.bind queries.
# hide-version: no
# enable to not answer trustanchor.unbound queries.
# hide-trustanchor: no
# the identity to report. Leave "" or default to return hostname.
# identity: ""
@@ -448,9 +429,6 @@ server:
# and under the terms of our LICENSE (see that file in the source).
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
# trust anchor signaling sends a RFC8145 key tag query after priming.
# trust-anchor-signaling: no
# 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.
@@ -688,48 +666,6 @@ server:
# can give this multiple times, the name closest to the zone is used.
# ratelimit-below-domain: com 1000
# global query ratelimit for all ip addresses.
# feature is experimental.
# if 0(default) it is disabled, otherwise states qps allowed per ip address
# ip-ratelimit: 0
# ip ratelimits are tracked in a cache, size in bytes of cache (or k,m).
# ip-ratelimit-size: 4m
# ip ratelimit cache slabs, reduces lock contention if equal to cpucount.
# ip-ratelimit-slabs: 4
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
# ip-ratelimit-factor: 10
# Specific options for ipsecmod. unbound needs to be configured with
# --enable-ipsecmod for these to take effect.
#
# Enable or disable ipsecmod (it still needs to be defined in
# module-config above). Can be used when ipsecmod needs to be
# enabled/disabled via remote-control(below).
# ipsecmod-enabled: yes
#
# Path to executable external hook. It must be defined when ipsecmod is
# listed in module-config (above).
# ipsecmod-hook: "./my_executable"
#
# When enabled unbound will reply with SERVFAIL if the return value of
# the ipsecmod-hook is not 0.
# ipsecmod-strict: no
#
# Maximum time to live (TTL) for cached A/AAAA records with IPSECKEY.
# ipsecmod-max-ttl: 3600
#
# Reply with A/AAAA even if the relevant IPSECKEY is bogus. Mainly used for
# testing.
# ipsecmod-ignore-bogus: no
#
# Domains for which ipsecmod will be triggered. If not defined (default)
# all domains are treated as being whitelisted.
# ipsecmod-whitelist: "example.com"
# ipsecmod-whitelist: "nlnetlabs.nl"
# Python config section. To enable:
# o use --with-pythonmodule to configure before compiling.
# o list python in the module-config string (above) to enable.
@@ -813,28 +749,7 @@ remote-control:
# 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"
# view-first: no
# view:
# name: "anotherview"
# local-zone: "example.com" refuse
# DNSCrypt
# Caveats:
# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper
# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to
# listen on `dnscrypt-port` with the follo0wing snippet:
# server:
# interface: 0.0.0.0@443
# interface: ::0@443
#
# Finally, `dnscrypt` config has its own section.
# dnscrypt:
# dnscrypt-enable: yes
# dnscrypt-port: 443
# dnscrypt-provider: 2.dnscrypt-cert.example.com.
# dnscrypt-secret-key: /path/unbound-conf/keys1/1.key
# dnscrypt-secret-key: /path/unbound-conf/keys2/1.key
# dnscrypt-provider-cert: /path/unbound-conf/keys1/1.cert
# dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert
+2 -2
View File
@@ -12,7 +12,7 @@
.B unbound.h,
.B ub_ctx,
.B ub_result,
.B ub_callback_type,
.B ub_callback_t,
.B ub_ctx_create,
.B ub_ctx_delete,
.B ub_ctx_set_option,
@@ -120,7 +120,7 @@
.br
\fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata,
.br
\fIub_callback_type\fR callback, \fIint*\fR async_id);
\fIub_callback_t\fR callback, \fIint*\fR async_id);
.LP
\fIint\fR
\fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id);
+1 -13
View File
@@ -194,7 +194,7 @@ harden\-referral\-path, prefetch, prefetch\-key, log\-queries,
hide\-identity, hide\-version, identity, version, val\-log\-level,
val\-log\-squelch, ignore\-cd\-flag, add\-holddown, del\-holddown,
keep\-missing, tcp\-upstream, ssl\-upstream, max\-udp\-size, ratelimit,
ip\-ratelimit, cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl.
cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl.
.TP
.B get_option \fIopt
Get the value of the option. Give the option name without a trailing ':'.
@@ -280,12 +280,6 @@ just the ratelimited domains, with their estimated qps. The ratelimited
domains return an error for uncached (new) queries, but cached queries work
as normal.
.TP
.B ip_ratelimit_list \fR[\fI+a\fR]
List the ip addresses that are ratelimited. Printed one per line with current
estimated qps and qps limit from config. With +a it prints all ips, not
just the ratelimited ips, with their estimated qps. The ratelimited
ips are dropped before checking the cache.
.TP
.B view_list_local_zones \fIview\fR
\fIlist_local_zones\fR for given view.
.TP
@@ -295,9 +289,6 @@ ips are dropped before checking the cache.
.B view_local_zone_remove \fIview\fR \fIname
\fIlocal_zone_remove\fR for given view.
.TP
.B view_list_local_data \fIview\fR
\fIlist_local_data\fR for given view.
.TP
.B view_local_data \fIview\fR \fIRR data...
\fIlocal_data\fR for given view.
.TP
@@ -328,9 +319,6 @@ The \fIstats\fR command shows a number of statistic counters.
.I threadX.num.queries
number of queries received by thread
.TP
.I threadX.num.queries_ip_ratelimited
number of queries rate limited by thread
.TP
.I threadX.num.cachehits
number of queries that were successfully answered using a cache lookup
.TP
+168 -379
View File
File diff suppressed because it is too large Load Diff
-532
View File
@@ -1,532 +0,0 @@
/*
* edns-subnet/addrtree.c -- radix tree for edns subnet cache.
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \file
* addrtree -- radix tree for edns subnet cache.
*/
#include "config.h"
#include "util/log.h"
#include "util/data/msgreply.h"
#include "util/module.h"
#include "addrtree.h"
/**
* Create a new edge
* @param node: Child node this edge will connect to.
* @param addr: full key to this edge.
* @param addrlen: length of relevant part of key for this node
* @param parent_node: Parent node for node
* @param parent_index: Index of child node at parent node
* @return new addredge or NULL on failure
*/
static struct addredge *
edge_create(struct addrnode *node, const addrkey_t *addr,
addrlen_t addrlen, struct addrnode *parent_node, int parent_index)
{
size_t n;
struct addredge *edge = (struct addredge *)malloc( sizeof (*edge) );
if (!edge)
return NULL;
edge->node = node;
edge->len = addrlen;
edge->parent_index = parent_index;
edge->parent_node = parent_node;
/* ceil() */
n = (size_t)((addrlen / KEYWIDTH) + ((addrlen % KEYWIDTH != 0)?1:0));
edge->str = (addrkey_t *)calloc(n, sizeof (addrkey_t));
if (!edge->str) {
free(edge);
return NULL;
}
memcpy(edge->str, addr, n * sizeof (addrkey_t));
/* Only manipulate other objects after successful alloc */
node->parent_edge = edge;
log_assert(parent_node->edge[parent_index] == NULL);
parent_node->edge[parent_index] = edge;
return edge;
}
/**
* Create a new node
* @param tree: Tree the node lives in.
* @param elem: Element to store at this node
* @param scope: Scopemask from server reply
* @param ttl: Element is valid up to this time. Absolute, seconds
* @return new addrnode or NULL on failure
*/
static struct addrnode *
node_create(struct addrtree *tree, void *elem, addrlen_t scope,
time_t ttl)
{
struct addrnode* node = (struct addrnode *)malloc( sizeof (*node) );
if (!node)
return NULL;
node->elem = elem;
tree->node_count++;
node->scope = scope;
node->ttl = ttl;
node->edge[0] = NULL;
node->edge[1] = NULL;
node->parent_edge = NULL;
node->next = NULL;
node->prev = NULL;
return node;
}
/** Size in bytes of node and parent edge
* @param tree: tree the node lives in
* @param n: node which size must be calculated
* @return size in bytes.
**/
static inline size_t
node_size(const struct addrtree *tree, const struct addrnode *n)
{
return sizeof *n + sizeof *n->parent_edge + n->parent_edge->len +
(n->elem?tree->sizefunc(n->elem):0);
}
struct addrtree *
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count)
{
struct addrtree *tree;
log_assert(delfunc != NULL);
log_assert(sizefunc != NULL);
tree = (struct addrtree *)calloc(1, sizeof(*tree));
if (!tree)
return NULL;
tree->root = node_create(tree, NULL, 0, 0);
if (!tree->root) {
free(tree);
return NULL;
}
tree->size_bytes = sizeof *tree + sizeof *tree->root;
tree->first = NULL;
tree->last = NULL;
tree->max_depth = max_depth;
tree->delfunc = delfunc;
tree->sizefunc = sizefunc;
tree->env = env;
tree->node_count = 0;
tree->max_node_count = max_node_count;
return tree;
}
/**
* Scrub a node clean of elem
* @param tree: tree the node lives in.
* @param node: node to be cleaned.
*/
static void
clean_node(struct addrtree *tree, struct addrnode *node)
{
if (!node->elem) return;
tree->size_bytes -= tree->sizefunc(node->elem);
tree->delfunc(tree->env, node->elem);
node->elem = NULL;
}
/** Remove specified node from LRU list */
static void
lru_pop(struct addrtree *tree, struct addrnode *node)
{
if (node == tree->first) {
if (!node->next) { /* it is the last as well */
tree->first = NULL;
tree->last = NULL;
} else {
tree->first = node->next;
tree->first->prev = NULL;
}
} else if (node == tree->last) { /* but not the first */
tree->last = node->prev;
tree->last->next = NULL;
} else {
node->prev->next = node->next;
node->next->prev = node->prev;
}
}
/** Add node to LRU list as most recently used. */
static void
lru_push(struct addrtree *tree, struct addrnode *node)
{
if (!tree->first) {
tree->first = node;
node->prev = NULL;
} else {
tree->last->next = node;
node->prev = tree->last;
}
tree->last = node;
node->next = NULL;
}
/** Move node to the end of LRU list */
static void
lru_update(struct addrtree *tree, struct addrnode *node)
{
if (tree->root == node) return;
lru_pop(tree, node);
lru_push(tree, node);
}
/**
* Purge a node from the tree. Node and parentedge are cleaned and
* free'd.
* @param tree: Tree the node lives in.
* @param node: Node to be freed
*/
static void
purge_node(struct addrtree *tree, struct addrnode *node)
{
struct addredge *parent_edge, *child_edge = NULL;
int index;
int keep = node->edge[0] && node->edge[1];
clean_node(tree, node);
parent_edge = node->parent_edge;
if (keep || !parent_edge) return;
tree->node_count--;
index = parent_edge->parent_index;
child_edge = node->edge[!node->edge[0]];
if (child_edge) {
child_edge->parent_node = parent_edge->parent_node;
child_edge->parent_index = index;
}
parent_edge->parent_node->edge[index] = child_edge;
tree->size_bytes -= node_size(tree, node);
free(parent_edge->str);
free(parent_edge);
lru_pop(tree, node);
free(node);
}
/**
* If a limit is set remove old nodes while above that limit.
* @param tree: Tree to be cleaned up.
*/
static void
lru_cleanup(struct addrtree *tree)
{
struct addrnode *n, *p;
int children;
if (tree->max_node_count == 0) return;
while (tree->node_count > tree->max_node_count) {
n = tree->first;
if (!n) break;
children = (n->edge[0] != NULL) + (n->edge[1] != NULL);
/** Don't remove this node, it is either the root or we can't
* do without it because it has 2 children */
if (children == 2 || !n->parent_edge) {
lru_update(tree, n);
continue;
}
p = n->parent_edge->parent_node;
purge_node(tree, n);
/** Since we removed n, n's parent p is eligible for deletion
* if it is not the root node, caries no data and has only 1
* child */
children = (p->edge[0] != NULL) + (p->edge[1] != NULL);
if (!p->elem && children == 1 && p->parent_edge) {
purge_node(tree, p);
}
}
}
inline size_t
addrtree_size(const struct addrtree *tree)
{
return tree?tree->size_bytes:0;
}
void addrtree_delete(struct addrtree *tree)
{
struct addrnode *n;
if (!tree) return;
clean_node(tree, tree->root);
free(tree->root);
tree->size_bytes -= sizeof(struct addrnode);
while ((n = tree->first)) {
tree->first = n->next;
clean_node(tree, n);
tree->size_bytes -= node_size(tree, n);
free(n->parent_edge->str);
free(n->parent_edge);
free(n);
}
log_assert(sizeof *tree == addrtree_size(tree));
free(tree);
}
/**
* Get N'th bit from address
* @param addr: address to inspect
* @param addrlen: length of addr in bits
* @param n: index of bit to test. Must be in range [0, addrlen)
* @return 0 or 1
*/
static int
getbit(const addrkey_t *addr, addrlen_t addrlen, addrlen_t n)
{
log_assert(addrlen > n);
(void)addrlen;
return (int)(addr[n/KEYWIDTH]>>((KEYWIDTH-1)-(n%KEYWIDTH))) & 1;
}
/**
* Test for equality on N'th bit.
* @return 0 for equal, 1 otherwise
*/
static inline int
cmpbit(const addrkey_t *key1, const addrkey_t *key2, addrlen_t n)
{
addrkey_t c = key1[n/KEYWIDTH] ^ key2[n/KEYWIDTH];
return (int)(c >> ((KEYWIDTH-1)-(n%KEYWIDTH))) & 1;
}
/**
* Common number of bits in prefix.
* @param s1: first prefix.
* @param l1: length of s1 in bits.
* @param s2: second prefix.
* @param l2: length of s2 in bits.
* @param skip: nr of bits already checked.
* @return common number of bits.
*/
static addrlen_t
bits_common(const addrkey_t *s1, addrlen_t l1,
const addrkey_t *s2, addrlen_t l2, addrlen_t skip)
{
addrlen_t len, i;
len = (l1 > l2) ? l2 : l1;
log_assert(skip < len);
for (i = skip; i < len; i++) {
if (cmpbit(s1, s2, i)) return i;
}
return len;
}
/**
* Tests if s1 is a substring of s2
* @param s1: first prefix.
* @param l1: length of s1 in bits.
* @param s2: second prefix.
* @param l2: length of s2 in bits.
* @param skip: nr of bits already checked.
* @return 1 for substring, 0 otherwise
*/
static int
issub(const addrkey_t *s1, addrlen_t l1,
const addrkey_t *s2, addrlen_t l2, addrlen_t skip)
{
return bits_common(s1, l1, s2, l2, skip) == l1;
}
void
addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
time_t now)
{
struct addrnode *newnode, *node;
struct addredge *edge;
int index;
addrlen_t common, depth;
node = tree->root;
log_assert(node != NULL);
/* Protect our cache against too much fine-grained data */
if (tree->max_depth < scope) scope = tree->max_depth;
/* Server answer was less specific than question */
if (scope < sourcemask) sourcemask = scope;
depth = 0;
while (1) {
log_assert(depth <= sourcemask);
/* Case 1: update existing node */
if (depth == sourcemask) {
/* update this node's scope and data */
clean_node(tree, node);
node->ttl = ttl;
node->elem = elem;
node->scope = scope;
tree->size_bytes += tree->sizefunc(elem);
return;
}
index = getbit(addr, sourcemask, depth);
/* Get an edge to an unexpired node */
edge = node->edge[index];
while (edge) {
/* Purge all expired nodes on path */
if (!edge->node->elem || edge->node->ttl >= now)
break;
purge_node(tree, edge->node);
edge = node->edge[index];
}
/* Case 2: New leafnode */
if (!edge) {
newnode = node_create(tree, elem, scope, ttl);
if (!newnode) return;
if (!edge_create(newnode, addr, sourcemask, node,
index)) {
clean_node(tree, newnode);
tree->node_count--;
free(newnode);
return;
}
tree->size_bytes += node_size(tree, newnode);
lru_push(tree, newnode);
lru_cleanup(tree);
return;
}
/* Case 3: Traverse edge */
common = bits_common(edge->str, edge->len, addr, sourcemask,
depth);
if (common == edge->len) {
/* We update the scope of intermediate nodes. Apparently
* the * authority changed its mind. If we would not do
* this we might not be able to reach our new node. */
node->scope = scope;
depth = edge->len;
node = edge->node;
continue;
}
/* Case 4: split. */
if (!(newnode = node_create(tree, NULL, 0, 0)))
return;
node->edge[index] = NULL;
if (!edge_create(newnode, addr, common, node, index)) {
node->edge[index] = edge;
clean_node(tree, newnode);
tree->node_count--;
free(newnode);
return;
}
lru_push(tree, newnode);
/* connect existing child to our new node */
index = getbit(edge->str, edge->len, common);
newnode->edge[index] = edge;
edge->parent_node = newnode;
edge->parent_index = (int)index;
if (common == sourcemask) {
/* Data is stored in the node */
newnode->elem = elem;
newnode->scope = scope;
newnode->ttl = ttl;
}
tree->size_bytes += node_size(tree, newnode);
if (common != sourcemask) {
/* Data is stored in other leafnode */
node = newnode;
newnode = node_create(tree, elem, scope, ttl);
if (!edge_create(newnode, addr, sourcemask, node,
index^1)) {
clean_node(tree, newnode);
tree->node_count--;
free(newnode);
return;
}
tree->size_bytes += node_size(tree, newnode);
lru_push(tree, newnode);
}
lru_cleanup(tree);
return;
}
}
struct addrnode *
addrtree_find(struct addrtree *tree, const addrkey_t *addr,
addrlen_t sourcemask, time_t now)
{
struct addrnode *node = tree->root;
struct addredge *edge = NULL;
addrlen_t depth = 0;
log_assert(node != NULL);
while (1) {
/* Current node more specific then question. */
log_assert(depth <= sourcemask);
/* does this node have data? if yes, see if we have a match */
if (node->elem && node->ttl >= now) {
/* saved at wrong depth */;
log_assert(node->scope >= depth)
if (depth == node->scope ||
(node->scope > sourcemask &&
depth == sourcemask)) {
/* Authority indicates it does not have a more
* precise answer or we cannot ask a more
* specific question. */
lru_update(tree, node);
return node;
}
}
/* This is our final depth, but we haven't found an answer. */
if (depth == sourcemask)
return NULL;
/* Find an edge to traverse */
edge = node->edge[getbit(addr, sourcemask, depth)];
if (!edge || !edge->node)
return NULL;
if (edge->len > sourcemask )
return NULL;
if (!issub(edge->str, edge->len, addr, sourcemask, depth))
return NULL;
log_assert(depth < edge->len);
depth = edge->len;
node = edge->node;
}
}
/** Wrappers for static functions to unit test */
int unittest_wrapper_addrtree_cmpbit(const addrkey_t *key1,
const addrkey_t *key2, addrlen_t n) {
return cmpbit(key1, key2, n);
}
addrlen_t unittest_wrapper_addrtree_bits_common(const addrkey_t *s1,
addrlen_t l1, const addrkey_t *s2, addrlen_t l2, addrlen_t skip) {
return bits_common(s1, l1, s2, l2, skip);
}
int unittest_wrapper_addrtree_getbit(const addrkey_t *addr,
addrlen_t addrlen, addrlen_t n) {
return getbit(addr, addrlen, n);
}
int unittest_wrapper_addrtree_issub(const addrkey_t *s1, addrlen_t l1,
const addrkey_t *s2, addrlen_t l2, addrlen_t skip) {
return issub(s1, l1, s2, l2, skip);
}
-187
View File
@@ -1,187 +0,0 @@
/*
* edns-subnet/addrtree.h -- radix tree for edns subnet cache.
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* The addrtree is a radix tree designed for edns subnet. Most notable
* is the addition of 'scope' to a node. Scope is only relevant for
* nodes with elem set, it indicates the number of bits the authority
* desires.
*
* For retrieving data one needs an address and address length
* (sourcemask). While traversing the tree the first matching node is
* returned. A node matches when
* node.scope<=sourcemask && node.elem!=NULL
* (This is the most specific answer the authority has.)
* or
* node.sourcemask==sourcemask && node.elem!=NULL
* (This is the most specific question the client can ask.)
*
* Insertion needs an address, sourcemask and scope. The length of the
* address is capped by min(sourcemask, scope). While traversing the
* tree the scope of all visited nodes is updated. This ensures we are
* always able to find the most specific answer available.
*/
#ifndef ADDRTREE_H
#define ADDRTREE_H
typedef uint8_t addrlen_t;
typedef uint8_t addrkey_t;
#define KEYWIDTH 8
struct addrtree {
struct addrnode *root;
/** Number of elements in the tree (not always equal to number of
* nodes) */
unsigned int node_count;
/** Maximum number of allowed nodes, will be enforced by LRU list.
* Excluding the root node, 0 for unlimited */
unsigned int max_node_count;
/** Size of tree in bytes */
size_t size_bytes;
/** Maximum prefix length we are willing to cache. */
addrlen_t max_depth;
/** External function to delete elem. Called as
* delfunc(addrnode->elem, addrtree->env) */
void (*delfunc)(void *, void *);
/** Environment for delfunc */
void *env;
/** External function returning size of elem. Called as
* sizefunc(addrnode->elem) */
size_t (*sizefunc)(void *);
/** first node in LRU list, first candidate to go */
struct addrnode* first;
/** last node in LRU list, last candidate to go */
struct addrnode *last;
};
struct addrnode {
/** Payload of node, may be NULL */
void *elem;
/** Abs time in seconds in which elem is meaningful */
time_t ttl;
/** Number of significant bits in address. */
addrlen_t scope;
/** A node can have 0-2 edges, set to NULL for unused */
struct addredge *edge[2];
/** edge between this node and parent */
struct addredge *parent_edge;
/** previous node in LRU list */
struct addrnode *prev;
/** next node in LRU list */
struct addrnode *next;
};
struct addredge {
/** address of connected node */
addrkey_t *str;
/** lenght in bits of str */
addrlen_t len;
/** child node this edge is connected to */
struct addrnode *node;
/** Parent node this ege is connected to */
struct addrnode *parent_node;
/** Index of this edge in parent_node */
int parent_index;
};
/**
* Size of tree in bytes.
* @param tree: Tree.
* @return size of tree in bytes.
*/
size_t addrtree_size(const struct addrtree *tree);
/**
* Create a new tree.
* @param max_depth: Tree will cap keys to this length.
* @param delfunc: f(element, env) delete element.
* @param sizefunc: f(element) returning the size of element.
* @param env: Module environment for alloc information.
* @param max_node_count: Maximum size of this data structure in nodes.
* 0 for unlimited.
* @return new addrtree or NULL on failure.
*/
struct addrtree *
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count);
/**
* Free tree and all nodes below.
* @param tree: Tree to be freed.
*/
void addrtree_delete(struct addrtree *tree);
/**
* Insert an element in the tree. Failures are silent. Sourcemask and
* scope might be changed according to local policy. Caller should no
* longer access elem, it could be free'd now or later during future
* inserts.
*
* @param tree: Tree insert elem in.
* @param addr: key for element lookup.
* @param sourcemask: Length of addr in bits.
* @param scope: Number of significant bits in addr.
* @param elem: data to store in the tree.
* @param ttl: elem is valid up to this time, seconds.
* @param now: Current time in seconds.
*/
void addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
time_t now);
/**
* Find a node containing an element in the tree.
*
* @param tree: Tree to search.
* @param addr: key for element lookup.
* @param sourcemask: Length of addr in bits.
* @param now: Current time in seconds.
* @return addrnode or NULL on miss.
*/
struct addrnode * addrtree_find(struct addrtree *tree,
const addrkey_t *addr, addrlen_t sourcemask, time_t now);
/** Wrappers for static functions to unit test */
int unittest_wrapper_addrtree_cmpbit(const addrkey_t *key1,
const addrkey_t *key2, addrlen_t n);
addrlen_t unittest_wrapper_addrtree_bits_common(const addrkey_t *s1,
addrlen_t l1, const addrkey_t *s2, addrlen_t l2, addrlen_t skip);
int unittest_wrapper_addrtree_getbit(const addrkey_t *addr,
addrlen_t addrlen, addrlen_t n);
int unittest_wrapper_addrtree_issub(const addrkey_t *s1, addrlen_t l1,
const addrkey_t *s2, addrlen_t l2, addrlen_t skip);
#endif /* ADDRTREE_H */
-65
View File
@@ -1,65 +0,0 @@
/*
* edns-subnet/edns-subnet.c - Subnet option related constants
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Subnet option related constants.
*/
#include "config.h"
#ifdef CLIENT_SUBNET /* keeps splint happy */
#include "edns-subnet/edns-subnet.h"
#include <string.h>
int
copy_clear(uint8_t* dst, size_t dstlen, uint8_t* src, size_t srclen, size_t n)
{
size_t intpart = n / 8; /* bytes */
size_t fracpart = n % 8; /* bits */
size_t written = intpart;
if (intpart > dstlen || intpart > srclen)
return 1;
if (fracpart && (intpart+1 > dstlen || intpart+1 > srclen))
return 1;
memcpy(dst, src, intpart);
if (fracpart) {
dst[intpart] = src[intpart] & ~(0xFF >> fracpart);
written++;
}
memset(dst + written, 0, dstlen - written);
return 0;
}
#endif /* CLIENT_SUBNET */
-67
View File
@@ -1,67 +0,0 @@
/*
* edns-subnet/edns-subnet.h - Subnet option related constants
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Subnet option related constants.
*/
#include "util/net_help.h"
#ifndef EDNSSUBNET_EDNSSUBNET_H
#define EDNSSUBNET_EDNSSUBNET_H
/** In use by the edns subnet option code, as assigned by IANA */
#define EDNSSUBNET_ADDRFAM_IP4 1
#define EDNSSUBNET_ADDRFAM_IP6 2
/**
* ECS option
*/
struct ecs_data {
uint16_t subnet_addr_fam;
uint8_t subnet_source_mask;
uint8_t subnet_scope_mask;
uint8_t subnet_addr[INET6_SIZE];
int subnet_validdata;
};
/**
* copy the first n BITS from src to dst iff both src and dst
* are large enough, return 0 on succes
*/
int
copy_clear(uint8_t* dst, size_t dstlen, uint8_t* src, size_t srclen, size_t n);
#endif /* EDNSSUBNET_EDNSSUBNET_H */
-207
View File
@@ -1,207 +0,0 @@
/*
* edns-subnet/subnet-whitelist.c - Hosts we actively try to send subnet option
* to.
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* Keep track of the white listed servers for subnet option. Based
* on acl_list.c|h
*/
#include "config.h"
#ifdef CLIENT_SUBNET /* keeps splint happy */
#include "edns-subnet/edns-subnet.h"
#include "edns-subnet/subnet-whitelist.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/storage/dnstree.h"
#include "sldns/str2wire.h"
#include "util/data/dname.h"
struct ecs_whitelist*
ecs_whitelist_create(void)
{
struct ecs_whitelist* whitelist =
(struct ecs_whitelist*)calloc(1,
sizeof(struct ecs_whitelist));
if(!whitelist)
return NULL;
whitelist->region = regional_create();
if(!whitelist->region) {
ecs_whitelist_delete(whitelist);
return NULL;
}
return whitelist;
}
void
ecs_whitelist_delete(struct ecs_whitelist* whitelist)
{
if(!whitelist)
return;
regional_destroy(whitelist->region);
free(whitelist);
}
/** insert new address into whitelist structure */
static int
upstream_insert(struct ecs_whitelist* whitelist,
struct sockaddr_storage* addr, socklen_t addrlen, int net)
{
struct addr_tree_node* node = (struct addr_tree_node*)regional_alloc(
whitelist->region, sizeof(*node));
if(!node)
return 0;
if(!addr_tree_insert(&whitelist->upstream, node, addr, addrlen, net)) {
verbose(VERB_QUERY,
"duplicate send-client-subnet address ignored.");
}
return 1;
}
/** apply edns-subnet string */
static int
upstream_str_cfg(struct ecs_whitelist* whitelist, const char* str)
{
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
verbose(VERB_ALGO, "send-client-subnet: %s", str);
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse send-client-subnet netblock: %s", str);
return 0;
}
if(!upstream_insert(whitelist, &addr, addrlen, net)) {
log_err("out of memory");
return 0;
}
return 1;
}
/** read client_subnet config */
static int
read_upstream(struct ecs_whitelist* whitelist, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->client_subnet; p; p = p->next) {
log_assert(p->str);
if(!upstream_str_cfg(whitelist, p->str))
return 0;
}
return 1;
}
/** read client_subnet_zone config */
static int
read_names(struct ecs_whitelist* whitelist, struct config_file* cfg)
{
/* parse names, report errors, insert into tree */
struct config_strlist* p;
struct name_tree_node* n;
uint8_t* nm, *nmr;
size_t nm_len;
int nm_labs;
for(p = cfg->client_subnet_zone; p; p = p->next) {
log_assert(p->str);
nm = sldns_str2wire_dname(p->str, &nm_len);
if(!nm) {
log_err("cannot parse client-subnet-zone: %s", p->str);
return 0;
}
nm_labs = dname_count_size_labels(nm, &nm_len);
nmr = (uint8_t*)regional_alloc_init(whitelist->region, nm,
nm_len);
free(nm);
if(!nmr) {
log_err("out of memory");
return 0;
}
n = (struct name_tree_node*)regional_alloc(whitelist->region,
sizeof(*n));
if(!n) {
log_err("out of memory");
return 0;
}
if(!name_tree_insert(&whitelist->dname, n, nmr, nm_len, nm_labs,
LDNS_RR_CLASS_IN)) {
verbose(VERB_QUERY, "ignoring duplicate "
"client-subnet-zone: %s", p->str);
}
}
return 1;
}
int
ecs_whitelist_apply_cfg(struct ecs_whitelist* whitelist,
struct config_file* cfg)
{
regional_free_all(whitelist->region);
addr_tree_init(&whitelist->upstream);
name_tree_init(&whitelist->dname);
if(!read_upstream(whitelist, cfg))
return 0;
if(!read_names(whitelist, cfg))
return 0;
addr_tree_init_parents(&whitelist->upstream);
name_tree_init_parents(&whitelist->dname);
return 1;
}
int
ecs_is_whitelisted(struct ecs_whitelist* whitelist,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* qname,
size_t qname_len, uint16_t qclass)
{
int labs;
if(addr_tree_lookup(&whitelist->upstream, addr, addrlen))
return 1;
/* Not in upstream whitelist, check dname whitelist. */
labs = dname_count_labels(qname);
return name_tree_lookup(&whitelist->dname, qname, qname_len, labs,
qclass) != NULL;
}
size_t
ecs_whitelist_get_mem(struct ecs_whitelist* whitelist)
{
if(!whitelist) return 0;
return sizeof(*whitelist) + regional_get_mem(whitelist->region);
}
#endif /* CLIENT_SUBNET */
-111
View File
@@ -1,111 +0,0 @@
/*
* edns-subnet/subnet-whitelist.h - Hosts we actively try to send subnet option
* to.
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* Keep track of the white listed servers and domain names for subnet option.
* Based on acl_list.c|h
*/
#ifndef EDNSSUBNET_WHITELIST_H
#define EDNSSUBNET_WHITELIST_H
#include "util/storage/dnstree.h"
struct config_file;
struct regional;
/**
* ecs_whitelist structure
*/
struct ecs_whitelist {
/** regional for allocation */
struct regional* region;
/**
* Tree of the address spans that are whitelisted.
* contents of type addr_tree_node. Each node is an address span
* Unbound will append subnet option for.
*/
rbtree_type upstream;
/**
* Tree of domain names for which Unbound will append an ECS option.
* rbtree of struct name_tree_node.
*/
rbtree_type dname;
};
/**
* Create ecs_whitelist structure
* @return new structure or NULL on error.
*/
struct ecs_whitelist* ecs_whitelist_create(void);
/**
* Delete ecs_whitelist structure.
* @param whitelist: to delete.
*/
void ecs_whitelist_delete(struct ecs_whitelist* whitelist);
/**
* Process ecs_whitelist config.
* @param whitelist: where to store.
* @param cfg: config options.
* @return 0 on error.
*/
int ecs_whitelist_apply_cfg(struct ecs_whitelist* whitelist,
struct config_file* cfg);
/**
* See if an address or domain is whitelisted.
* @param whitelist: structure for address storage.
* @param addr: address to check
* @param addrlen: length of addr.
* @param qname: dname in query
* @param qname_len: length of dname
* @param qclass: class in query
* @return: true if the address is whitelisted for subnet option.
*/
int ecs_is_whitelisted(struct ecs_whitelist* whitelist,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* qname,
size_t qname_len, uint16_t qclass);
/**
* Get memory used by ecs_whitelist structure.
* @param whitelist: structure for address storage.
* @return bytes in use.
*/
size_t ecs_whitelist_get_mem(struct ecs_whitelist* whitelist);
#endif /* EDNSSUBNET_WHITELIST_H */
-810
View File
@@ -1,810 +0,0 @@
/*
* edns-subnet/subnetmod.c - edns subnet module. Must be called before validator
* and iterator.
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* subnet module for unbound.
*/
#include "config.h"
#ifdef CLIENT_SUBNET /* keeps splint happy */
#include "edns-subnet/subnetmod.h"
#include "edns-subnet/edns-subnet.h"
#include "edns-subnet/addrtree.h"
#include "edns-subnet/subnet-whitelist.h"
#include "services/mesh.h"
#include "services/cache/dns.h"
#include "util/module.h"
#include "util/regional.h"
#include "util/storage/slabhash.h"
#include "util/config_file.h"
#include "util/data/msgreply.h"
#include "sldns/sbuffer.h"
#define ECS_MAX_TREESIZE 100
/** externally called */
void
subnet_data_delete(void *d, void *ATTR_UNUSED(arg))
{
struct subnet_msg_cache_data *r;
r = (struct subnet_msg_cache_data*)d;
addrtree_delete(r->tree4);
addrtree_delete(r->tree6);
free(r);
}
/** externally called */
size_t
msg_cache_sizefunc(void *k, void *d)
{
struct msgreply_entry *q = (struct msgreply_entry*)k;
struct subnet_msg_cache_data *r = (struct subnet_msg_cache_data*)d;
size_t s = sizeof(struct msgreply_entry)
+ sizeof(struct subnet_msg_cache_data)
+ q->key.qname_len + lock_get_mem(&q->entry.lock);
s += addrtree_size(r->tree4);
s += addrtree_size(r->tree6);
return s;
}
/** new query for ecs module */
static int
subnet_new_qstate(struct module_qstate *qstate, int id)
{
struct subnet_qstate *sq = (struct subnet_qstate*)regional_alloc(
qstate->region, sizeof(struct subnet_qstate));
if(!sq)
return 0;
qstate->minfo[id] = sq;
memset(sq, 0, sizeof(*sq));
return 1;
}
/** Add ecs struct to edns list, after parsing it to wire format. */
static void
ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list,
struct module_qstate *qstate)
{
size_t sn_octs, sn_octs_remainder;
sldns_buffer* buf = qstate->env->scratch_buffer;
if(ecs->subnet_validdata) {
log_assert(ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 ||
ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6);
log_assert(ecs->subnet_addr_fam != EDNSSUBNET_ADDRFAM_IP4 ||
ecs->subnet_source_mask <= INET_SIZE*8);
log_assert(ecs->subnet_addr_fam != EDNSSUBNET_ADDRFAM_IP6 ||
ecs->subnet_source_mask <= INET6_SIZE*8);
sn_octs = ecs->subnet_source_mask / 8;
sn_octs_remainder =
(size_t)((ecs->subnet_source_mask % 8)>0?1:0);
log_assert(sn_octs + sn_octs_remainder <= INET6_SIZE);
sldns_buffer_clear(buf);
sldns_buffer_write_u16(buf, ecs->subnet_addr_fam);
sldns_buffer_write_u8(buf, ecs->subnet_source_mask);
sldns_buffer_write_u8(buf, ecs->subnet_scope_mask);
sldns_buffer_write(buf, ecs->subnet_addr, sn_octs);
if(sn_octs_remainder)
sldns_buffer_write_u8(buf, ecs->subnet_addr[sn_octs] &
~(0xFF >> (ecs->subnet_source_mask % 8)));
sldns_buffer_flip(buf);
edns_opt_list_append(list,
qstate->env->cfg->client_subnet_opcode,
sn_octs + sn_octs_remainder + 4,
sldns_buffer_begin(buf), qstate->region);
}
}
int ecs_whitelist_check(struct query_info* qinfo,
uint16_t ATTR_UNUSED(flags), struct module_qstate* qstate,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
struct regional* ATTR_UNUSED(region), int id, void* ATTR_UNUSED(cbargs))
{
struct subnet_qstate *sq;
struct subnet_env *sn_env;
if(!(sq=(struct subnet_qstate*)qstate->minfo[id]))
return 1;
sn_env = (struct subnet_env*)qstate->env->modinfo[id];
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
qstate->no_cache_store = 0;
if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
qstate->env->cfg->client_subnet_always_forward) ||
ecs_is_whitelisted(sn_env->whitelist,
addr, addrlen, qinfo->qname, qinfo->qname_len,
qinfo->qclass))) {
/* Address on whitelist or client query contains ECS option, we
* want to sent out ECS. Only add option if it is not already
* set. */
if(!(sq->subnet_sent)) {
ecs_opt_list_append(&sq->ecs_server_out,
&qstate->edns_opts_back_out, qstate);
sq->subnet_sent = 1;
}
}
else if(sq->subnet_sent) {
/* Outgoing ECS option is set, but we don't want to sent it to
* this address, remove option. */
edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
}
return 1;
}
int
subnetmod_init(struct module_env *env, int id)
{
struct subnet_env *sn_env = (struct subnet_env*)calloc(1,
sizeof(struct subnet_env));
if(!sn_env) {
log_err("malloc failure");
return 0;
}
alloc_init(&sn_env->alloc, NULL, 0);
env->modinfo[id] = (void*)sn_env;
/* Copy msg_cache settings */
sn_env->subnet_msg_cache = slabhash_create(env->cfg->msg_cache_slabs,
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
msg_cache_sizefunc, query_info_compare, query_entry_delete,
subnet_data_delete, NULL);
if(!sn_env->subnet_msg_cache) {
log_err("subnet: could not create cache");
free(sn_env);
env->modinfo[id] = NULL;
return 0;
}
/* whitelist for edns subnet capable servers */
sn_env->whitelist = ecs_whitelist_create();
if(!sn_env->whitelist ||
!ecs_whitelist_apply_cfg(sn_env->whitelist, env->cfg)) {
log_err("subnet: could not create ECS whitelist");
slabhash_delete(sn_env->subnet_msg_cache);
free(sn_env);
env->modinfo[id] = NULL;
return 0;
}
verbose(VERB_QUERY, "subnet: option registered (%d)",
env->cfg->client_subnet_opcode);
/* Create new mesh state for all queries. */
env->unique_mesh = 1;
if(!edns_register_option(env->cfg->client_subnet_opcode,
env->cfg->client_subnet_always_forward /* bypass cache */,
0 /* no aggregation */, env)) {
log_err("subnet: could not register opcode");
ecs_whitelist_delete(sn_env->whitelist);
slabhash_delete(sn_env->subnet_msg_cache);
free(sn_env);
env->modinfo[id] = NULL;
return 0;
}
inplace_cb_register((void*)ecs_whitelist_check, inplace_cb_query, NULL,
env, id);
inplace_cb_register((void*)ecs_edns_back_parsed,
inplace_cb_edns_back_parsed, NULL, env, id);
inplace_cb_register((void*)ecs_query_response,
inplace_cb_query_response, NULL, env, id);
lock_rw_init(&sn_env->biglock);
return 1;
}
void
subnetmod_deinit(struct module_env *env, int id)
{
struct subnet_env *sn_env;
if(!env || !env->modinfo[id])
return;
sn_env = (struct subnet_env*)env->modinfo[id];
lock_rw_destroy(&sn_env->biglock);
inplace_cb_delete(env, inplace_cb_edns_back_parsed, id);
inplace_cb_delete(env, inplace_cb_query, id);
inplace_cb_delete(env, inplace_cb_query_response, id);
ecs_whitelist_delete(sn_env->whitelist);
slabhash_delete(sn_env->subnet_msg_cache);
alloc_clear(&sn_env->alloc);
free(sn_env);
env->modinfo[id] = NULL;
}
/** Tells client that upstream has no/improper support */
static void
cp_edns_bad_response(struct ecs_data *target, struct ecs_data *source)
{
target->subnet_scope_mask = 0;
target->subnet_source_mask = source->subnet_source_mask;
target->subnet_addr_fam = source->subnet_addr_fam;
memcpy(target->subnet_addr, source->subnet_addr, INET6_SIZE);
target->subnet_validdata = 1;
}
static void
delfunc(void *envptr, void *elemptr) {
struct reply_info *elem = (struct reply_info *)elemptr;
struct subnet_env *env = (struct subnet_env *)envptr;
reply_info_parsedelete(elem, &env->alloc);
}
static size_t
sizefunc(void *elemptr) {
struct reply_info *elem = (struct reply_info *)elemptr;
return sizeof (struct reply_info) - sizeof (struct rrset_ref)
+ elem->rrset_count * sizeof (struct rrset_ref)
+ elem->rrset_count * sizeof (struct ub_packed_rrset_key *);
}
/**
* Select tree from cache entry based on edns data.
* If for address family not present it will create a new one.
* NULL on failure to create. */
static struct addrtree*
get_tree(struct subnet_msg_cache_data *data, struct ecs_data *edns,
struct subnet_env *env, struct config_file* cfg)
{
struct addrtree *tree;
if (edns->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
if (!data->tree4)
data->tree4 = addrtree_create(
cfg->max_client_subnet_ipv4, &delfunc,
&sizefunc, env, ECS_MAX_TREESIZE);
tree = data->tree4;
} else {
if (!data->tree6)
data->tree6 = addrtree_create(
cfg->max_client_subnet_ipv6, &delfunc,
&sizefunc, env, ECS_MAX_TREESIZE);
tree = data->tree6;
}
return tree;
}
static void
update_cache(struct module_qstate *qstate, int id)
{
struct msgreply_entry *mrep_entry;
struct addrtree *tree;
struct reply_info *rep;
struct query_info qinf;
struct subnet_env *sne = qstate->env->modinfo[id];
struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id];
struct slabhash *subnet_msg_cache = sne->subnet_msg_cache;
struct ecs_data *edns = &sq->ecs_client_in;
size_t i;
/* We already calculated hash upon lookup */
hashvalue_type h = qstate->minfo[id] ?
((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash :
query_info_hash(&qstate->qinfo, qstate->query_flags);
/* Step 1, general qinfo lookup */
struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
&qstate->qinfo, 1);
int acquired_lock = (lru_entry != NULL);
if (!lru_entry) {
qinf = qstate->qinfo;
qinf.qname = memdup(qstate->qinfo.qname,
qstate->qinfo.qname_len);
if(!qinf.qname) {
log_err("memdup failed");
return;
}
mrep_entry = query_info_entrysetup(&qinf, NULL, h);
free(qinf.qname); /* if qname 'consumed', it is set to NULL */
if (!mrep_entry) {
log_err("query_info_entrysetup failed");
return;
}
lru_entry = &mrep_entry->entry;
lru_entry->data = calloc(1,
sizeof(struct subnet_msg_cache_data));
if (!lru_entry->data) {
log_err("malloc failed");
return;
}
}
/* Step 2, find the correct tree */
if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
log_err("Subnet cache insertion failed");
return;
}
rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL);
if (!rep) {
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
log_err("Subnet cache insertion failed");
return;
}
/* store RRsets */
for(i=0; i<rep->rrset_count; i++) {
rep->ref[i].key = rep->rrsets[i];
rep->ref[i].id = rep->rrsets[i]->id;
}
reply_info_set_ttls(rep, *qstate->env->now);
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
edns->subnet_source_mask,
sq->ecs_server_in.subnet_scope_mask, rep,
rep->ttl, *qstate->env->now);
if (acquired_lock) {
lock_rw_unlock(&lru_entry->lock);
} else {
slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
NULL);
}
}
/** Lookup in cache and reply true iff reply is sent. */
static int
lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
{
struct lruhash_entry *e;
struct module_env *env = qstate->env;
struct subnet_env *sne = (struct subnet_env*)env->modinfo[id];
hashvalue_type h = query_info_hash(&qstate->qinfo, qstate->query_flags);
struct subnet_msg_cache_data *data;
struct ecs_data *ecs = &sq->ecs_client_in;
struct addrtree *tree;
struct addrnode *node;
uint8_t scope;
memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out));
if (sq) sq->qinfo_hash = h; /* Might be useful on cache miss */
e = slabhash_lookup(sne->subnet_msg_cache, h, &qstate->qinfo, 1);
if (!e) return 0; /* qinfo not in cache */
data = e->data;
tree = (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4)?
data->tree4 : data->tree6;
if (!tree) { /* qinfo in cache but not for this family */
lock_rw_unlock(&e->lock);
return 0;
}
node = addrtree_find(tree, (addrkey_t*)ecs->subnet_addr,
ecs->subnet_source_mask, *env->now);
if (!node) { /* plain old cache miss */
lock_rw_unlock(&e->lock);
return 0;
}
qstate->return_msg = tomsg(NULL, &qstate->qinfo,
(struct reply_info *)node->elem, qstate->region, *env->now,
env->scratch);
scope = (uint8_t)node->scope;
lock_rw_unlock(&e->lock);
if (!qstate->return_msg) { /* Failed allocation or expired TTL */
return 0;
}
if (sq->subnet_downstream) { /* relay to interested client */
sq->ecs_client_out.subnet_scope_mask = scope;
sq->ecs_client_out.subnet_addr_fam = ecs->subnet_addr_fam;
sq->ecs_client_out.subnet_source_mask = ecs->subnet_source_mask;
memcpy(&sq->ecs_client_out.subnet_addr, &ecs->subnet_addr,
INET6_SIZE);
sq->ecs_client_out.subnet_validdata = 1;
}
return 1;
}
/**
* Test first bits of addresses for equality. Caller is responsible
* for making sure that both a and b are at least net/8 octets long.
* @param a: first address.
* @param a: seconds address.
* @param net: Number of bits to test.
* @return: 1 if equal, 0 otherwise.
*/
static int
common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
{
size_t n = (size_t)net / 8;
return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]);
}
static enum module_ext_state
eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
{
struct subnet_env *sne = qstate->env->modinfo[id];
struct ecs_data *c_in = &sq->ecs_client_in; /* rcvd from client */
struct ecs_data *c_out = &sq->ecs_client_out;/* will send to client */
struct ecs_data *s_in = &sq->ecs_server_in; /* rcvd from auth */
struct ecs_data *s_out = &sq->ecs_server_out;/* sent to auth */
memset(c_out, 0, sizeof(*c_out));
if (!qstate->return_msg) return module_error;
/* We have not asked for subnet data */
if (!sq->subnet_sent) {
if (s_in->subnet_validdata)
verbose(VERB_QUERY, "subnet: received spurious data");
if (sq->subnet_downstream) /* Copy back to client */
cp_edns_bad_response(c_out, c_in);
return module_finished;
}
/* subnet sent but nothing came back */
if (!s_in->subnet_validdata) {
/* The authority indicated no support for edns subnet. As a
* consequence the answer ended up in the regular cache. It
* is still usefull to put it in the edns subnet cache for
* when a client explicitly asks for subnet specific answer. */
verbose(VERB_QUERY, "subnet: Authority indicates no support");
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
if (sq->subnet_downstream)
cp_edns_bad_response(c_out, c_in);
return module_finished;
}
/* Being here means we have asked for and got a subnet specific
* answer. Also, the answer from the authority is not yet cached
* anywhere. */
/* can we accept response? */
if(s_out->subnet_addr_fam != s_in->subnet_addr_fam ||
s_out->subnet_source_mask != s_in->subnet_source_mask ||
!common_prefix(s_out->subnet_addr, s_in->subnet_addr,
s_out->subnet_source_mask))
{
/* we can not accept, restart query without option */
verbose(VERB_QUERY, "subnet: forged data");
s_out->subnet_validdata = 0;
(void)edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
return module_restart_next;
}
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
if (sq->subnet_downstream) {
/* Client wants to see the answer, echo option back
* and adjust the scope. */
c_out->subnet_addr_fam = c_in->subnet_addr_fam;
c_out->subnet_source_mask = c_in->subnet_source_mask;
memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
c_out->subnet_scope_mask = s_in->subnet_scope_mask;
c_out->subnet_validdata = 1;
}
return module_finished;
}
/** Parse EDNS opt data containing ECS */
static int
parse_subnet_option(struct edns_option* ecs_option, struct ecs_data* ecs)
{
memset(ecs, 0, sizeof(*ecs));
if (ecs_option->opt_len < 4)
return 0;
ecs->subnet_addr_fam = sldns_read_uint16(ecs_option->opt_data);
ecs->subnet_source_mask = ecs_option->opt_data[2];
ecs->subnet_scope_mask = ecs_option->opt_data[3];
/* remaing bytes indicate address */
/* validate input*/
/* option length matches calculated length? */
if (ecs_option->opt_len != (size_t)((ecs->subnet_source_mask+7)/8 + 4))
return 0;
if (ecs_option->opt_len - 4 > INET6_SIZE || ecs_option->opt_len == 0)
return 0;
if (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
if (ecs->subnet_source_mask > 32 || ecs->subnet_scope_mask > 32)
return 0;
} else if (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6) {
if (ecs->subnet_source_mask > 128 ||
ecs->subnet_scope_mask > 128)
return 0;
} else
return 0;
/* valid ECS data, write to ecs_data */
if (copy_clear(ecs->subnet_addr, INET6_SIZE, ecs_option->opt_data + 4,
ecs_option->opt_len - 4, ecs->subnet_source_mask))
return 0;
ecs->subnet_validdata = 1;
return 1;
}
static void
subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs,
struct config_file* cfg)
{
void* sinaddr;
/* Construct subnet option from original query */
if(((struct sockaddr_in*)ss)->sin_family == AF_INET) {
ecs->subnet_source_mask = cfg->max_client_subnet_ipv4;
ecs->subnet_addr_fam = EDNSSUBNET_ADDRFAM_IP4;
sinaddr = &((struct sockaddr_in*)ss)->sin_addr;
if (!copy_clear( ecs->subnet_addr, INET6_SIZE,
(uint8_t *)sinaddr, INET_SIZE,
ecs->subnet_source_mask)) {
ecs->subnet_validdata = 1;
}
}
#ifdef INET6
else {
ecs->subnet_source_mask = cfg->max_client_subnet_ipv6;
ecs->subnet_addr_fam = EDNSSUBNET_ADDRFAM_IP6;
sinaddr = &((struct sockaddr_in6*)ss)->sin6_addr;
if (!copy_clear( ecs->subnet_addr, INET6_SIZE,
(uint8_t *)sinaddr, INET6_SIZE,
ecs->subnet_source_mask)) {
ecs->subnet_validdata = 1;
}
}
#else
/* We don't know how to handle ip6, just pass */
#endif /* INET6 */
}
int
ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
int id, void* ATTR_UNUSED(cbargs))
{
struct subnet_qstate *sq;
if(!response || !(sq=(struct subnet_qstate*)qstate->minfo[id]))
return 1;
if(sq->subnet_sent &&
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_REFUSED) {
/* REFUSED reponse to ECS query, remove ECS option. */
edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
}
return 1;
}
int
ecs_edns_back_parsed(struct module_qstate* qstate, int id,
void* ATTR_UNUSED(cbargs))
{
struct subnet_qstate *sq;
struct edns_option* ecs_opt;
if(!(sq=(struct subnet_qstate*)qstate->minfo[id]))
return 1;
if((ecs_opt = edns_opt_list_find(
qstate->edns_opts_back_in,
qstate->env->cfg->client_subnet_opcode))) {
if(parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
sq->subnet_sent &&
sq->ecs_server_in.subnet_validdata)
/* Only skip global cache store if we sent an ECS option
* and received one back. Answers from non-whitelisted
* servers will end up in global cache. Ansers for
* queries with 0 source will not (unless nameserver
* does not support ECS). */
qstate->no_cache_store = 1;
}
return 1;
}
void
subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
int id, struct outbound_entry* outbound)
{
struct subnet_env *sne = qstate->env->modinfo[id];
struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id];
verbose(VERB_QUERY, "subnet[module %d] operate: extstate:%s "
"event:%s", id, strextstate(qstate->ext_state[id]),
strmodulevent(event));
log_query_info(VERB_QUERY, "subnet operate: query", &qstate->qinfo);
if((event == module_event_new || event == module_event_pass) &&
sq == NULL) {
struct edns_option* ecs_opt;
if(!subnet_new_qstate(qstate, id)) {
qstate->return_msg = NULL;
qstate->ext_state[id] = module_finished;
return;
}
sq = (struct subnet_qstate*)qstate->minfo[id];
if((ecs_opt = edns_opt_list_find(
qstate->edns_opts_front_in,
qstate->env->cfg->client_subnet_opcode))) {
if(!parse_subnet_option(ecs_opt, &sq->ecs_client_in)) {
/* Wrongly formatted ECS option. RFC mandates to
* return FORMERROR. */
qstate->return_rcode = LDNS_RCODE_FORMERR;
qstate->ext_state[id] = module_finished;
return;
}
sq->subnet_downstream = 1;
}
else if(qstate->mesh_info->reply_list) {
subnet_option_from_ss(
&qstate->mesh_info->reply_list->query_reply.addr,
&sq->ecs_client_in, qstate->env->cfg);
}
if(sq->ecs_client_in.subnet_validdata == 0) {
/* No clients are interested in result or we could not
* parse it, we don't do client subnet */
sq->ecs_server_out.subnet_validdata = 0;
verbose(VERB_ALGO, "subnet: pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
}
lock_rw_wrlock(&sne->biglock);
if (lookup_and_reply(qstate, id, sq)) {
lock_rw_unlock(&sne->biglock);
verbose(VERB_QUERY, "subnet: answered from cache");
qstate->ext_state[id] = module_finished;
ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate);
return;
}
lock_rw_unlock(&sne->biglock);
sq->ecs_server_out.subnet_addr_fam =
sq->ecs_client_in.subnet_addr_fam;
sq->ecs_server_out.subnet_source_mask =
sq->ecs_client_in.subnet_source_mask;
/* Limit source prefix to configured maximum */
if(sq->ecs_server_out.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4
&& sq->ecs_server_out.subnet_source_mask >
qstate->env->cfg->max_client_subnet_ipv4)
sq->ecs_server_out.subnet_source_mask =
qstate->env->cfg->max_client_subnet_ipv4;
else if(sq->ecs_server_out.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6
&& sq->ecs_server_out.subnet_source_mask >
qstate->env->cfg->max_client_subnet_ipv6)
sq->ecs_server_out.subnet_source_mask =
qstate->env->cfg->max_client_subnet_ipv6;
/* Safe to copy completely, even if the source is limited by the
* configuration. ecs_opt_list_append() will limit the address.
* */
memcpy(&sq->ecs_server_out.subnet_addr,
sq->ecs_client_in.subnet_addr, INET6_SIZE);
sq->ecs_server_out.subnet_scope_mask = 0;
sq->ecs_server_out.subnet_validdata = 1;
if(sq->ecs_server_out.subnet_source_mask != 0 &&
sq->subnet_downstream)
/* ECS specific data required, do not look at the global
* cache in other modules. */
qstate->no_cache_lookup = 1;
/* pass request to next module */
verbose(VERB_ALGO,
"subnet: not found in cache. pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
}
/* Query handed back by next module, we have a 'final' answer */
if(sq && event == module_event_moddone) {
qstate->ext_state[id] = eval_response(qstate, id, sq);
if(qstate->ext_state[id] == module_finished) {
ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate);
}
return;
}
if(sq && outbound) {
return;
}
/* We are being revisited */
if(event == module_event_pass || event == module_event_new) {
/* Just pass it on, we already did the work */
verbose(VERB_ALGO, "subnet: pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
}
if(!sq && (event == module_event_moddone)) {
/* during priming, module done but we never started */
qstate->ext_state[id] = module_finished;
return;
}
log_err("subnet: bad event %s", strmodulevent(event));
qstate->ext_state[id] = module_error;
return;
}
void
subnetmod_clear(struct module_qstate *ATTR_UNUSED(qstate),
int ATTR_UNUSED(id))
{
/* qstate has no data outside region */
}
void
subnetmod_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super))
{
/* Not used */
}
size_t
subnetmod_get_mem(struct module_env *env, int id)
{
struct subnet_env *sn_env = env->modinfo[id];
if (!sn_env) return 0;
return sizeof(*sn_env) +
slabhash_get_mem(sn_env->subnet_msg_cache) +
ecs_whitelist_get_mem(sn_env->whitelist);
}
/**
* The module function block
*/
static struct module_func_block subnetmod_block = {
"subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
};
struct module_func_block*
subnetmod_get_funcblock(void)
{
return &subnetmod_block;
}
/** Wrappers for static functions to unit test */
size_t
unittest_wrapper_subnetmod_sizefunc(void *elemptr)
{
return sizefunc(elemptr);
}
#endif /* CLIENT_SUBNET */
-130
View File
@@ -1,130 +0,0 @@
/*
* edns-subnet/subnetmod.h - edns subnet module. Must be called before validator
* and iterator.
*
* Copyright (c) 2013, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* subnet module for unbound.
*/
#ifndef SUBNETMOD_H
#define SUBNETMOD_H
#include "util/module.h"
#include "services/outbound_list.h"
#include "util/alloc.h"
#include "util/net_help.h"
#include "util/storage/slabhash.h"
#include "edns-subnet/addrtree.h"
#include "edns-subnet/edns-subnet.h"
/**
* Global state for the subnet module.
*/
struct subnet_env {
/** shared message cache
* key: struct query_info*
* data: struct subnet_msg_cache_data* */
struct slabhash* subnet_msg_cache;
/** access control, which upstream servers we send client address */
struct ecs_whitelist* whitelist;
/** allocation service */
struct alloc_cache alloc;
lock_rw_type biglock;
};
struct subnet_msg_cache_data {
struct addrtree* tree4;
struct addrtree* tree6;
};
struct subnet_qstate {
/** We need the hash for both cache lookup and insert */
hashvalue_type qinfo_hash;
/** ecs_data for client communication */
struct ecs_data ecs_client_in;
struct ecs_data ecs_client_out;
/** ecss data for server communication */
struct ecs_data ecs_server_in;
struct ecs_data ecs_server_out;
int subnet_downstream;
int subnet_sent;
};
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
size_t msg_cache_sizefunc(void* k, void* d);
/**
* Get the module function block.
* @return: function block with function pointers to module methods.
*/
struct module_func_block* subnetmod_get_funcblock(void);
/** subnet module init */
int subnetmod_init(struct module_env* env, int id);
/** subnet module deinit */
void subnetmod_deinit(struct module_env* env, int id);
/** subnet module operate on a query */
void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** subnet module */
void subnetmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** subnet module cleanup query state */
void subnetmod_clear(struct module_qstate* qstate, int id);
/** subnet module alloc size routine */
size_t subnetmod_get_mem(struct module_env* env, int id);
/** Wrappers for static functions to unit test */
size_t unittest_wrapper_subnetmod_sizefunc(void *elemptr);
/** Whitelist check, called just before query is sent upstream. */
int ecs_whitelist_check(struct query_info* qinfo, uint16_t flags,
struct module_qstate* qstate, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen,
struct regional* region, int id, void* cbargs);
/** Check whether reponse from server contains ECS record, if so, skip cache
* store. Called just after parsing EDNS data from server. */
int ecs_edns_back_parsed(struct module_qstate* qstate, int id, void* cbargs);
/** Remove ECS record from back_out when query resulted in REFUSED response. */
int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
int id, void* cbargs);
#endif /* SUBNETMOD_H */
-158
View File
@@ -1,158 +0,0 @@
/*
* ipsecmod/ipsecmod-whitelist.h - White listed domains for the ipsecmod to
* operate on.
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* Keep track of the white listed domains for ipsecmod.
*/
#include "config.h"
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#include "ipsecmod/ipsecmod-whitelist.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/rbtree.h"
#include "util/data/dname.h"
#include "util/storage/dnstree.h"
#include "sldns/str2wire.h"
/** Apply ipsecmod-whitelist string. */
static int
whitelist_str_cfg(rbtree_type* whitelist, const char* name)
{
struct name_tree_node* n;
size_t len;
uint8_t* nm = sldns_str2wire_dname(name, &len);
if(!nm) {
log_err("ipsecmod: could not parse %s for whitelist.", name);
return 0;
}
n = (struct name_tree_node*)calloc(1, sizeof(*n));
if(!n) {
log_err("ipsecmod: out of memory while creating whitelist.");
free(nm);
return 0;
}
n->node.key = n;
n->name = nm;
n->len = len;
n->labs = dname_count_labels(nm);
n->dclass = LDNS_RR_CLASS_IN;
if(!name_tree_insert(whitelist, n, nm, len, n->labs, n->dclass)) {
/* duplicate element ignored, idempotent */
free(n->name);
free(n);
}
return 1;
}
/** Read ipsecmod-whitelist config. */
static int
read_whitelist(rbtree_type* whitelist, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->ipsecmod_whitelist; p; p = p->next) {
log_assert(p->str);
if(!whitelist_str_cfg(whitelist, p->str))
return 0;
}
return 1;
}
int
ipsecmod_whitelist_apply_cfg(struct ipsecmod_env* ie,
struct config_file* cfg)
{
ie->whitelist = rbtree_create(name_tree_compare);
if(!read_whitelist(ie->whitelist, cfg))
return 0;
name_tree_init_parents(ie->whitelist);
return 1;
}
/** Delete ipsecmod_env->whitelist element. */
static void
whitelist_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
{
if(n) {
free(((struct name_tree_node*)n)->name);
free(n);
}
}
/** Get memory usage of ipsecmod_env->whitelist element. */
static void
whitelist_get_mem(struct rbnode_type* n, void* arg)
{
struct name_tree_node* node = (struct name_tree_node*)n;
size_t* size = (size_t*) arg;
if(node) {
*size += sizeof(node) + node->len;
}
}
void
ipsecmod_whitelist_delete(rbtree_type* whitelist)
{
if(whitelist) {
traverse_postorder(whitelist, whitelist_free, NULL);
free(whitelist);
}
}
int
ipsecmod_domain_is_whitelisted(struct ipsecmod_env* ie, uint8_t* dname,
size_t dname_len, uint16_t qclass)
{
if(!ie->whitelist) return 1; /* No whitelist, treat as whitelisted. */
return name_tree_lookup(ie->whitelist, dname, dname_len,
dname_count_labels(dname), qclass) != NULL;
}
size_t
ipsecmod_whitelist_get_mem(rbtree_type* whitelist)
{
size_t size = 0;
if(whitelist) {
traverse_postorder(whitelist, whitelist_get_mem, &size);
}
return size;
}
#endif /* USE_IPSECMOD */
-82
View File
@@ -1,82 +0,0 @@
/*
* ipsecmod/ipsecmod-whitelist.h - White listed domains for the ipsecmod to
* operate on.
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* Keep track of the white listed domains for ipsecmod.
*/
#ifndef IPSECMOD_WHITELIST_H
#define IPSECMOD_WHITELIST_H
#include "util/storage/dnstree.h"
struct config_file;
struct regional;
/**
* Process ipsecmod_whitelist config.
* @param ie: ipsecmod environment.
* @param cfg: config options.
* @return 0 on error.
*/
int ipsecmod_whitelist_apply_cfg(struct ipsecmod_env* ie,
struct config_file* cfg);
/**
* Delete the ipsecmod whitelist.
* @param whitelist: ipsecmod whitelist.
*/
void ipsecmod_whitelist_delete(rbtree_type* whitelist);
/**
* See if a domain is whitelisted.
* @param ie: ipsecmod environment.
* @param dname: domain name to check.
* @param dname_len: length of domain name.
* @param qclass: query CLASS.
* @return: true if the domain is whitelisted for the ipsecmod.
*/
int ipsecmod_domain_is_whitelisted(struct ipsecmod_env* ie, uint8_t* dname,
size_t dname_len, uint16_t qclass);
/**
* Get memory used by ipsecmod whitelist.
* @param whitelist: structure for domain storage.
* @return bytes in use.
*/
size_t ipsecmod_whitelist_get_mem(rbtree_type* whitelist);
#endif /* IPSECMOD_WHITELIST_H */
-515
View File
@@ -1,515 +0,0 @@
/*
* ipsecmod/ipsecmod.c - facilitate opportunistic IPsec module
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains a module that facilitates opportunistic IPsec. It does so
* by also quering for the IPSECKEY for A/AAAA queries and calling a
* configurable hook (eg. signaling an IKE daemon) before replying.
*/
#include "config.h"
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#include "ipsecmod/ipsecmod-whitelist.h"
#include "util/fptr_wlist.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "services/cache/dns.h"
#include "sldns/wire2str.h"
/** Apply configuration to ipsecmod module 'global' state. */
static int
ipsecmod_apply_cfg(struct ipsecmod_env* ipsecmod_env, struct config_file* cfg)
{
if(!cfg->ipsecmod_hook || (cfg->ipsecmod_hook && !cfg->ipsecmod_hook[0])) {
log_err("ipsecmod: missing ipsecmod-hook.");
return 0;
}
if(cfg->ipsecmod_whitelist &&
!ipsecmod_whitelist_apply_cfg(ipsecmod_env, cfg))
return 0;
return 1;
}
int
ipsecmod_init(struct module_env* env, int id)
{
struct ipsecmod_env* ipsecmod_env = (struct ipsecmod_env*)calloc(1,
sizeof(struct ipsecmod_env));
if(!ipsecmod_env) {
log_err("malloc failure");
return 0;
}
env->modinfo[id] = (void*)ipsecmod_env;
ipsecmod_env->whitelist = NULL;
if(!ipsecmod_apply_cfg(ipsecmod_env, env->cfg)) {
log_err("ipsecmod: could not apply configuration settings.");
return 0;
}
return 1;
}
void
ipsecmod_deinit(struct module_env* env, int id)
{
struct ipsecmod_env* ipsecmod_env;
if(!env || !env->modinfo[id])
return;
ipsecmod_env = (struct ipsecmod_env*)env->modinfo[id];
/* Free contents. */
ipsecmod_whitelist_delete(ipsecmod_env->whitelist);
free(ipsecmod_env);
env->modinfo[id] = NULL;
}
/** New query for ipsecmod. */
static int
ipsecmod_new(struct module_qstate* qstate, int id)
{
struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc(
qstate->region, sizeof(struct ipsecmod_qstate));
memset(iq, 0, sizeof(*iq));
qstate->minfo[id] = iq;
if(!iq)
return 0;
/* Initialise it. */
iq->enabled = qstate->env->cfg->ipsecmod_enabled;
iq->is_whitelisted = ipsecmod_domain_is_whitelisted(
(struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qclass);
return 1;
}
/**
* Exit module with an error status.
* @param qstate: query state
* @param id: module id.
*/
static void
ipsecmod_error(struct module_qstate* qstate, int id)
{
qstate->ext_state[id] = module_error;
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
}
/**
* Generate a request for the IPSECKEY.
*
* @param qstate: query state that is the parent.
* @param id: module id.
* @param name: what name to query for.
* @param namelen: length of name.
* @param qtype: query type.
* @param qclass: query class.
* @param flags: additional flags, such as the CD bit (BIT_CD), or 0.
* @return false on alloc failure.
*/
static int
generate_request(struct module_qstate* qstate, int id, uint8_t* name,
size_t namelen, uint16_t qtype, uint16_t qclass, uint16_t flags)
{
struct module_qstate* newq;
struct query_info ask;
ask.qname = name;
ask.qname_len = namelen;
ask.qtype = qtype;
ask.qclass = qclass;
ask.local_alias = NULL;
log_query_info(VERB_ALGO, "ipsecmod: generate request", &ask);
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
(uint16_t)(BIT_RD|flags), 0, 0, &newq)){
log_err("Could not generate request: out of memory");
return 0;
}
qstate->ext_state[id] = module_wait_subquery;
return 1;
}
/**
* Prepare the data and call the hook.
*
* @param qstate: query state.
* @param iq: ipsecmod qstate.
* @param ie: ipsecmod environment.
* @return true on success, false otherwise.
*/
static int
call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq,
struct ipsecmod_env* ATTR_UNUSED(ie))
{
size_t slen, tempdata_len, tempstring_len, i;
char str[65535], *s, *tempstring;
int w;
struct ub_packed_rrset_key* rrset_key;
struct packed_rrset_data* rrset_data;
uint8_t *tempdata;
/* Check if a shell is available */
if(system(NULL) == 0) {
log_err("ipsecmod: no shell available for ipsecmod-hook");
return 0;
}
/* Zero the buffer. */
s = str;
slen = sizeof(str);
memset(s, 0, slen);
/* Copy the hook into the buffer. */
sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook);
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the qname into the buffer. */
tempstring = sldns_wire2str_dname(qstate->qinfo.qname,
qstate->qinfo.qname_len);
if(!tempstring) {
log_err("ipsecmod: out of memory when calling the hook");
return 0;
}
sldns_str_print(&s, &slen, "\"%s\"", tempstring);
free(tempstring);
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the IPSECKEY TTL into the buffer. */
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl);
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the A/AAAA record(s) into the buffer. Start and end this section
* with a double quote. */
rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo,
qstate->return_msg->rep);
rrset_data = (struct packed_rrset_data*)rrset_key->entry.data;
sldns_str_print(&s, &slen, "\"");
for(i=0; i<rrset_data->count; i++) {
if(i > 0) {
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
}
/* Ignore the first two bytes, they are the rr_data len. */
w = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2,
rrset_data->rr_len[i] - 2, s, slen, qstate->qinfo.qtype);
if(w < 0) {
/* Error in printout. */
return -1;
} else if((size_t)w >= slen) {
s = NULL; /* We do not want str to point outside of buffer. */
slen = 0;
return -1;
} else {
s += w;
slen -= w;
}
}
sldns_str_print(&s, &slen, "\"");
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the IPSECKEY record(s) into the buffer. Start and end this section
* with a double quote. */
sldns_str_print(&s, &slen, "\"");
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
for(i=0; i<rrset_data->count; i++) {
if(i > 0) {
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
}
/* Ignore the first two bytes, they are the rr_data len. */
tempdata = rrset_data->rr_data[i] + 2;
tempdata_len = rrset_data->rr_len[i] - 2;
/* Save the buffer pointers. */
tempstring = s; tempstring_len = slen;
w = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, &slen,
NULL, 0);
/* There was an error when parsing the IPSECKEY; reset the buffer
* pointers to their previous values. */
if(w == -1){
s = tempstring; slen = tempstring_len;
}
}
sldns_str_print(&s, &slen, "\"");
verbose(VERB_ALGO, "ipsecmod: hook command: '%s'", str);
/* ipsecmod-hook should return 0 on success. */
if(system(str) != 0)
return 0;
return 1;
}
/**
* Handle an ipsecmod module event with a query
* @param qstate: query state (from the mesh), passed between modules.
* contains qstate->env module environment with global caches and so on.
* @param iq: query state specific for this module. per-query.
* @param ie: environment specific for this module. global.
* @param id: module id.
*/
static void
ipsecmod_handle_query(struct module_qstate* qstate,
struct ipsecmod_qstate* iq, struct ipsecmod_env* ie, int id)
{
struct ub_packed_rrset_key* rrset_key;
struct packed_rrset_data* rrset_data;
size_t i;
/* Pass to next module if we are not enabled and whitelisted. */
if(!(iq->enabled && iq->is_whitelisted)) {
qstate->ext_state[id] = module_wait_module;
return;
}
/* New query, check if the query is for an A/AAAA record and disable
* caching for other modules. */
if(!iq->ipseckey_done) {
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
char type[16];
sldns_wire2str_type_buf(qstate->qinfo.qtype, type,
sizeof(type));
verbose(VERB_ALGO, "ipsecmod: query for %s; engaging",
type);
qstate->no_cache_store = 1;
}
/* Pass request to next module. */
qstate->ext_state[id] = module_wait_module;
return;
}
/* IPSECKEY subquery is finished. */
/* We have an IPSECKEY answer. */
if(iq->ipseckey_rrset) {
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
if(rrset_data) {
/* If bogus return SERVFAIL. */
if(!qstate->env->cfg->ipsecmod_ignore_bogus &&
rrset_data->security == sec_status_bogus) {
log_err("ipsecmod: bogus IPSECKEY");
ipsecmod_error(qstate, id);
return;
}
/* We have a valid IPSECKEY reply, call hook. */
if(!call_hook(qstate, iq, ie) &&
qstate->env->cfg->ipsecmod_strict) {
log_err("ipsecmod: ipsecmod-hook failed");
ipsecmod_error(qstate, id);
return;
}
/* Make sure the A/AAAA's TTL is equal/less than the
* ipsecmod_max_ttl. */
rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo,
qstate->return_msg->rep);
rrset_data = (struct packed_rrset_data*)rrset_key->entry.data;
if(rrset_data->ttl > (time_t)qstate->env->cfg->ipsecmod_max_ttl) {
/* Update TTL for rrset to fixed value. */
rrset_data->ttl = qstate->env->cfg->ipsecmod_max_ttl;
for(i=0; i<rrset_data->count+rrset_data->rrsig_count; i++)
rrset_data->rr_ttl[i] = qstate->env->cfg->ipsecmod_max_ttl;
/* Also update reply_info's TTL */
if(qstate->return_msg->rep->ttl > (time_t)qstate->env->cfg->ipsecmod_max_ttl) {
qstate->return_msg->rep->ttl =
qstate->env->cfg->ipsecmod_max_ttl;
qstate->return_msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(
qstate->return_msg->rep->ttl);
}
}
}
}
/* Store A/AAAA in cache. */
if(!dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway,
0, qstate->region, qstate->query_flags)) {
log_err("ipsecmod: out of memory caching record");
}
qstate->ext_state[id] = module_finished;
}
/**
* Handle an ipsecmod module event with a response from the iterator.
* @param qstate: query state (from the mesh), passed between modules.
* contains qstate->env module environment with global caches and so on.
* @param iq: query state specific for this module. per-query.
* @param ie: environment specific for this module. global.
* @param id: module id.
*/
static void
ipsecmod_handle_response(struct module_qstate* qstate,
struct ipsecmod_qstate* ATTR_UNUSED(iq),
struct ipsecmod_env* ATTR_UNUSED(ie), int id)
{
/* Pass to previous module if we are not enabled and whitelisted. */
if(!(iq->enabled && iq->is_whitelisted)) {
qstate->ext_state[id] = module_finished;
return;
}
/* check if the response is for an A/AAAA query. */
if((qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) &&
/* check that we had an answer for the A/AAAA query. */
qstate->return_msg &&
reply_find_answer_rrset(&qstate->return_msg->qinfo,
qstate->return_msg->rep) &&
/* check that another module didn't SERVFAIL. */
qstate->return_rcode == LDNS_RCODE_NOERROR) {
char type[16];
sldns_wire2str_type_buf(qstate->qinfo.qtype, type,
sizeof(type));
verbose(VERB_ALGO, "ipsecmod: response for %s; generating IPSECKEY "
"subquery", type);
/* generate an IPSECKEY query. */
if(!generate_request(qstate, id, qstate->qinfo.qname,
qstate->qinfo.qname_len, LDNS_RR_TYPE_IPSECKEY,
qstate->qinfo.qclass, 0)) {
log_err("ipsecmod: could not generate subquery.");
ipsecmod_error(qstate, id);
}
return;
}
/* we are done with the query. */
qstate->ext_state[id] = module_finished;
}
void
ipsecmod_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
struct ipsecmod_env* ie = (struct ipsecmod_env*)qstate->env->modinfo[id];
struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)qstate->minfo[id];
verbose(VERB_QUERY, "ipsecmod[module %d] operate: extstate:%s event:%s",
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
if(iq) log_query_info(VERB_QUERY, "ipsecmod operate: query",
&qstate->qinfo);
/* create ipsecmod_qstate. */
if((event == module_event_new || event == module_event_pass) &&
iq == NULL) {
if(!ipsecmod_new(qstate, id)) {
ipsecmod_error(qstate, id);
return;
}
iq = (struct ipsecmod_qstate*)qstate->minfo[id];
}
if(iq && (event == module_event_pass || event == module_event_new)) {
ipsecmod_handle_query(qstate, iq, ie, id);
return;
}
if(iq && (event == module_event_moddone)) {
ipsecmod_handle_response(qstate, iq, ie, id);
return;
}
if(iq && outbound) {
/* cachedb does not need to process responses at this time
* ignore it.
cachedb_process_response(qstate, iq, ie, id, outbound, event);
*/
return;
}
if(event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
ipsecmod_error(qstate, id);
return;
}
if(!iq && (event == module_event_moddone)) {
/* during priming, module done but we never started. */
qstate->ext_state[id] = module_finished;
return;
}
log_err("ipsecmod: bad event %s", strmodulevent(event));
ipsecmod_error(qstate, id);
return;
}
void
ipsecmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super)
{
struct ipsecmod_qstate* siq;
log_query_info(VERB_ALGO, "ipsecmod: inform_super, sub is",
&qstate->qinfo);
log_query_info(VERB_ALGO, "super is", &super->qinfo);
siq = (struct ipsecmod_qstate*)super->minfo[id];
if(!siq) {
verbose(VERB_ALGO, "super has no ipsecmod state");
return;
}
if(qstate->return_msg) {
struct ub_packed_rrset_key* rrset_key = reply_find_answer_rrset(
&qstate->return_msg->qinfo, qstate->return_msg->rep);
if(rrset_key) {
/* We have an answer. */
/* Copy to super's region. */
rrset_key = packed_rrset_copy_region(rrset_key, super->region, 0);
siq->ipseckey_rrset = rrset_key;
if(!rrset_key) {
log_err("ipsecmod: out of memory.");
}
}
}
/* Notify super to proceed. */
siq->ipseckey_done = 1;
}
void
ipsecmod_clear(struct module_qstate* qstate, int id)
{
if(!qstate)
return;
qstate->minfo[id] = NULL;
}
size_t
ipsecmod_get_mem(struct module_env* env, int id)
{
struct ipsecmod_env* ie = (struct ipsecmod_env*)env->modinfo[id];
if(!ie)
return 0;
return sizeof(*ie) + ipsecmod_whitelist_get_mem(ie->whitelist);
}
/**
* The ipsecmod function block
*/
static struct module_func_block ipsecmod_block = {
"ipsecmod",
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
};
struct module_func_block*
ipsecmod_get_funcblock(void)
{
return &ipsecmod_block;
}
#endif /* USE_IPSECMOD */
-97
View File
@@ -1,97 +0,0 @@
/*
* ipsecmod/ipsecmod.h - facilitate opportunistic IPsec module
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains a module that facilitates opportunistic IPsec. It does so
* by also quering for the IPSECKEY for A/AAAA queries and calling a
* configurable hook (eg. signaling an IKE daemon) before replying.
*/
#ifndef IPSECMOD_H
#define IPSECMOD_H
#include "util/module.h"
#include "util/rbtree.h"
/**
* The global variable environment contents for the ipsecmod
* Shared between threads, this represents long term information.
*/
struct ipsecmod_env {
/** White listed domains for ipsecmod. */
rbtree_type* whitelist;
};
/**
* Per query state for the ipsecmod module.
*/
struct ipsecmod_qstate {
/** State of the IPsec module. */
/** NOTE: This value is copied here from the configuration so that a change
* with unbound-control would not complicate an already running mesh. */
int enabled;
/** If the qname is whitelisted or not. */
/** NOTE: No whitelist means all qnames are whitelisted. */
int is_whitelisted;
/** Pointer to IPSECKEY rrset allocated in the qstate region. NULL if there
* was no IPSECKEY reply from the subquery. */
struct ub_packed_rrset_key* ipseckey_rrset;
/** If the IPSECKEY subquery has finished. */
int ipseckey_done;
};
/** Init the ipsecmod module */
int ipsecmod_init(struct module_env* env, int id);
/** Deinit the ipsecmod module */
void ipsecmod_deinit(struct module_env* env, int id);
/** Operate on an event on a query (in qstate). */
void ipsecmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** Subordinate query done, inform this super request of its conclusion */
void ipsecmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** clear the ipsecmod query-specific contents out of qstate */
void ipsecmod_clear(struct module_qstate* qstate, int id);
/** return memory estimate for the ipsecmod module */
size_t ipsecmod_get_mem(struct module_env* env, int id);
/**
* Get the function block with pointers to the ipsecmod functions
* @return the function block for "ipsecmod".
*/
struct module_func_block* ipsecmod_get_funcblock(void);
#endif /* IPSECMOD_H */
+1 -1
View File
@@ -58,7 +58,7 @@ struct iter_donotq {
* contents of type addr_tree_node. Each node is an address span
* that must not be used to send queries to.
*/
rbtree_type tree;
rbtree_t tree;
};
/**
+4 -4
View File
@@ -82,7 +82,7 @@ static void fwd_zone_free(struct iter_forward_zone* n)
free(n);
}
static void delfwdnode(rbnode_type* n, void* ATTR_UNUSED(arg))
static void delfwdnode(rbnode_t* n, void* ATTR_UNUSED(arg))
{
struct iter_forward_zone* node = (struct iter_forward_zone*)n;
fwd_zone_free(node);
@@ -332,7 +332,7 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
struct delegpt*
forwards_find(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
{
rbnode_type* res = NULL;
rbnode_t* res = NULL;
struct iter_forward_zone key;
key.node.key = &key;
key.dclass = qclass;
@@ -347,7 +347,7 @@ struct delegpt*
forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
{
/* lookup the forward zone in the tree */
rbnode_type* res = NULL;
rbnode_t* res = NULL;
struct iter_forward_zone *result;
struct iter_forward_zone key;
key.node.key = &key;
@@ -388,7 +388,7 @@ int
forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
{
struct iter_forward_zone key;
rbnode_type* n;
rbnode_t* n;
struct iter_forward_zone* p;
if(*dclass == 0) {
/* first root item is first item in tree */
+2 -2
View File
@@ -57,7 +57,7 @@ struct iter_forwards {
* match which gives the ancestor needed.
* contents of type iter_forward_zone.
*/
rbtree_type* tree;
rbtree_t* tree;
};
/**
@@ -65,7 +65,7 @@ struct iter_forwards {
*/
struct iter_forward_zone {
/** redblacktree node, key is this structure: class and name */
rbnode_type node;
rbnode_t node;
/** name */
uint8_t* name;
/** length of name */
+2 -2
View File
@@ -67,7 +67,7 @@ static void hints_stub_free(struct iter_hints_stub* s)
free(s);
}
static void delhintnode(rbnode_type* n, void* ATTR_UNUSED(arg))
static void delhintnode(rbnode_t* n, void* ATTR_UNUSED(arg))
{
struct iter_hints_stub* node = (struct iter_hints_stub*)n;
hints_stub_free(node);
@@ -144,7 +144,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
}
if(do_ip6) {
if(!ah(dp, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) goto failed;
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:200::b")) goto failed;
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:84::b")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "2001:500:2::c")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) goto failed;
if(!ah(dp, "E.ROOT-SERVERS.NET.", "2001:500:a8::e")) goto failed;
+1 -1
View File
@@ -59,7 +59,7 @@ struct iter_hints {
* contents of type iter_hints_stub. The class IN root is in here.
* uses name_tree_node from dnstree.h.
*/
rbtree_type tree;
rbtree_t tree;
};
/**
+2 -2
View File
@@ -60,14 +60,14 @@ struct iter_priv {
* contents of type addr_tree_node.
* No further data need, only presence or absence.
*/
rbtree_type a;
rbtree_t a;
/**
* Tree of the domains spans that are allowed to contain
* the blocked address spans.
* contents of type name_tree_node.
* No further data need, only presence or absence.
*/
rbtree_type n;
rbtree_t n;
};
/**
+2 -2
View File
@@ -161,8 +161,8 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,
for(rr = rrset->rr_first; rr; rr = rr->next) {
if(get_additional_name(rrset, rr, &nm, &nmlen, pkt)) {
/* mark A */
hashvalue_type h = pkt_hash_rrset(pkt, nm,
LDNS_RR_TYPE_A, rrset->rrset_class, 0);
hashvalue_t h = pkt_hash_rrset(pkt, nm, LDNS_RR_TYPE_A,
rrset->rrset_class, 0);
struct rrset_parse* r = msgparse_hashtable_lookup(
msg, pkt, h, 0, nm, nmlen,
LDNS_RR_TYPE_A, rrset->rrset_class);
+1 -1
View File
@@ -108,7 +108,7 @@ read_fetch_policy(struct iter_env* ie, const char* str)
/** apply config caps whitelist items to name tree */
static int
caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
caps_white_apply_cfg(rbtree_t* ntree, struct config_file* cfg)
{
struct config_strlist* p;
for(p=cfg->caps_whitelist; p; p=p->next) {
+34 -129
View File
@@ -88,7 +88,7 @@ iter_init(struct module_env* env, int id)
/** delete caps_whitelist element */
static void
caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
caps_free(struct rbnode_t* n, void* ATTR_UNUSED(d))
{
if(n) {
free(((struct name_tree_node*)n)->name);
@@ -288,22 +288,6 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
return error_response(qstate, id, rcode);
/* if that fails (not in cache), fall through to store err */
}
if(qstate->env->cfg->serve_expired) {
/* if serving expired contents, and such content is
* already available, don't overwrite this servfail */
struct msgreply_entry* msg;
if((msg=msg_cache_lookup(qstate->env,
qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass,
qstate->query_flags, 0, 0))
!= NULL) {
lock_rw_unlock(&msg->entry.lock);
return error_response(qstate, id, rcode);
}
/* serving expired contents, but nothing is cached
* at all, so the servfail cache entry is useful
* (stops waste of time on this servfail NORR_TTL) */
}
memset(&err, 0, sizeof(err));
err.flags = (uint16_t)(BIT_QR | BIT_RA);
FLAGS_SET_RCODE(err.flags, rcode);
@@ -388,29 +372,6 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
return 1;
}
/**
* Find rrset in ANSWER prepend list.
* to avoid duplicate DNAMEs when a DNAME is traversed twice.
* @param iq: iterator query state.
* @param rrset: rrset to add.
* @return false if not found
*/
static int
iter_find_rrset_in_prepend_answer(struct iter_qstate* iq,
struct ub_packed_rrset_key* rrset)
{
struct iter_prep_list* p = iq->an_prepend_list;
while(p) {
if(ub_rrset_compare(p->rrset, rrset) == 0 &&
rrsetdata_equal((struct packed_rrset_data*)p->rrset
->entry.data, (struct packed_rrset_data*)rrset
->entry.data))
return 1;
p = p->next;
}
return 0;
}
/**
* Add rrset to ANSWER prepend list
* @param qstate: query state.
@@ -493,16 +454,14 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
* by this DNAME following, so we don't process the DNAME
* directly. */
if(ntohs(r->rk.type) == LDNS_RR_TYPE_DNAME &&
dname_strict_subdomain_c(*mname, r->rk.dname) &&
!iter_find_rrset_in_prepend_answer(iq, r)) {
dname_strict_subdomain_c(*mname, r->rk.dname)) {
if(!iter_add_prepend_answer(qstate, iq, r))
return 0;
continue;
}
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(*mname, r->rk.dname) == 0 &&
!iter_find_rrset_in_prepend_answer(iq, r)) {
query_dname_compare(*mname, r->rk.dname) == 0) {
/* Add this relevant CNAME rrset to the prepend list.*/
if(!iter_add_prepend_answer(qstate, iq, r))
return 0;
@@ -525,33 +484,6 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
return 1;
}
/** 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)
{
struct delegpt* fwddp;
struct iter_hints_stub* stub;
int labs = dname_count_labels(nm);
/* do not process a last resort (the parent side) if a stub
* or forward is configured, because we do not want to go 'above'
* the configured servers */
if(!dname_is_root(nm) && (stub = (struct iter_hints_stub*)
name_tree_find(&env->hints->tree, nm, nmlen, labs, qclass)) &&
/* has_parent side is turned off for stub_first, where we
* are allowed to go to the parent */
stub->dp->has_parent_side_NS) {
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) {
return 0;
}
return 1;
}
/** see if target name is caps-for-id whitelisted */
static int
is_caps_whitelisted(struct iter_env* ie, struct iter_qstate* iq)
@@ -896,9 +828,6 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
if(iq->depth == ie->max_dependency_depth)
return;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
iq->qchase.qclass))
return;
/* is this query the same as the nscheck? */
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS &&
query_dname_compare(iq->dp->name, qstate->qinfo.qname)==0 &&
@@ -1071,20 +1000,6 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(iq, COLLECT_CLASS_STATE);
}
/*
* If we are restricted by a forward-zone or a stub-zone, we
* can't re-fetch glue for this delegation point.
* we wont try to re-fetch glue if the iq->dp is null.
*/
if (iq->refetch_glue &&
iq->dp &&
!can_have_last_resort(qstate->env,
iq->dp->name,
iq->dp->namelen,
iq->qchase.qclass)) {
iq->refetch_glue = 0;
}
/* Resolver Algorithm Step 1 -- Look for the answer in local data. */
/* This either results in a query restart (CNAME cache response), a
@@ -1411,7 +1326,7 @@ processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq,
/* If the RD flag wasn't set, then we just finish with the
* cached referral as the response. */
if(!(qstate->query_flags & BIT_RD) && iq->deleg_msg) {
if(!(qstate->query_flags & BIT_RD)) {
iq->response = iq->deleg_msg;
if(verbosity >= VERB_ALGO && iq->response)
log_dns_msg("no RD requested, using delegation msg",
@@ -1618,6 +1533,35 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 1;
}
/** see if last resort is possible - does config allow queries to parent */
static int
can_have_last_resort(struct module_env* env, struct delegpt* dp,
struct iter_qstate* iq)
{
struct delegpt* fwddp;
struct iter_hints_stub* stub;
/* do not process a last resort (the parent side) if a stub
* or forward is configured, because we do not want to go 'above'
* the configured servers */
if(!dname_is_root(dp->name) && (stub = (struct iter_hints_stub*)
name_tree_find(&env->hints->tree, dp->name, dp->namelen,
dp->namelabs, iq->qchase.qclass)) &&
/* has_parent side is turned off for stub_first, where we
* are allowed to go to the parent */
stub->dp->has_parent_side_NS) {
verbose(VERB_QUERY, "configured stub servers failed -- returning SERVFAIL");
return 0;
}
if((fwddp = forwards_find(env->fwds, dp->name, iq->qchase.qclass)) &&
/* has_parent_side is turned off for forward_first, where
* we are allowed to go to the parent */
fwddp->has_parent_side_NS) {
verbose(VERB_QUERY, "configured forward servers failed -- returning SERVFAIL");
return 0;
}
return 1;
}
/**
* Called by processQueryTargets when it would like extra targets to query
* but it seems to be out of options. At last resort some less appealing
@@ -1639,11 +1583,9 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_ALGO, "No more query targets, attempting last resort");
log_assert(iq->dp);
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
iq->qchase.qclass)) {
if(!can_have_last_resort(qstate->env, iq->dp, iq)) {
/* 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");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) {
@@ -1728,19 +1670,6 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
/* see if we can issue queries to get nameserver addresses */
/* this lookup is not randomized, but sequential. */
for(ns = iq->dp->nslist; ns; ns = ns->next) {
/* if this nameserver is at a delegation point, but that
* delegation point is a stub and we cannot go higher, skip*/
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)) {
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
"because it is also a stub/forward,",
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
if(ie->supports_ipv6) ns->done_pside6 = 1;
if(ie->supports_ipv4) ns->done_pside4 = 1;
continue;
}
/* query for parent-side A and AAAA for nameservers */
if(ie->supports_ipv6 && !ns->done_pside6) {
/* Send the AAAA request. */
@@ -2240,10 +2169,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
int dnsseclame = 0;
enum response_type type;
iq->num_current_queries--;
if(!inplace_cb_query_response_call(qstate->env, qstate, iq->response))
log_err("unable to call query_response callback");
if(iq->response == NULL) {
/* Don't increment qname when QNAME minimisation is enabled */
if(qstate->env->cfg->qname_minimisation)
@@ -2308,22 +2233,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
} else
iter_scrub_ds(iq->response, ns, iq->dp->name);
} else iter_scrub_ds(iq->response, NULL, NULL);
if(type == RESPONSE_TYPE_THROWAWAY &&
FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_YXDOMAIN) {
/* YXDOMAIN is a permanent error, no need to retry */
type = RESPONSE_TYPE_ANSWER;
}
if(type == RESPONSE_TYPE_CNAME && iq->response->rep->an_numrrsets >= 1
&& ntohs(iq->response->rep->rrsets[0]->rk.type) == LDNS_RR_TYPE_DNAME) {
uint8_t* sname = NULL;
size_t snamelen = 0;
get_cname_target(iq->response->rep->rrsets[0], &sname,
&snamelen);
if(snamelen && dname_subdomain_c(sname, iq->response->rep->rrsets[0]->rk.dname)) {
/* DNAME to a subdomain loop; do not recurse */
type = RESPONSE_TYPE_ANSWER;
}
}
/* handle each of the type cases */
if(type == RESPONSE_TYPE_ANSWER) {
@@ -3252,10 +3161,6 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
/* like packet got dropped */
goto handle_it;
}
if(!inplace_cb_edns_back_parsed_call(qstate->env, qstate)) {
log_err("unable to call edns_back_parsed callback");
goto handle_it;
}
}
/* remove CD-bit, we asked for in case we handle validation ourself */
+2 -2
View File
@@ -51,7 +51,7 @@ struct iter_forwards;
struct iter_donotq;
struct iter_prep_list;
struct iter_priv;
struct rbtree_type;
struct rbtree_t;
/** max number of targets spawned for a query and its subqueries */
#define MAX_TARGET_COUNT 64
@@ -115,7 +115,7 @@ struct iter_env {
struct iter_priv* priv;
/** whitelist for capsforid names */
struct rbtree_type* caps_white;
struct rbtree_t* caps_white;
/** The maximum dependency depth that this resolver will pursue. */
int max_dependency_depth;
+1 -1
View File
@@ -127,7 +127,7 @@ find_id(struct ub_ctx* ctx, int* id)
struct ctx_query*
context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
ub_callback_type cb, void* cbarg)
ub_callback_t cb, void* cbarg)
{
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
if(!q) return NULL;
+8 -8
View File
@@ -61,17 +61,17 @@ struct ub_event_base;
struct ub_ctx {
/* --- pipes --- */
/** mutex on query write pipe */
lock_basic_type qqpipe_lock;
lock_basic_t qqpipe_lock;
/** the query write pipe */
struct tube* qq_pipe;
/** mutex on result read pipe */
lock_basic_type rrpipe_lock;
lock_basic_t rrpipe_lock;
/** the result read pipe */
struct tube* rr_pipe;
/* --- shared data --- */
/** mutex for access to env.cfg, finalized and dothread */
lock_basic_type cfglock;
lock_basic_t cfglock;
/**
* The context has been finalized
* This is after config when the first resolve is done.
@@ -84,7 +84,7 @@ struct ub_ctx {
/** pid of bg worker process */
pid_t bg_pid;
/** tid of bg worker thread */
ub_thread_type bg_tid;
ub_thread_t bg_tid;
/** do threading (instead of forking) for async resolution */
int dothread;
@@ -129,7 +129,7 @@ struct ub_ctx {
* Used to see if querynum is free for use.
* Content of type ctx_query.
*/
rbtree_type queries;
rbtree_t queries;
};
/**
@@ -140,7 +140,7 @@ struct ub_ctx {
*/
struct ctx_query {
/** node in rbtree, must be first entry, key is ptr to the querynum */
struct rbnode_type node;
struct rbnode_t node;
/** query id number, key for node */
int querynum;
/** was this an async query? */
@@ -149,7 +149,7 @@ struct ctx_query {
int cancelled;
/** for async query, the callback function */
ub_callback_type cb;
ub_callback_t cb;
/** for async query, the callback user arg */
void* cb_arg;
@@ -242,7 +242,7 @@ void context_query_delete(struct ctx_query* q);
* @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_t cb, void* cbarg);
/**
* Get a new alloc. Creates a new one or uses a cached one.
+8 -8
View File
@@ -215,7 +215,7 @@ ub_ctx_create_event(struct event_base* eb)
/** delete q */
static void
delq(rbnode_type* n, void* ATTR_UNUSED(arg))
delq(rbnode_t* n, void* ATTR_UNUSED(arg))
{
struct ctx_query* q = (struct ctx_query*)n;
context_query_delete(q);
@@ -310,6 +310,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
inplace_cb_lists_delete(ctx->env);
free(ctx->env);
}
ub_randfree(ctx->seed_rnd);
@@ -499,7 +500,7 @@ ub_fd(struct ub_ctx* ctx)
/** process answer from bg worker */
static int
process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
ub_callback_type* cb, void** cbarg, int* err,
ub_callback_t* cb, void** cbarg, int* err,
struct ub_result** res)
{
struct ctx_query* q;
@@ -566,7 +567,7 @@ static int
process_answer(struct ub_ctx* ctx, uint8_t* msg, uint32_t len)
{
int err;
ub_callback_type cb;
ub_callback_t cb;
void* cbarg;
struct ub_result* res;
int r;
@@ -609,7 +610,7 @@ int
ub_wait(struct ub_ctx* ctx)
{
int err;
ub_callback_type cb;
ub_callback_t cb;
void* cbarg;
struct ub_result* res;
int r;
@@ -705,8 +706,7 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
int
ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_event_callback_type callback,
int* async_id)
int rrclass, void* mydata, ub_event_callback_t callback, int* async_id)
{
struct ctx_query* q;
int r;
@@ -734,7 +734,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
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,
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
mydata);
if(!q)
return UB_NOMEM;
@@ -748,7 +748,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
int
ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_callback_type callback, int* async_id)
int rrclass, void* mydata, ub_callback_t callback, int* async_id)
{
struct ctx_query* q;
uint8_t* msg = NULL;
+1 -1
View File
@@ -639,7 +639,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
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_t cb = (ub_event_callback_t)q->cb;
void* cb_arg = q->cb_arg;
int cancelled = q->cancelled;
+2 -3
View File
@@ -170,7 +170,7 @@ struct ub_event {
struct ub_event_vmt* vmt;
};
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*);
typedef void (*ub_event_callback_t)(void*, int, void*, int, int, char*);
/**
* Create a resolving and validation context.
@@ -254,8 +254,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
* @return 0 if OK, else error.
*/
int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_event_callback_type callback,
int* async_id);
int rrclass, void* mydata, ub_event_callback_t callback, int* async_id);
#ifdef __cplusplus
}
+2 -163
View File
@@ -223,7 +223,7 @@ struct ub_result {
* This structure is allocated on the heap and needs to be
* freed with ub_resolve_free(result);
*/
typedef void (*ub_callback_type)(void*, int, struct ub_result*);
typedef void (*ub_callback_t)(void*, int, struct ub_result*);
/**
* Create a resolving and validation context.
@@ -519,7 +519,7 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
* @return 0 if OK, else error.
*/
int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_callback_type callback, int* async_id);
int rrclass, void* mydata, ub_callback_t callback, int* async_id);
/**
* Cancel an async query in progress.
@@ -601,167 +601,6 @@ int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data);
*/
const char* ub_version(void);
/**
* Some global statistics that are not in struct stats_info,
* this struct is shared on a shm segment (shm-key in unbound.conf)
*/
struct ub_shm_stat_info {
int num_threads;
struct {
long long now_sec, now_usec;
long long up_sec, up_usec;
long long elapsed_sec, elapsed_usec;
} time;
struct {
long long msg;
long long rrset;
long long val;
long long iter;
long long subnet;
long long ipsecmod;
long long respip;
} mem;
};
/** number of qtype that is stored for in array */
#define UB_STATS_QTYPE_NUM 256
/** number of qclass that is stored for in array */
#define UB_STATS_QCLASS_NUM 256
/** number of rcodes in stats */
#define UB_STATS_RCODE_NUM 16
/** number of opcodes in stats */
#define UB_STATS_OPCODE_NUM 16
/** number of histogram buckets */
#define UB_STATS_BUCKET_NUM 40
/** per worker statistics. */
struct ub_server_stats {
/** number of queries from clients received. */
long long num_queries;
/** number of queries that have been dropped/ratelimited by ip. */
long long num_queries_ip_ratelimited;
/** number of queries that had a cache-miss. */
long long num_queries_missed_cache;
/** number of prefetch queries - cachehits with prefetch */
long long num_queries_prefetch;
/**
* Sum of the querylistsize of the worker for
* every query that missed cache. To calculate average.
*/
long long sum_query_list_size;
/** max value of query list size reached. */
long long max_query_list_size;
/** Extended stats below (bool) */
int extended;
/** qtype stats */
long long qtype[UB_STATS_QTYPE_NUM];
/** bigger qtype values not in array */
long long qtype_big;
/** qclass stats */
long long qclass[UB_STATS_QCLASS_NUM];
/** bigger qclass values not in array */
long long qclass_big;
/** query opcodes */
long long qopcode[UB_STATS_OPCODE_NUM];
/** number of queries over TCP */
long long qtcp;
/** number of outgoing queries over TCP */
long long qtcp_outgoing;
/** number of queries over IPv6 */
long long qipv6;
/** number of queries with QR bit */
long long qbit_QR;
/** number of queries with AA bit */
long long qbit_AA;
/** number of queries with TC bit */
long long qbit_TC;
/** number of queries with RD bit */
long long qbit_RD;
/** number of queries with RA bit */
long long qbit_RA;
/** number of queries with Z bit */
long long qbit_Z;
/** number of queries with AD bit */
long long qbit_AD;
/** number of queries with CD bit */
long long qbit_CD;
/** number of queries with EDNS OPT record */
long long qEDNS;
/** number of queries with EDNS with DO flag */
long long qEDNS_DO;
/** answer rcodes */
long long ans_rcode[UB_STATS_RCODE_NUM];
/** answers with pseudo rcode 'nodata' */
long long ans_rcode_nodata;
/** answers that were secure (AD) */
long long ans_secure;
/** answers that were bogus (withheld as SERVFAIL) */
long long ans_bogus;
/** rrsets marked bogus by validator */
long long rrset_bogus;
/** unwanted traffic received on server-facing ports */
long long unwanted_replies;
/** unwanted traffic received on client-facing ports */
long long unwanted_queries;
/** usage of tcp accept list */
long long tcp_accept_usage;
/** answers served from expired cache */
long long zero_ttl_responses;
/** histogram data exported to array
* if the array is the same size, no data is lost, and
* if all histograms are same size (is so by default) then
* adding up works well. */
long long hist[UB_STATS_BUCKET_NUM];
/** number of message cache entries */
long long msg_cache_count;
/** number of rrset cache entries */
long long rrset_cache_count;
/** number of infra cache entries */
long long infra_cache_count;
/** number of key cache entries */
long long key_cache_count;
/** number of queries that used dnscrypt */
long long num_query_dnscrypt_crypted;
/** number of queries that queried dnscrypt certificates */
long long num_query_dnscrypt_cert;
/** number of queries in clear text and not asking for the certificates */
long long num_query_dnscrypt_cleartext;
/** number of malformed encrypted queries */
long long num_query_dnscrypt_crypted_malformed;
};
/**
* Statistics to send over the control pipe when asked
* This struct is made to be memcpied, sent in binary.
* shm mapped with (number+1) at num_threads+1, with first as total
*/
struct ub_stats_info {
/** the thread stats */
struct ub_server_stats svr;
/** mesh stats: current number of states */
long long mesh_num_states;
/** mesh stats: current number of reply (user) states */
long long mesh_num_reply_states;
/** mesh stats: number of reply states overwritten with a new one */
long long mesh_jostled;
/** mesh stats: number of incoming queries dropped */
long long mesh_dropped;
/** mesh stats: replies sent */
long long mesh_replies_sent;
/** mesh stats: sum of waiting times for the replies */
long long mesh_replies_sum_wait_sec, mesh_replies_sum_wait_usec;
/** mesh stats: median of waiting times for replies (in sec) */
double mesh_time_median;
};
#ifdef __cplusplus
}
#endif
+8 -24
View File
@@ -55,7 +55,7 @@ Generate a distribution tar file for unbound.
Detected from svn working copy if not specified.
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
-w32 32bit windows compile.
-w64 64bit windows compile.
-w ... Build windows binary dist. last args passed to configure.
EOF
exit 1
@@ -178,7 +178,7 @@ storehash () {
SNAPSHOT="no"
RC="no"
DOWIN="no"
W64="yes"
W64="no"
WINSSL=""
WINEXPAT=""
@@ -203,8 +203,9 @@ while [ "$1" ]; do
WINEXPAT="$2"
shift
;;
"-w32")
W64="no"
"-w64")
W64="yes"
shift
;;
"-w")
DOWIN="yes"
@@ -323,20 +324,9 @@ if [ "$DOWIN" = "yes" ]; then
# procedure for making unbound installer on mingw.
info "Creating windows dist unbound $version"
info "Calling configure"
if test "$W64" = "no"; then
file_flag="--with-conf-file=C:\Program Files (x86)\Unbound\service.conf"
file2_flag="--with-rootkey-file=C:\Program Files (x86)\Unbound\root.key"
file3_flag="--with-rootcert-file=C:\Program Files (x86)\Unbound\icannbundle.pem"
version="$version"-w32
fi
echo "$configure"' --enable-debug --enable-static-exe --disable-flto '"$* $cross_flag "$file_flag" "$file2_flag" "$file3_flag""
if test "$W64" = "no"; then
$configure --enable-debug --enable-static-exe --disable-flto $* $cross_flag "$file_flag" "$file2_flag" "$file3_flag" \
echo "$configure"' --enable-debug --enable-static-exe --disable-flto '"$* $cross_flag"
$configure --enable-debug --enable-static-exe --disable-flto $* $cross_flag \
|| error_cleanup "Could not configure"
else
$configure --enable-debug --enable-static-exe --disable-flto $* $cross_flag \
|| error_cleanup "Could not configure"
fi
info "Calling make"
make || error_cleanup "Could not make"
info "Make complete"
@@ -345,7 +335,6 @@ if [ "$DOWIN" = "yes" ]; then
file="unbound-$version.zip"
rm -f $file
info "Creating $file"
grep '^". IN DS' smallapp/unbound-anchor.c | sed -e 's/"//' -e 's/\\n.*$//' > root.key
mkdir tmp.$$
# keep debug symbols
#$strip unbound.exe
@@ -357,21 +346,16 @@ if [ "$DOWIN" = "yes" ]; then
#$strip unbound-service-install.exe
#$strip unbound-service-remove.exe
cd tmp.$$
cp ../root.key .
cp ../doc/example.conf ../doc/Changelog .
cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-control-setup.cmd ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt ../contrib/create_unbound_ad_servers.cmd ../contrib/warmup.cmd ../contrib/unbound_cache.cmd .
# zipfile
zip ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog
zip ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog
info "Testing $file"
(cd .. ; zip -T $file )
# installer
info "Creating installer"
quadversion=`cat ../config.h | grep RSRC_PACKAGE_VERSION | sed -e 's/#define RSRC_PACKAGE_VERSION //' -e 's/,/\\./g'`
cat ../winrc/setup.nsi | sed -e 's/define VERSION.*$/define VERSION "'$version'"/' -e 's/define QUADVERSION.*$/define QUADVERSION "'$quadversion'"/' > ../winrc/setup_ed.nsi
if test "$W64" = "yes"; then
mv ../winrc/setup_ed.nsi ../winrc/setup_ed_old.nsi
cat ../winrc/setup_ed_old.nsi | sed -e 's/PROGRAMFILES/PROGRAMFILES64/' > ../winrc/setup_ed.nsi
fi
"$makensis" ../winrc/setup_ed.nsi
info "Created installer"
cd ..
+4 -4
View File
@@ -63,7 +63,7 @@ We can register such function as:
.. code-block:: python
if not register_inplace_cb_reply(inplace_reply_callback, env, id):
if not register_inplace_cb_reply(inplace_reply_callback, env):
log_info("python: Could not register inplace callback function.")
@@ -99,7 +99,7 @@ We can register such function as:
.. code-block:: python
if not register_inplace_cb_reply_cache(inplace_cache_callback, env, id):
if not register_inplace_cb_reply_cache(inplace_cache_callback, env):
log_info("python: Could not register inplace callback function.")
@@ -135,7 +135,7 @@ We can register such function as:
.. code-block:: python
if not register_inplace_cb_reply_local(inplace_local_callback, env, id):
if not register_inplace_cb_reply_local(inplace_local_callback, env):
log_info("python: Could not register inplace callback function.")
@@ -172,7 +172,7 @@ We can register such function as:
.. code-block:: python
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env, id):
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env):
log_info("python: Could not register inplace callback function.")
+8 -8
View File
@@ -46,22 +46,22 @@
# (unbound needs to be validating for this example to work)
# Useful functions:
# register_inplace_cb_reply(inplace_reply_callback, env, id):
# register_inplace_cb_reply(inplace_reply_callback, env):
# Register the reply_callback function as an inplace callback function
# when answering with a resolved query.
# Return True on success, False on failure.
#
# register_inplace_cb_reply_cache(inplace_reply_cache_callback, env, id):
# register_inplace_cb_reply_cache(inplace_reply_cache_callback, env):
# Register the reply_cache_callback function as an inplace callback
# function when answering from cache.
# Return True on success, False on failure.
#
# register_inplace_cb_reply_local(inplace_reply_local_callback, env, id):
# register_inplace_cb_reply_local(inplace_reply_local_callback, env):
# Register the reply_local_callback function as an inplace callback
# function when answering from local data or chaos reply.
# Return True on success, False on failure.
#
# register_inplace_cb_reply_servfail(inplace_reply_servfail_callback, env, id):
# register_inplace_cb_reply_servfail(inplace_reply_servfail_callback, env):
# Register the reply_servfail_callback function as an inplace callback
# function when answering with servfail.
# Return True on success, False on failure.
@@ -193,22 +193,22 @@ def init_standard(id, env):
# Register the inplace_reply_callback function as an inplace callback
# function when answering a resolved query.
if not register_inplace_cb_reply(inplace_reply_callback, env, id):
if not register_inplace_cb_reply(inplace_reply_callback, env):
return False
# Register the inplace_cache_callback function as an inplace callback
# function when answering from cache.
if not register_inplace_cb_reply_cache(inplace_cache_callback, env, id):
if not register_inplace_cb_reply_cache(inplace_cache_callback, env):
return False
# Register the inplace_local_callback function as an inplace callback
# function when answering from local data.
if not register_inplace_cb_reply_local(inplace_local_callback, env, id):
if not register_inplace_cb_reply_local(inplace_local_callback, env):
return False
# Register the inplace_servfail_callback function as an inplace callback
# function when answering with SERVFAIL.
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env, id):
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env):
return False
return True
+148 -160
View File
@@ -4,7 +4,7 @@
%module unboundmodule
%{
/**
* \file
* \file
* This is the interface between the unbound server and a python module
* called to perform operations on queries.
*/
@@ -58,7 +58,7 @@
}
%}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure query_info
* ************************************************************************************ */
/* Query info */
@@ -76,24 +76,24 @@ struct query_info {
};
%inline %{
enum enum_rr_class {
enum enum_rr_class {
RR_CLASS_IN = 1,
RR_CLASS_CH = 3,
RR_CLASS_HS = 4,
RR_CLASS_NONE = 254,
RR_CLASS_ANY = 255,
};
enum enum_rr_type {
RR_TYPE_A = 1,
RR_TYPE_NS = 2,
RR_TYPE_MD = 3,
RR_TYPE_MF = 4,
RR_TYPE_CNAME = 5,
RR_TYPE_SOA = 6,
RR_TYPE_MB = 7,
RR_TYPE_MG = 8,
RR_TYPE_MR = 9,
RR_TYPE_A = 1,
RR_TYPE_NS = 2,
RR_TYPE_MD = 3,
RR_TYPE_MF = 4,
RR_TYPE_CNAME = 5,
RR_TYPE_SOA = 6,
RR_TYPE_MB = 7,
RR_TYPE_MG = 8,
RR_TYPE_MR = 9,
RR_TYPE_NULL = 10,
RR_TYPE_WKS = 11,
RR_TYPE_PTR = 12,
@@ -131,7 +131,7 @@ struct query_info {
RR_TYPE_SSHFP = 44,
RR_TYPE_IPSECKEY = 45,
RR_TYPE_RRSIG = 46,
RR_TYPE_NSEC = 47,
RR_TYPE_NSEC = 47,
RR_TYPE_DNSKEY = 48,
RR_TYPE_DHCID = 49,
RR_TYPE_NSEC3 = 50,
@@ -151,7 +151,7 @@ struct query_info {
PyObject* _get_qname(struct query_info* q) {
return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len);
}
}
PyObject* _get_qname_components(struct query_info* q) {
return GetNameAsLabelList((const char*)q->qname, q->qname_len);
@@ -179,7 +179,7 @@ struct query_info {
__swig_getmethods__["qname"] = _unboundmodule._get_qname
if _newclass:qname = _swig_property(_unboundmodule._get_qname)
__swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components
if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components)
@@ -189,7 +189,7 @@ struct query_info {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure packed_rrset_key
* ************************************************************************************ */
%ignore packed_rrset_key::dname;
@@ -200,7 +200,7 @@ struct packed_rrset_key {
%immutable;
char* dname;
size_t dname_len;
uint32_t flags;
uint32_t flags;
uint16_t type; /* rrset type in network format */
uint16_t rrset_class; /* rrset class in network format */
%mutable;
@@ -216,7 +216,7 @@ uint16_t ntohs(uint16_t netshort);
%inline %{
PyObject* _get_dname(struct packed_rrset_key* k) {
return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len);
}
}
PyObject* _get_dname_components(struct packed_rrset_key* k) {
return GetNameAsLabelList((char*)k->dname, k->dname_len);
}
@@ -244,24 +244,24 @@ uint16_t ntohs(uint16_t netshort);
%}
}
#if defined(SWIGWORDSIZE64)
typedef long int rrset_id_type;
#else
typedef long long int rrset_id_type;
#endif
#if defined(SWIGWORDSIZE64)
typedef long int rrset_id_t;
#else
typedef long long int rrset_id_t;
#endif
struct ub_packed_rrset_key {
struct lruhash_entry entry;
rrset_id_type id;
rrset_id_t id;
struct packed_rrset_key rk;
};
struct lruhash_entry {
lock_rw_type lock;
lock_rw_t lock;
struct lruhash_entry* overflow_next;
struct lruhash_entry* lru_next;
struct lruhash_entry* lru_prev;
hashvalue_type hash;
hashvalue_t hash;
void* key;
struct packed_rrset_data* data;
};
@@ -279,7 +279,7 @@ struct packed_rrset_data {
/* number of rrsigs */
size_t rrsig_count;
enum rrset_trust trust;
enum rrset_trust trust;
enum sec_status security;
/* length of every rr's rdata */
@@ -309,26 +309,26 @@ struct packed_rrset_data {
%inline %{
PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
return PyInt_FromLong(d->rr_len[idx]);
return Py_None;
}
void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
{
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
d->rr_ttl[idx] = ttl;
}
PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
return PyInt_FromLong(d->rr_ttl[idx]);
return Py_None;
}
PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
if ((d != NULL) && (idx >= 0) &&
((size_t)idx < (d->count+d->rrsig_count)))
return PyBytes_FromStringAndSize((char*)d->rr_data[idx],
d->rr_len[idx]);
return Py_None;
@@ -349,7 +349,7 @@ struct packed_rrset_data {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure reply_info
* ************************************************************************************ */
/* Messages */
@@ -376,7 +376,7 @@ struct reply_info {
struct rrset_ref {
struct ub_packed_rrset_key* key;
rrset_id_type id;
rrset_id_t id;
};
struct dns_msg {
@@ -426,7 +426,7 @@ struct dns_msg {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure mesh_state
* ************************************************************************************ */
struct mesh_state {
@@ -439,7 +439,7 @@ struct mesh_reply {
};
struct comm_reply {
};
%inline %{
@@ -489,7 +489,7 @@ struct comm_reply {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure edns_option
* ************************************************************************************ */
/* Rename the members to follow the python convention of marking them as
@@ -500,10 +500,10 @@ struct comm_reply {
%rename(_opt_len) edns_option::opt_len;
%rename(_opt_data) edns_option::opt_data;
struct edns_option {
struct edns_option* next;
uint16_t opt_code;
size_t opt_len;
uint8_t* opt_data;
struct edns_option* next;
uint16_t opt_code;
size_t opt_len;
uint8_t* opt_data;
};
%inline %{
@@ -513,7 +513,7 @@ struct edns_option {
}
PyObject* _edns_option_opt_data_get(struct edns_option* option) {
return PyByteArray_FromStringAndSize((void*)option->opt_data,
return PyByteArray_FromStringAndSize((uint8_t*)option->opt_data,
option->opt_len);
}
%}
@@ -529,7 +529,7 @@ struct edns_option {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure edns_data
* ************************************************************************************ */
/* This is ignored because we will pass a double pointer of this to Python
@@ -537,12 +537,12 @@ struct edns_option {
* pointers as None. */
%ignore edns_data::opt_list;
struct edns_data {
int edns_present;
uint8_t ext_rcode;
uint8_t edns_version;
uint16_t bits;
uint16_t udp_size;
struct edns_option* opt_list;
int edns_present;
uint8_t ext_rcode;
uint8_t edns_version;
uint16_t bits;
uint16_t udp_size;
struct edns_option* opt_list;
};
%inline %{
struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) {
@@ -564,48 +564,49 @@ struct edns_data {
Structure module_env
* ************************************************************************************ */
struct module_env {
struct config_file* cfg;
struct slabhash* msg_cache;
struct rrset_cache* rrset_cache;
struct infra_cache* infra_cache;
struct key_cache* key_cache;
struct config_file* cfg;
struct slabhash* msg_cache;
struct rrset_cache* rrset_cache;
struct infra_cache* infra_cache;
struct key_cache* key_cache;
/* --- services --- */
struct outbound_entry* (*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);
void (*detach_subs)(struct module_qstate* qstate);
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
void (*kill_sub)(struct module_qstate* newq);
int (*detect_cycle)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t flags, int prime,
int valrec);
/* --- services --- */
struct outbound_entry* (*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);
void (*detach_subs)(struct module_qstate* qstate);
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
void (*kill_sub)(struct module_qstate* newq);
int (*detect_cycle)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t flags, int prime,
int valrec);
struct regional* scratch;
struct sldns_buffer* scratch_buffer;
struct worker* worker;
struct mesh_area* mesh;
struct alloc_cache* alloc;
struct ub_randstate* rnd;
time_t* now;
struct timeval* now_tv;
int need_to_validate;
struct val_anchors* anchors;
struct val_neg_cache* neg_cache;
struct comm_timer* probe_timer;
struct iter_forwards* fwds;
struct iter_hints* hints;
void* modinfo[MAX_MODULE];
struct regional* scratch;
struct sldns_buffer* scratch_buffer;
struct worker* worker;
struct mesh_area* mesh;
struct alloc_cache* alloc;
struct ub_randstate* rnd;
time_t* now;
struct timeval* now_tv;
int need_to_validate;
struct val_anchors* anchors;
struct val_neg_cache* neg_cache;
struct comm_timer* probe_timer;
struct iter_forwards* fwds;
struct iter_hints* hints;
void* modinfo[MAX_MODULE];
void* inplace_cb_lists[inplace_cb_types_total];
struct edns_known_option* edns_known_options;
size_t edns_known_options_num;
void* inplace_cb_lists[inplace_cb_types_total];
struct edns_known_option* edns_known_options;
size_t edns_known_options_num;
};
/* ************************************************************************************ *
Structure module_qstate
* ************************************************************************************ */
@@ -709,14 +710,14 @@ struct module_qstate {
enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
return q->ext_state[idx];
}
}
return 0;
}
void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
q->ext_state[idx] = state;
}
}
}
int edns_opt_list_is_empty(struct edns_option** opt) {
@@ -788,7 +789,7 @@ struct module_qstate {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure config_strlist
* ************************************************************************************ */
struct config_strlist {
@@ -796,7 +797,7 @@ struct config_strlist {
char* str;
};
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure config_str2list
* ************************************************************************************ */
struct config_str2list {
@@ -805,7 +806,7 @@ struct config_str2list {
char* str2;
};
/* ************************************************************************************ *
/* ************************************************************************************ *
Structure config_file
* ************************************************************************************ */
struct config_file {
@@ -872,7 +873,7 @@ struct config_file {
struct config_strlist* dlv_anchor_list;
int max_ttl;
int32_t val_date_override;
int bogus_ttl;
int bogus_ttl;
int val_clean_additional;
int val_permissive_mode;
char* val_nsec3_key_iterations;
@@ -893,7 +894,7 @@ struct config_file {
char* python_script;
};
/* ************************************************************************************ *
/* ************************************************************************************ *
ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation
* ************************************************************************************ */
struct delegpt_ns {
@@ -931,7 +932,7 @@ struct delegpt {
%inline %{
PyObject* _get_dp_dname(struct delegpt* dp) {
return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen);
}
}
PyObject* _get_dp_dname_components(struct delegpt* dp) {
return GetNameAsLabelList((char*)dp->name, dp->namelen);
}
@@ -986,7 +987,7 @@ struct delegpt {
%}
}
/* ************************************************************************************ *
/* ************************************************************************************ *
Enums
* ************************************************************************************ */
%rename ("MODULE_STATE_INITIAL") "module_state_initial";
@@ -1039,26 +1040,6 @@ enum verbosity_value {
VERB_ALGO
};
enum inplace_cb_list_type {
/* Inplace callbacks for when a resolved reply is ready to be sent to the
* front.*/
inplace_cb_reply = 0,
/* Inplace callbacks for when a reply is given from the cache. */
inplace_cb_reply_cache,
/* Inplace callbacks for when a reply is given with local data
* (or Chaos reply). */
inplace_cb_reply_local,
/* Inplace callbacks for when the reply is servfail. */
inplace_cb_reply_servfail,
/* Inplace callbacks for when a query is ready to be sent to the back.*/
inplace_cb_query,
/* Inplace callback for when a reply is received from the back. */
inplace_cb_edns_back_parsed,
/* Total number of types. Used for array initialization.
* Should always be last. */
inplace_cb_types_total
};
%constant uint16_t PKT_QR = 1; /* QueRy - query flag */
%constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */
%constant uint16_t PKT_TC = 4; /* TrunCated - server flag */
@@ -1068,17 +1049,17 @@ enum inplace_cb_list_type {
%constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */
%{
int checkList(PyObject *l)
int checkList(PyObject *l)
{
PyObject* item;
int i;
if (l == Py_None)
if (l == Py_None)
return 1;
if (PyList_Check(l))
if (PyList_Check(l))
{
for (i=0; i < PyList_Size(l); i++)
for (i=0; i < PyList_Size(l); i++)
{
item = PyList_GetItem(l, i);
if (!PyBytes_Check(item))
@@ -1097,7 +1078,7 @@ int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
int i;
size_t len;
for (i=0; i < PyList_Size(l); i++)
for (i=0; i < PyList_Size(l); i++)
{
item = PyList_GetItem(l, i);
@@ -1121,9 +1102,9 @@ int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
return 1;
}
int set_return_msg(struct module_qstate* qstate,
int set_return_msg(struct module_qstate* qstate,
const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
{
sldns_buffer *qb = 0;
int res = 1;
@@ -1135,7 +1116,7 @@ int set_return_msg(struct module_qstate* qstate,
uint16_t PKT_CD = 16;
uint16_t PKT_RA = 32;
uint16_t PKT_AD = 64;
if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
return 0;
if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0;
@@ -1184,7 +1165,7 @@ int set_return_msg(struct module_qstate* qstate,
}
%}
int set_return_msg(struct module_qstate* qstate,
int set_return_msg(struct module_qstate* qstate,
const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
@@ -1204,17 +1185,17 @@ int set_return_msg(struct module_qstate* qstate,
def set_return_msg(self, qstate):
"""Returns 1 if OK"""
status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
self.query_flags, self.default_ttl,
self.question, self.answer, self.authority, self.additional)
if (status) and (PKT_AA & self.query_flags):
qstate.return_msg.rep.authoritative = 1
return status
return status
%}
/* ************************************************************************************ *
/* ************************************************************************************ *
ASN: Delegation pointer related functions
* ************************************************************************************ */
@@ -1273,7 +1254,7 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
}
%}
/* ************************************************************************************ *
/* ************************************************************************************ *
Functions
* ************************************************************************************ */
/******************************
@@ -1351,7 +1332,7 @@ int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!");
return NULL;
}
$2 = (void*)PyByteArray_AsString($input);
$2 = PyByteArray_AsString($input);
$1 = PyByteArray_Size($input);
}
@@ -1365,15 +1346,15 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
int python_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct regional* region, int id, void* python_callback)
struct regional* region, void* python_callback)
{
PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
PyObject *py_rep, *py_region;
PyObject *result;
int res = 0;
PyGILState_STATE gstate = PyGILState_Ensure();
func = (PyObject *) python_callback;
PyGILState_STATE gstate = PyGILState_Ensure();
py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
py_qstate = SWIG_NewPointerObj((void*) qstate,
SWIGTYPE_p_module_qstate, 0);
@@ -1398,49 +1379,56 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
return res;
}
/* register a callback */
static int python_inplace_cb_register(enum inplace_cb_list_type type,
PyObject* py_cb, struct module_env* env, int id)
/* Swig implementations for Python */
static int register_inplace_cb_reply(PyObject* py_cb,
struct module_env* env)
{
int ret = inplace_cb_register(python_inplace_cb_reply_generic,
type, (void*) py_cb, env, id);
int ret = inplace_cb_reply_register(
python_inplace_cb_reply_generic, (void*) py_cb, env);
if (ret) Py_INCREF(py_cb);
return ret;
}
/* Swig implementations for Python */
static int register_inplace_cb_reply(PyObject* py_cb,
struct module_env* env, int id)
{
return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id);
}
static int register_inplace_cb_reply_cache(PyObject* py_cb,
struct module_env* env, int id)
struct module_env* env)
{
return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id);
int ret = inplace_cb_reply_cache_register(
python_inplace_cb_reply_generic, (void*) py_cb, env);
if (ret) Py_INCREF(py_cb);
return ret;
}
static int register_inplace_cb_reply_local(PyObject* py_cb,
struct module_env* env, int id)
struct module_env* env)
{
return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id);
int ret = inplace_cb_reply_local_register(
python_inplace_cb_reply_generic, (void*) py_cb, env);
if (ret) Py_INCREF(py_cb);
return ret;
}
static int register_inplace_cb_reply_servfail(PyObject* py_cb,
struct module_env* env, int id)
struct module_env* env)
{
return python_inplace_cb_register(inplace_cb_reply_servfail,
py_cb, env, id);
int ret = inplace_cb_reply_servfail_register(
python_inplace_cb_reply_generic, (void*) py_cb, env);
if (ret) Py_INCREF(py_cb);
return ret;
}
%}
/* C declarations */
int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
struct module_env* env, int id);
int inplace_cb_reply_register(
inplace_cb_reply_func_t* cb, void* cb_arg, struct module_env* env);
int inplace_cb_reply_cache_register(
inplace_cb_reply_func_t* cb, void* cb_arg, struct module_env* env);
int inplace_cb_reply_local_register(
inplace_cb_reply_func_t* cb, void* cb_arg, struct module_env* env);
int inplace_cb_reply_servfail_register(
inplace_cb_reply_func_t* cb, void* cb_arg, struct module_env* env);
/* Swig declarations */
static int register_inplace_cb_reply(PyObject* py_cb,
struct module_env* env, int id);
struct module_env* env);
static int register_inplace_cb_reply_cache(PyObject* py_cb,
struct module_env* env, int id);
struct module_env* env);
static int register_inplace_cb_reply_local(PyObject* py_cb,
struct module_env* env, int id);
struct module_env* env);
static int register_inplace_cb_reply_servfail(PyObject* py_cb,
struct module_env* env, int id);
struct module_env* env);
+34 -36
View File
@@ -1,22 +1,22 @@
/*
* pythonmod.c: unbound module C wrapper
*
*
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
*
* This software is open source.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* * Neither the name of the organization nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
@@ -41,10 +41,8 @@
/* ignore the varargs unused warning from SWIGs internal vararg support */
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-parameter"
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
#endif
#include "config.h"
#include "sldns/sbuffer.h"
@@ -65,7 +63,7 @@ typedef void* PyGILState_STATE;
#endif
/**
* Global state for the module.
* Global state for the module.
*/
struct pythonmod_env {
@@ -119,7 +117,7 @@ int pythonmod_init(struct module_env* env, int id)
int init_standard = 1;
struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env));
if (!pe)
if (!pe)
{
log_err("pythonmod: malloc failure");
return 0;
@@ -135,7 +133,7 @@ int pythonmod_init(struct module_env* env, int id)
}
/* Initialize Python libraries */
if (!Py_IsInitialized())
if (!Py_IsInitialized())
{
#if PY_MAJOR_VERSION >= 3
wchar_t progname[8];
@@ -171,13 +169,13 @@ int pythonmod_init(struct module_env* env, int id)
PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n");
if (PyRun_SimpleString("from unboundmodule import *\n") < 0)
{
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
PyGILState_Release(gil);
return 0;
}
/* Check Python file load */
if ((script_py = fopen(pe->fname, "r")) == NULL)
if ((script_py = fopen(pe->fname, "r")) == NULL)
{
log_err("pythonmod: can't open file %s for reading", pe->fname);
PyGILState_Release(gil);
@@ -192,8 +190,8 @@ int pythonmod_init(struct module_env* env, int id)
PyModule_AddObject(pe->module, "mod_env", pe->data);
/* TODO: deallocation of pe->... if an error occurs */
if (PyRun_SimpleFile(script_py, pe->fname) < 0)
if (PyRun_SimpleFile(script_py, pe->fname) < 0)
{
log_err("pythonmod: can't parse Python script %s", pe->fname);
PyGILState_Release(gil);
@@ -205,26 +203,26 @@ int pythonmod_init(struct module_env* env, int id)
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL)
{
init_standard = 0;
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
{
log_err("pythonmod: function init is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
}
}
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
{
log_err("pythonmod: function deinit is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
}
if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL)
if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL)
{
log_err("pythonmod: function operate is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
}
if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL)
if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL)
{
log_err("pythonmod: function inform_super is missing in %s", pe->fname);
PyGILState_Release(gil);
@@ -241,7 +239,7 @@ int pythonmod_init(struct module_env* env, int id)
SWIGTYPE_p_config_file, 0);
}
res = PyObject_CallFunction(pe->func_init, "iO", id, py_init_arg);
if (PyErr_Occurred())
if (PyErr_Occurred())
{
log_err("pythonmod: Exception occurred in function init");
PyErr_Print();
@@ -306,20 +304,20 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_
py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
py_sqstate = SWIG_NewPointerObj((void*) super, SWIGTYPE_p_module_qstate, 0);
res = PyObject_CallFunction(pe->func_inform, "iOOO", id, py_qstate,
res = PyObject_CallFunction(pe->func_inform, "iOOO", id, py_qstate,
py_sqstate, pq->data);
if (PyErr_Occurred())
if (PyErr_Occurred())
{
log_err("pythonmod: Exception occurred in function inform_super");
PyErr_Print();
qstate->ext_state[id] = module_error;
}
else if ((res == NULL) || (!PyObject_IsTrue(res)))
}
else if ((res == NULL) || (!PyObject_IsTrue(res)))
{
log_err("pythonmod: python returned bad code in inform_super");
qstate->ext_state[id] = module_error;
}
}
Py_XDECREF(res);
Py_XDECREF(py_sqstate);
@@ -328,7 +326,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_
PyGILState_Release(gil);
}
void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* ATTR_UNUSED(outbound))
{
struct pythonmod_env* pe = (struct pythonmod_env*)qstate->env->modinfo[id];
@@ -337,10 +335,10 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
PyGILState_STATE gil = PyGILState_Ensure();
if ( pq == NULL)
{
{
/* create qstate */
pq = qstate->minfo[id] = malloc(sizeof(struct pythonmod_qstate));
/* Initialize per query data */
pq->data = Py_None;
Py_INCREF(pq->data);
@@ -348,19 +346,19 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
/* Call operate */
py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
res = PyObject_CallFunction(pe->func_operate, "iiOO", id, (int) event,
res = PyObject_CallFunction(pe->func_operate, "iiOO", id, (int) event,
py_qstate, pq->data);
if (PyErr_Occurred())
if (PyErr_Occurred())
{
log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event));
PyErr_Print();
qstate->ext_state[id] = module_error;
}
else if ((res == NULL) || (!PyObject_IsTrue(res)))
}
else if ((res == NULL) || (!PyObject_IsTrue(res)))
{
log_err("pythonmod: python returned bad code, event: %s", strmodulevent(event));
qstate->ext_state[id] = module_error;
}
}
Py_XDECREF(res);
Py_XDECREF(py_qstate);
@@ -374,7 +372,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id)
return;
pq = (struct pythonmod_qstate*)qstate->minfo[id];
verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id,
verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id,
(unsigned long int)pq);
if(pq != NULL)
{
@@ -391,7 +389,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id)
size_t pythonmod_get_mem(struct module_env* env, int id)
{
struct pythonmod_env* pe = (struct pythonmod_env*)env->modinfo[id];
verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id,
verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id,
(unsigned long int)pe);
if(!pe)
return 0;
@@ -399,11 +397,11 @@ size_t pythonmod_get_mem(struct module_env* env, int id)
}
/**
* The module function block
* The module function block
*/
static struct module_func_block pythonmod_block = {
"python",
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
&pythonmod_clear, &pythonmod_get_mem
};
+1 -1
View File
@@ -72,5 +72,5 @@ size_t pythonmod_get_mem(struct module_env* env, int id);
int python_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct regional* region, int id, void* python_callback);
struct regional* region, void* python_callback);
#endif /* PYTHONMOD_H */
+1 -1
View File
@@ -74,7 +74,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
/* Invalidate the message associated with query_info stored in message cache */
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo)
{
hashvalue_type h;
hashvalue_t h;
struct lruhash_entry* e;
struct reply_info *r;
size_t i, j;
-1180
View File
File diff suppressed because it is too large Load Diff
-230
View File
@@ -1,230 +0,0 @@
/*
* respip/respip.h - IP-based response modification module
*/
/**
* \file
*
* This file contains a module that selectively modifies query responses
* based on their AAAA/A IP addresses.
*/
#ifndef RESPIP_RESPIP_H
#define RESPIP_RESPIP_H
#include "util/module.h"
#include "services/localzone.h"
/**
* Set of response IP addresses with associated actions and tags.
* Forward declaration only here. Actual definition is hidden within the
* module.
*/
struct respip_set;
/**
* Forward declaration for the structure that represents a node in the
* respip_set address tree
*/
struct resp_addr;
/**
* Forward declaration for the structure that represents a tree of view data.
*/
struct views;
struct respip_addr_info;
/**
* Client-specific attributes that can affect IP-based actions.
* This is essentially a subset of acl_addr (except for respip_set) but
* defined as a separate structure to avoid dependency on the daemon-specific
* structure.
* respip_set is supposed to refer to the response-ip set for the global view.
*/
struct respip_client_info {
uint8_t* taglist;
size_t taglen;
uint8_t* tag_actions;
size_t tag_actions_size;
struct config_strlist** tag_datas;
size_t tag_datas_size;
struct view* view;
struct respip_set* respip_set;
};
/**
* Data items representing the result of response-ip processing.
* Note: this structure currently only define a few members, but exists
* as a separate struct mainly for the convenience of custom extensions.
*/
struct respip_action_info {
enum respip_action action;
struct respip_addr_info* addrinfo; /* set only for inform variants */
};
/**
* Forward declaration for the structure that represents a node in the
* respip_set address tree
*/
struct resp_addr;
/**
* Create response IP set.
* @return new struct or NULL on error.
*/
struct respip_set* respip_set_create(void);
/**
* Delete response IP set.
* @param set: to delete.
*/
void respip_set_delete(struct respip_set* set);
/**
* Apply response-ip config settings to the global (default) view.
* It assumes exclusive access to set (no internal locks).
* @param set: processed global respip config data
* @param cfg: config data.
* @return 1 on success, 0 on error.
*/
int respip_global_apply_cfg(struct respip_set* set, struct config_file* cfg);
/**
* Apply response-ip config settings in named views.
* @param vs: view structures with processed config data
* @param cfg: config data.
* @param have_view_respip_cfg: set to true if any named view has respip
* configuration; otherwise set to false
* @return 1 on success, 0 on error.
*/
int respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
int* have_view_respip_cfg);
/**
* Merge two replies to build a complete CNAME chain.
* It appends the content of 'tgt_rep' to 'base_rep', assuming (but not
* checking) the former ends with a CNAME and the latter resolves its target.
* A merged new reply will be built using 'region' and *new_repp will point
* to the new one on success.
* If the target reply would also be subject to a response-ip action for
* 'cinfo', this function uses 'base_rep' as the merged reply, ignoring
* 'tgt_rep'. This is for avoiding cases like a CNAME loop or failure of
* applying an action to an address.
* RRSIGs in 'tgt_rep' will be excluded in the merged reply, as the resulting
* reply is assumed to be faked due to a response-ip action and can't be
* considered secure in terms of DNSSEC.
* The caller must ensure that neither 'base_rep' nor 'tgt_rep' can be modified
* until this function returns.
* @param base_rep: the reply info containing an incomplete CNAME.
* @param qinfo: query info corresponding to 'base_rep'.
* @param tgt_rep: the reply info that completes the CNAME chain.
* @param cinfo: client info corresponding to 'base_rep'.
* @param must_validate: whether 'tgt_rep' must be DNSSEC-validated.
* @param new_repp: pointer placeholder for the merged reply. will be intact
* on error.
* @param region: allocator to build *new_repp.
* @return 1 on success, 0 on error.
*/
int respip_merge_cname(struct reply_info* base_rep,
const struct query_info* qinfo, const struct reply_info* tgt_rep,
const struct respip_client_info* cinfo, int must_validate,
struct reply_info** new_repp, struct regional* region);
/**
* See if any IP-based action should apply to any IP address of AAAA/A answer
* record in the reply. If so, apply the action. In some cases it rewrites
* the reply rrsets, in which case *new_repp will point to the updated reply
* info. Depending on the action, some of the rrsets in 'rep' will be
* shallow-copied into '*new_repp'; the caller must ensure that the rrsets
* in 'rep' are valid throughout the lifetime of *new_repp, and it must
* provide appropriate mutex if the rrsets can be shared by multiple threads.
* @param qinfo: query info corresponding to the reply.
* @param cinfo: client-specific info to identify the best matching action.
* can be NULL.
* @param rep: original reply info. must not be NULL.
* @param new_repp: can be set to the rewritten reply info (intact on failure).
* @param actinfo: result of response-ip processing
* @param alias_rrset: must not be NULL.
* @param search_only: if true, only check if an action would apply. actionp
* will be set (or intact) accordingly but the modified reply won't be built.
* @param region: allocator to build *new_repp.
* @return 1 on success, 0 on error.
*/
int respip_rewrite_reply(const struct query_info* qinfo,
const struct respip_client_info* cinfo,
const struct reply_info *rep, struct reply_info** new_repp,
struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset,
int search_only, struct regional* region);
/**
* Get the response-ip function block.
* @return: function block with function pointers to response-ip methods.
*/
struct module_func_block* respip_get_funcblock(void);
/** response-ip init */
int respip_init(struct module_env* env, int id);
/** response-ip deinit */
void respip_deinit(struct module_env* env, int id);
/** response-ip operate on a query */
void respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound);
/** inform response-ip super */
void respip_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** response-ip cleanup query state */
void respip_clear(struct module_qstate* qstate, int id);
/**
* returns address of the IP address tree of the specified respip set;
* returns NULL for NULL input; exists for test purposes only
*/
struct rbtree_type* respip_set_get_tree(struct respip_set* set);
/**
* returns respip action for the specified node in the respip address
* returns respip_none for NULL input; exists for test purposes only
*/
enum respip_action resp_addr_get_action(const struct resp_addr* addr);
/**
* returns rrset portion of the specified node in the respip address
* tree; returns NULL for NULL input; exists for test purposes only
*/
struct ub_packed_rrset_key* resp_addr_get_rrset(struct resp_addr* addr);
/** response-ip alloc size routine */
size_t respip_get_mem(struct module_env* env, int id);
/**
* respip set emptiness test
* @param set respip set to test
* @return 0 if the specified set exists (non-NULL) and is non-empty;
* otherwise returns 1
*/
int respip_set_is_empty(const struct respip_set* set);
/**
* print log information for a query subject to an inform or inform-deny
* response-ip action.
* @param respip_addr: response-ip information that causes the action
* @param qname: query name in the context, will be ignored if local_alias is
* non-NULL.
* @param qtype: query type, in host byte order.
* @param qclass: query class, in host byte order.
* @param local_alias: set to a local alias if the query matches an alias in
* a local zone. In this case its owner name will be considered the actual
* query name.
* @param repinfo: reply info containing the client's source address and port.
*/
void respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
struct comm_reply* repinfo);
#endif /* RESPIP_RESPIP_H */
-2369
View File
File diff suppressed because it is too large Load Diff
-209
View File
@@ -1,209 +0,0 @@
/*
* services/authzone.h - authoritative zone that is locally hosted.
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains the functions for an authority zone. This zone
* is queried by the iterator, just like a stub or forward zone, but then
* the data is locally held.
*/
#ifndef SERVICES_AUTHZONE_H
#define SERVICES_AUTHZONE_H
#include "util/rbtree.h"
#include "util/locks.h"
struct ub_packed_rrset_key;
struct regional;
struct config_file;
struct query_info;
struct dns_msg;
/**
* Authoritative zones, shared.
*/
struct auth_zones {
/** lock on the authzone tree */
lock_rw_type lock;
/** rbtree of struct auth_zone */
rbtree_type ztree;
};
/**
* Auth zone. Authoritative data, that is fetched from instead of sending
* packets to the internet.
*/
struct auth_zone {
/** rbtree node, key is name and class */
rbnode_type node;
/** zone name, in uncompressed wireformat */
uint8_t* name;
/** length of zone name */
size_t namelen;
/** number of labels in zone name */
int namelabs;
/** the class of this zone, in host byteorder.
* uses 'dclass' to not conflict with c++ keyword class. */
uint16_t dclass;
/** lock on the data in the structure
* For the node, parent, name, namelen, namelabs, dclass, you
* need to also hold the zones_tree lock to change them (or to
* delete this zone) */
lock_rw_type lock;
/** auth data for this zone
* rbtree of struct auth_data */
rbtree_type data;
/* zonefile name (or NULL for no zonefile) */
char* zonefile;
/* fallback to the internet on failure or ttl-expiry of auth zone */
int fallback_enabled;
};
/**
* Auth data. One domain name, and the RRs to go with it.
*/
struct auth_data {
/** rbtree node, key is name only */
rbnode_type node;
/** domain name */
uint8_t* name;
/** length of name */
size_t namelen;
/** number of labels in name */
int namelabs;
/** the data rrsets, with different types, linked list.
* if the list if NULL the node would be an empty non-terminal,
* but in this data structure such nodes that represent an empty
* non-terminal are not needed; they just don't exist.
*/
struct auth_rrset* rrsets;
};
/**
* A auth data RRset
*/
struct auth_rrset {
/** next in list */
struct auth_rrset* next;
/** RR type in host byteorder */
uint16_t type;
/** RRset data item */
struct packed_rrset_data* data;
};
/**
* Create auth zones structure
*/
struct auth_zones* auth_zones_create(void);
/**
* Apply configuration to auth zones. Reads zonefiles.
*/
int auth_zones_apply_config(struct auth_zones* az, struct config_file* cfg);
/**
* Delete auth zones structure
*/
void auth_zones_delete(struct auth_zones* az);
/**
* Write auth zone data to file, in zonefile format.
*/
int auth_zone_write_file(struct auth_zone* z, const char* fname);
/**
* Use auth zones to lookup the answer to a query.
* The query is from the iterator. And the auth zones attempts to provide
* the answer instead of going to the internet.
*
* @param az: auth zones structure.
* @param qinfo: query info to lookup.
* @param region: region to use to allocate the reply in.
* @param msg: reply is stored here (if one).
* @param fallback: if true, fallback to making a query to the internet.
* @param dp_nm: name of delegation point to look for. This zone is used
* to answer the query.
* If the dp_nm is not found, fallback is set to true and false returned.
* @param dp_nmlen: length of dp_nm.
* @return 0: failure (an error of some sort, like servfail).
* if 0 and fallback is true, fallback to the internet.
* if 0 and fallback is false, like getting servfail.
* If true, an answer is available.
*/
int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
struct regional* region, struct dns_msg** msg, int* fallback,
uint8_t* dp_nm, size_t dp_nmlen);
/**
* Find the auth zone that is above the given qname.
* Return NULL when there is no auth_zone above the give name, otherwise
* returns the closest auth_zone above the qname that pertains to it.
* @param az: auth zones structure.
* @param qinfo: query info to lookup.
* @return NULL or auth_zone that pertains to the query.
*/
struct auth_zone* auth_zones_find_zone(struct auth_zones* az,
struct query_info* qinfo);
/** find an auth zone by name (exact match by name or NULL returned) */
struct auth_zone* auth_zone_find(struct auth_zones* az, uint8_t* nm,
size_t nmlen, uint16_t dclass);
/** create an auth zone. returns wrlocked zone. caller must have wrlock
* on az. returns NULL on malloc failure */
struct auth_zone* auth_zone_create(struct auth_zones* az, uint8_t* nm,
size_t nmlen, uint16_t dclass);
/** set auth zone zonefile string. caller must have lock on zone */
int auth_zone_set_zonefile(struct auth_zone* z, char* zonefile);
/** set auth zone fallback. caller must have lock on zone.
* fallbackstr is "yes" or "no". false on parse failure. */
int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
/** read auth zone from zonefile. caller must lock zone. false on failure */
int auth_zone_read_zonefile(struct auth_zone* z);
/** compare auth_zones for sorted rbtree */
int auth_zone_cmp(const void* z1, const void* z2);
/** compare auth_data for sorted rbtree */
int auth_data_cmp(const void* z1, const void* z2);
#endif /* SERVICES_AUTHZONE_H */
+12 -21
View File
@@ -41,7 +41,6 @@
#include "config.h"
#include "iterator/iter_delegpt.h"
#include "validator/val_nsec.h"
#include "validator/val_utils.h"
#include "services/cache/dns.h"
#include "services/cache/rrset.h"
#include "util/data/msgreply.h"
@@ -107,7 +106,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
void
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
hashvalue_t hash, struct reply_info* rep, time_t leeway, int pside,
struct reply_info* qrep, struct regional* region)
{
struct msgreply_entry* e;
@@ -183,13 +182,13 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
}
/** lookup message in message cache */
struct msgreply_entry*
static struct msgreply_entry*
msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr)
{
struct lruhash_entry* e;
struct query_info k;
hashvalue_type h;
hashvalue_t h;
k.qname = qname;
k.qname_len = qnamelen;
@@ -480,7 +479,8 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
return msg;
}
struct dns_msg*
/** generate dns_msg from cached message */
static struct dns_msg*
tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
struct regional* region, time_t now, struct regional* scratch)
{
@@ -525,11 +525,8 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
return NULL;
}
}
if(env)
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
r->rrset_count);
else
rrset_array_unlock(r->ref, r->rrset_count);
return msg;
}
@@ -712,7 +709,7 @@ dns_cache_lookup(struct module_env* env,
{
struct lruhash_entry* e;
struct query_info k;
hashvalue_type h;
hashvalue_t h;
time_t now = *env->now;
struct ub_packed_rrset_key* rrset;
@@ -756,16 +753,10 @@ dns_cache_lookup(struct module_env* env,
if( qtype != LDNS_RR_TYPE_DS &&
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) {
uint8_t* wc = NULL;
/* if the rrset is not a wildcard expansion, with wcname */
/* because, if we return that CNAME rrset on its own, it is
* missing the NSEC or NSEC3 proof */
if(!(val_rrset_wildcard(rrset, &wc) && wc != NULL)) {
struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
if(msg) {
lock_rw_unlock(&rrset->entry.lock);
return msg;
}
struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
if(msg) {
lock_rw_unlock(&rrset->entry.lock);
return msg;
}
lock_rw_unlock(&rrset->entry.lock);
}
@@ -874,7 +865,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
} else {
/* store msg, and rrsets */
struct query_info qinf;
hashvalue_type h;
hashvalue_t h;
qinf = *msgqinf;
qinf.qname = memdup(msgqinf->qname, msgqinf->qname_len);
+1 -21
View File
@@ -106,7 +106,7 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
* @param region: to allocate into for qmsg.
*/
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
hashvalue_t hash, struct reply_info* rep, time_t leeway, int pside,
struct reply_info* qrep, struct regional* region);
/**
@@ -126,20 +126,6 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct regional* region, struct dns_msg** msg, time_t timenow);
/**
* generate dns_msg from cached message
* @param env: module environment with the DNS cache. NULL if the LRU from cache
* does not need to be touched.
* @param q: query info, contains qname that will make up the dns message.
* @param r: reply info that, together with qname, will make up the dns message.
* @param region: where to allocate dns message.
* @param now: the time now, for check if TTL on cache entry is ok.
* @param scratch: where to allocate temporary data.
* */
struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
struct reply_info* r, struct regional* region, time_t now,
struct regional* scratch);
/**
* Find cached message
* @param env: module environment with the DNS cache.
@@ -208,10 +194,4 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region,
int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
time_t adjust, uint16_t flags);
/** lookup message in message cache
* the returned nonNULL entry is locked and has to be unlocked by the caller */
struct msgreply_entry* msg_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
uint16_t flags, time_t now, int wr);
#endif /* SERVICES_CACHE_DNS_H */
+11 -132
View File
@@ -61,10 +61,6 @@
/** ratelimit value for delegation point */
int infra_dp_ratelimit = 0;
/** ratelimit value for client ip addresses,
* in queries per second. */
int infra_ip_ratelimit = 0;
size_t
infra_sizefunc(void* k, void* ATTR_UNUSED(d))
{
@@ -248,19 +244,11 @@ infra_create(struct config_file* cfg)
}
name_tree_init_parents(&infra->domain_limits);
}
infra_ip_ratelimit = cfg->ip_ratelimit;
infra->client_ip_rates = slabhash_create(cfg->ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
if(!infra->client_ip_rates) {
infra_delete(infra);
return NULL;
}
return infra;
}
/** delete domain_limit entries */
static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg))
static void domain_limit_free(rbnode_t* n, void* ATTR_UNUSED(arg))
{
if(n) {
free(((struct domain_limit_data*)n)->node.name);
@@ -276,7 +264,6 @@ infra_delete(struct infra_cache* infra)
slabhash_delete(infra->hosts);
slabhash_delete(infra->domain_rates);
traverse_postorder(&infra->domain_limits, domain_limit_free, NULL);
slabhash_delete(infra->client_ip_rates);
free(infra);
}
@@ -297,38 +284,31 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
return infra;
}
/** calculate the hash value for a host key
* set use_port to a non-0 number to use the port in
* the hash calculation; 0 to ignore the port.*/
static hashvalue_type
hash_addr(struct sockaddr_storage* addr, socklen_t addrlen,
int use_port)
/** calculate the hash value for a host key */
static hashvalue_t
hash_addr(struct sockaddr_storage* addr, socklen_t addrlen)
{
hashvalue_type h = 0xab;
hashvalue_t h = 0xab;
/* select the pieces to hash, some OS have changing data inside */
if(addr_is_ip6(addr, addrlen)) {
struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
h = hashlittle(&in6->sin6_family, sizeof(in6->sin6_family), h);
if(use_port){
h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
}
h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
h = hashlittle(&in6->sin6_addr, INET6_SIZE, h);
} else {
struct sockaddr_in* in = (struct sockaddr_in*)addr;
h = hashlittle(&in->sin_family, sizeof(in->sin_family), h);
if(use_port){
h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
}
h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
h = hashlittle(&in->sin_addr, INET_SIZE, h);
}
return h;
}
/** calculate infra hash for a key */
static hashvalue_type
static hashvalue_t
hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name)
{
return dname_query_hash(name, hash_addr(addr, addrlen, 1));
return dname_query_hash(name, hash_addr(addr, addrlen));
}
/** lookup version that does not check host ttl (you check it) */
@@ -746,36 +726,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
return infra_dp_ratelimit;
}
size_t ip_rate_sizefunc(void* k, void* ATTR_UNUSED(d))
{
struct ip_rate_key* key = (struct ip_rate_key*)k;
return sizeof(*key) + sizeof(struct ip_rate_data)
+ lock_get_mem(&key->entry.lock);
}
int ip_rate_compfunc(void* key1, void* key2)
{
struct ip_rate_key* k1 = (struct ip_rate_key*)key1;
struct ip_rate_key* k2 = (struct ip_rate_key*)key2;
return sockaddr_cmp_addr(&k1->addr, k1->addrlen,
&k2->addr, k2->addrlen);
}
void ip_rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
{
struct ip_rate_key* key = (struct ip_rate_key*)k;
if(!key)
return;
lock_rw_destroy(&key->entry.lock);
free(key);
}
/** find data item in array, for write access, caller unlocks */
static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
uint8_t* name, size_t namelen, int wr)
{
struct rate_key key;
hashvalue_type h = dname_query_hash(name, 0xab);
hashvalue_t h = dname_query_hash(name, 0xab);
memset(&key, 0, sizeof(key));
key.name = name;
key.namelen = namelen;
@@ -783,25 +739,11 @@ static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
return slabhash_lookup(infra->domain_rates, h, &key, wr);
}
/** find data item in array for ip addresses */
struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
struct comm_reply* repinfo, int wr)
{
struct ip_rate_key key;
hashvalue_type h = hash_addr(&(repinfo->addr),
repinfo->addrlen, 0);
memset(&key, 0, sizeof(key));
key.addr = repinfo->addr;
key.addrlen = repinfo->addrlen;
key.entry.hash = h;
return slabhash_lookup(infra->client_ip_rates, h, &key, wr);
}
/** create rate data item for name, number 1 in now */
static void infra_create_ratedata(struct infra_cache* infra,
uint8_t* name, size_t namelen, time_t timenow)
{
hashvalue_type h = dname_query_hash(name, 0xab);
hashvalue_t h = dname_query_hash(name, 0xab);
struct rate_key* k = (struct rate_key*)calloc(1, sizeof(*k));
struct rate_data* d = (struct rate_data*)calloc(1, sizeof(*d));
if(!k || !d) {
@@ -825,30 +767,6 @@ static void infra_create_ratedata(struct infra_cache* infra,
slabhash_insert(infra->domain_rates, h, &k->entry, d, NULL);
}
/** create rate data item for ip address */
static void infra_ip_create_ratedata(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow)
{
hashvalue_type h = hash_addr(&(repinfo->addr),
repinfo->addrlen, 0);
struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k));
struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d));
if(!k || !d) {
free(k);
free(d);
return; /* alloc failure */
}
k->addr = repinfo->addr;
k->addrlen = repinfo->addrlen;
lock_rw_init(&k->entry.lock);
k->entry.hash = h;
k->entry.key = k;
k->entry.data = d;
d->qps[0] = 1;
d->timestamp[0] = timenow;
slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
}
/** find the second and return its rate counter, if none, remove oldest */
static int* infra_rate_find_second(void* data, time_t t)
{
@@ -893,8 +811,6 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
/* find ratelimit */
lim = infra_find_ratelimit(infra, name, namelen);
if(!lim)
return 1; /* disabled for this domain */
/* find or insert ratedata */
entry = infra_find_ratedata(infra, name, namelen, 1);
@@ -943,8 +859,6 @@ int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
/* find ratelimit */
lim = infra_find_ratelimit(infra, name, namelen);
if(!lim)
return 0; /* disabled for this domain */
/* find current rate */
entry = infra_find_ratedata(infra, name, namelen, 0);
@@ -961,41 +875,6 @@ infra_get_mem(struct infra_cache* infra)
{
size_t s = sizeof(*infra) + slabhash_get_mem(infra->hosts);
if(infra->domain_rates) s += slabhash_get_mem(infra->domain_rates);
if(infra->client_ip_rates) s += slabhash_get_mem(infra->client_ip_rates);
/* ignore domain_limits because walk through tree is big */
return s;
}
int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow)
{
int max;
struct lruhash_entry* entry;
/* not enabled */
if(!infra_ip_ratelimit) {
return 1;
}
/* find or insert ratedata */
entry = infra_find_ip_ratedata(infra, repinfo, 1);
if(entry) {
int premax = infra_rate_max(entry->data, timenow);
int* cur = infra_rate_find_second(entry->data, timenow);
(*cur)++;
max = infra_rate_max(entry->data, timenow);
lock_rw_unlock(&entry->lock);
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
char client_ip[128];
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
repinfo->addrlen, client_ip, sizeof(client_ip));
verbose(VERB_OPS, "ratelimit exceeded %s %d", client_ip,
infra_ip_ratelimit);
}
return (max <= infra_ip_ratelimit);
}
/* create */
infra_ip_create_ratedata(infra, repinfo, timenow);
return 1;
}
+3 -49
View File
@@ -36,10 +36,7 @@
/**
* \file
*
* This file contains the infrastructure cache, as well as rate limiting.
* Note that there are two sorts of rate-limiting here:
* - Pre-cache, per-query rate limiting (query ratelimits)
* - Post-cache, per-domain name rate limiting (infra-ratelimits)
* This file contains the infrastructure cache.
*/
#ifndef SERVICES_CACHE_INFRA_H
@@ -47,8 +44,6 @@
#include "util/storage/lruhash.h"
#include "util/storage/dnstree.h"
#include "util/rtt.h"
#include "util/netevent.h"
#include "util/data/msgreply.h"
struct slabhash;
struct config_file;
@@ -117,9 +112,7 @@ struct infra_cache {
/** hash table with query rates per name: rate_key, rate_data */
struct slabhash* domain_rates;
/** ratelimit settings for domains, struct domain_limit_data */
rbtree_type domain_limits;
/** hash table with query rates per client ip: ip_rate_key, ip_rate_data */
struct slabhash* client_ip_rates;
rbtree_t domain_limits;
};
/** ratelimit, unless overridden by domain_limits, 0 is off */
@@ -149,21 +142,6 @@ struct rate_key {
size_t namelen;
};
/** ip ratelimit, 0 is off */
extern int infra_ip_ratelimit;
/**
* key for ip_ratelimit lookups, a source IP.
*/
struct ip_rate_key {
/** lruhash key entry */
struct lruhash_entry entry;
/** client ip information */
struct sockaddr_storage addr;
/** length of address */
socklen_t addrlen;
};
/** number of seconds to track qps rate */
#define RATE_WINDOW 2
@@ -182,8 +160,6 @@ struct rate_data {
time_t timestamp[RATE_WINDOW];
};
#define ip_rate_data rate_data
/** infra host cache default hash lookup size */
#define INFRA_HOST_STARTSIZE 32
/** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */
@@ -401,20 +377,10 @@ int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
/** find the maximum rate stored, not too old. 0 if no information. */
int infra_rate_max(void* data, time_t now);
/** find the ratelimit in qps for a domain. 0 if no limit for domain. */
/** find the ratelimit in qps for a domain */
int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
size_t namelen);
/** Update query ratelimit hash and decide
* whether or not a query should be dropped.
* @param infra: infra cache
* @param repinfo: information about client
* @param timenow: what time it is now.
* @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit and the query should be dropped. */
int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow);
/**
* Get memory used by the infra cache.
* @param infra: infrastructure cache.
@@ -447,16 +413,4 @@ void rate_delkeyfunc(void* k, void* arg);
/** delete data */
void rate_deldatafunc(void* d, void* arg);
/* calculate size for the client ip hashtable */
size_t ip_rate_sizefunc(void* k, void* d);
/* compare two addresses */
int ip_rate_compfunc(void* key1, void* key2);
/* delete key, and destroy the lock */
void ip_rate_delkeyfunc(void* d, void* arg);
/* delete data */
#define ip_rate_deldatafunc rate_deldatafunc
#endif /* SERVICES_CACHE_INFRA_H */
+5 -5
View File
@@ -91,7 +91,7 @@ struct rrset_cache* rrset_cache_adjust(struct rrset_cache *r,
void
rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
hashvalue_type hash, rrset_id_type id)
hashvalue_t hash, rrset_id_t id)
{
struct lruhash* table = slabhash_gettable(&r->table, hash);
/*
@@ -186,7 +186,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
{
struct lruhash_entry* e;
struct ub_packed_rrset_key* k = ref->key;
hashvalue_type h = k->entry.hash;
hashvalue_t h = k->entry.hash;
uint16_t rrset_type = ntohs(k->rk.type);
int equal = 0;
log_assert(ref->id != 0 && k->id != 0);
@@ -303,10 +303,10 @@ void
rrset_array_unlock_touch(struct rrset_cache* r, struct regional* scratch,
struct rrset_ref* ref, size_t count)
{
hashvalue_type* h;
hashvalue_t* h;
size_t i;
if(count > RR_COUNT_MAX || !(h = (hashvalue_type*)regional_alloc(
scratch, sizeof(hashvalue_type)*count))) {
if(count > RR_COUNT_MAX || !(h = (hashvalue_t*)regional_alloc(scratch,
sizeof(hashvalue_t)*count))) {
log_warn("rrset LRU: memory allocation failed");
h = NULL;
} else /* store hash values */
+1 -1
View File
@@ -102,7 +102,7 @@ struct rrset_cache* rrset_cache_adjust(struct rrset_cache* r,
* @param id: used to check that the item is unchanged and not deleted.
*/
void rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
hashvalue_type hash, rrset_id_type id);
hashvalue_t hash, rrset_id_t id);
/**
* Update an rrset in the rrset cache. Stores the information for later use.
+34 -211
View File
@@ -63,10 +63,6 @@
#include <sys/un.h>
#endif
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
/** number of queued TCP connections for listen() */
#define TCP_BACKLOG 256
@@ -100,71 +96,11 @@ verbose_print_addr(struct addrinfo *addr)
}
}
#ifdef HAVE_SYSTEMD
static int
systemd_get_activated(int family, int socktype, int listen,
struct sockaddr *addr, socklen_t addrlen,
const char *path)
{
int i = 0;
int r = 0;
int s = -1;
const char* listen_pid, *listen_fds;
/* We should use "listen" option only for stream protocols. For UDP it should be -1 */
if((r = sd_booted()) < 1) {
if(r == 0)
log_warn("systemd is not running");
else
log_err("systemd sd_booted(): %s", strerror(-r));
return -1;
}
listen_pid = getenv("LISTEN_PID");
listen_fds = getenv("LISTEN_FDS");
if (!listen_pid) {
log_warn("Systemd mandatory ENV variable is not defined: LISTEN_PID");
return -1;
}
if (!listen_fds) {
log_warn("Systemd mandatory ENV variable is not defined: LISTEN_FDS");
return -1;
}
if((r = sd_listen_fds(0)) < 1) {
if(r == 0)
log_warn("systemd: did not return socket, check unit configuration");
else
log_err("systemd sd_listen_fds(): %s", strerror(-r));
return -1;
}
for(i = 0; i < r; i++) {
if(sd_is_socket(SD_LISTEN_FDS_START + i, family, socktype, listen)) {
s = SD_LISTEN_FDS_START + i;
break;
}
}
if (s == -1) {
if (addr)
log_err_addr("systemd sd_listen_fds()",
"no such socket",
(struct sockaddr_storage *)addr, addrlen);
else
log_err("systemd sd_listen_fds(): %s", path);
}
return s;
}
#endif
int
create_udp_sock(int family, int socktype, struct sockaddr* addr,
socklen_t addrlen, int v6only, int* inuse, int* noproto,
int rcv, int snd, int listen, int* reuseport, int transparent,
int freebind, int use_systemd)
int freebind)
{
int s;
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND)
@@ -187,16 +123,6 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
#endif
#if !defined(IP_FREEBIND)
(void)freebind;
#endif
#ifdef HAVE_SYSTEMD
int got_fd_from_systemd = 0;
if (!use_systemd
|| (use_systemd
&& (s = systemd_get_activated(family, socktype, -1, addr,
addrlen, NULL)) == -1)) {
#else
(void)use_systemd;
#endif
if((s = socket(family, socktype, 0)) == -1) {
*inuse = 0;
@@ -218,11 +144,6 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
*noproto = 0;
return -1;
}
#ifdef HAVE_SYSTEMD
} else {
got_fd_from_systemd = 1;
}
#endif
if(listen) {
#ifdef SO_REUSEADDR
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
@@ -544,11 +465,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
}
# endif /* IPv4 MTU */
}
if(
#ifdef HAVE_SYSTEMD
!got_fd_from_systemd &&
#endif
bind(s, (struct sockaddr*)addr, addrlen) != 0) {
if(bind(s, (struct sockaddr*)addr, addrlen) != 0) {
*noproto = 0;
*inuse = 0;
#ifndef USE_WINSOCK
@@ -571,7 +488,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
(struct sockaddr_storage*)addr, addrlen);
}
closesocket(s);
#endif /* USE_WINSOCK */
#endif
return -1;
}
if(!fd_set_nonblock(s)) {
@@ -589,15 +506,12 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
int
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int freebind, int use_systemd)
int* reuseport, int transparent, int mss, int freebind)
{
int s;
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND)
int on = 1;
#endif
#ifdef HAVE_SYSTEMD
int got_fd_from_systemd = 0;
#endif
#ifdef USE_TCP_FASTOPEN
int qlen;
#endif
@@ -609,15 +523,6 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
#endif
verbose_print_addr(addr);
*noproto = 0;
#ifdef HAVE_SYSTEMD
if (!use_systemd ||
(use_systemd
&& (s = systemd_get_activated(addr->ai_family, addr->ai_socktype, 1,
addr->ai_addr, addr->ai_addrlen,
NULL)) == -1)) {
#else
(void)use_systemd;
#endif
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
#ifndef USE_WINSOCK
if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
@@ -655,11 +560,6 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
log_warn(" setsockopt(TCP_MAXSEG) unsupported");
#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
}
#ifdef HAVE_SYSTEMD
} else {
got_fd_from_systemd = 1;
}
#endif
#ifdef SO_REUSEADDR
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0) {
@@ -737,11 +637,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
(addr->ai_family==AF_INET6?"V6":""), strerror(errno));
}
#endif /* IP_TRANSPARENT || IP_BINDANY */
if(
#ifdef HAVE_SYSTEMD
!got_fd_from_systemd &&
#endif
bind(s, addr->ai_addr, addr->ai_addrlen) != 0) {
if(bind(s, addr->ai_addr, addr->ai_addrlen) != 0) {
#ifndef USE_WINSOCK
/* detect freebsd jail with no ipv6 permission */
if(addr->ai_family==AF_INET6 && errno==EINVAL)
@@ -799,21 +695,11 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
}
int
create_local_accept_sock(const char *path, int* noproto, int use_systemd)
create_local_accept_sock(const char *path, int* noproto)
{
#ifdef HAVE_SYSTEMD
int ret;
if (use_systemd && (ret = systemd_get_activated(AF_LOCAL, SOCK_STREAM, 1, NULL, 0, path)) != -1)
return ret;
else {
#endif
#ifdef HAVE_SYS_UN_H
int s;
struct sockaddr_un usock;
#ifndef HAVE_SYSTEMD
(void)use_systemd;
#endif
verbose(VERB_ALGO, "creating unix socket %s", path);
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
@@ -834,42 +720,29 @@ create_local_accept_sock(const char *path, int* noproto, int use_systemd)
/* The socket already exists and cannot be removed */
log_err("Cannot remove old local socket %s (%s)",
path, strerror(errno));
goto err;
return -1;
}
if (bind(s, (struct sockaddr *)&usock,
(socklen_t)sizeof(struct sockaddr_un)) == -1) {
log_err("Cannot bind local socket %s (%s)",
path, strerror(errno));
goto err;
return -1;
}
if (!fd_set_nonblock(s)) {
log_err("Cannot set non-blocking mode");
goto err;
return -1;
}
if (listen(s, TCP_BACKLOG) == -1) {
log_err("can't listen: %s", strerror(errno));
goto err;
return -1;
}
(void)noproto; /*unused*/
return s;
err:
#ifndef USE_WINSOCK
close(s);
#else
closesocket(s);
#endif
return -1;
#ifdef HAVE_SYSTEMD
}
#endif
#else
(void)use_systemd;
(void)path;
log_err("Local sockets are not supported");
*noproto = 1;
@@ -884,7 +757,7 @@ err:
static int
make_sock(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
int* reuseport, int transparent, int tcp_mss, int freebind)
{
struct addrinfo *res = NULL;
int r, s, inuse, noproto;
@@ -912,7 +785,7 @@ make_sock(int stype, const char* ifname, const char* port,
s = create_udp_sock(res->ai_family, res->ai_socktype,
(struct sockaddr*)res->ai_addr, res->ai_addrlen,
v6only, &inuse, &noproto, (int)rcv, (int)snd, 1,
reuseport, transparent, freebind, use_systemd);
reuseport, transparent, freebind);
if(s == -1 && inuse) {
log_err("bind: address already in use");
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
@@ -920,7 +793,7 @@ make_sock(int stype, const char* ifname, const char* port,
}
} else {
s = create_tcp_accept_sock(res, v6only, &noproto, reuseport,
transparent, tcp_mss, freebind, use_systemd);
transparent, tcp_mss, freebind);
if(s == -1 && noproto && hints->ai_family == AF_INET6){
*noip6 = 1;
}
@@ -933,7 +806,7 @@ make_sock(int stype, const char* ifname, const char* port,
static int
make_sock_port(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
int* reuseport, int transparent, int tcp_mss, int freebind)
{
char* s = strchr(ifname, '@');
if(s) {
@@ -955,10 +828,10 @@ make_sock_port(int stype, const char* ifname, const char* port,
(void)strlcpy(p, s+1, sizeof(p));
p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6,
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd);
rcv, snd, reuseport, transparent, tcp_mss, freebind);
}
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
reuseport, transparent, tcp_mss, freebind, use_systemd);
reuseport, transparent, tcp_mss, freebind);
}
/**
@@ -1008,7 +881,7 @@ set_recvpktinfo(int s, int family)
}
# else
log_err("no IPV6_RECVPKTINFO and no IPV6_PKTINFO option, please "
"disable interface-automatic or do-ip6 in config");
"disable interface-automatic in config");
return 0;
# endif /* defined IPV6_RECVPKTINFO */
@@ -1029,7 +902,7 @@ set_recvpktinfo(int s, int family)
}
# else
log_err("no IP_SENDSRCADDR or IP_PKTINFO option, please disable "
"interface-automatic or do-ip4 in config");
"interface-automatic in config");
return 0;
# endif /* IP_PKTINFO */
@@ -1055,32 +928,21 @@ set_recvpktinfo(int s, int family)
* @param transparent: set IP_TRANSPARENT socket option.
* @param tcp_mss: maximum segment size of tcp socket. default if zero.
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dnscrypt_port: dnscrypt service port number
* @return: returns false on error.
*/
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)
int tcp_mss, int freebind)
{
int s, noip6=0;
#ifdef USE_DNSCRYPT
int is_dnscrypt = ((strchr(ifname, '@') &&
atoi(strchr(ifname, '@')+1) == dnscrypt_port) ||
(!strchr(ifname, '@') && atoi(port) == dnscrypt_port));
#else
int is_dnscrypt = 0;
(void)dnscrypt_port;
#endif
if(!do_udp && !do_tcp)
return 0;
if(do_auto) {
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent,
tcp_mss, freebind, use_systemd)) == -1) {
tcp_mss, freebind)) == -1) {
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
@@ -1096,8 +958,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
#endif
return 0;
}
if(!port_insert(list, s,
is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil)) {
if(!port_insert(list, s, listen_type_udpancil)) {
#ifndef USE_WINSOCK
close(s);
#else
@@ -1109,15 +970,14 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
/* regular udp socket */
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent,
tcp_mss, freebind, use_systemd)) == -1) {
tcp_mss, freebind)) == -1) {
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
}
return 0;
}
if(!port_insert(list, s,
is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp)) {
if(!port_insert(list, s, listen_type_udp)) {
#ifndef USE_WINSOCK
close(s);
#else
@@ -1132,7 +992,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
(!strchr(ifname, '@') && atoi(port) == ssl_port));
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
&noip6, 0, 0, reuseport, transparent, tcp_mss,
freebind, use_systemd)) == -1) {
freebind)) == -1) {
if(noip6) {
/*log_warn("IPv6 protocol not available");*/
return 1;
@@ -1142,7 +1002,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
if(is_ssl)
verbose(VERB_ALGO, "setup TCP for SSL service");
if(!port_insert(list, s, is_ssl?listen_type_ssl:
(is_dnscrypt?listen_type_tcp_dnscrypt:listen_type_tcp))) {
listen_type_tcp)) {
#ifndef USE_WINSOCK
close(s);
#else
@@ -1176,7 +1036,7 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, void* sslctx,
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg)
struct dt_env* dtenv, comm_point_callback_t* cb, void *cb_arg)
{
struct listen_dnsport* front = (struct listen_dnsport*)
malloc(sizeof(struct listen_dnsport));
@@ -1184,9 +1044,6 @@ listen_create(struct comm_base* base, struct listen_port* ports,
return NULL;
front->cps = NULL;
front->udp_buff = sldns_buffer_new(bufsize);
#ifdef USE_DNSCRYPT
front->dnscrypt_udp_buff = NULL;
#endif
if(!front->udp_buff) {
free(front);
return NULL;
@@ -1195,20 +1052,17 @@ listen_create(struct comm_base* base, struct listen_port* ports,
/* create comm points as needed */
while(ports) {
struct comm_point* cp = NULL;
if(ports->ftype == listen_type_udp ||
ports->ftype == listen_type_udp_dnscrypt)
if(ports->ftype == listen_type_udp)
cp = comm_point_create_udp(base, ports->fd,
front->udp_buff, cb, cb_arg);
else if(ports->ftype == listen_type_tcp ||
ports->ftype == listen_type_tcp_dnscrypt)
else if(ports->ftype == listen_type_tcp)
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, bufsize, cb, cb_arg);
else if(ports->ftype == listen_type_ssl) {
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, bufsize, cb, cb_arg);
cp->ssl = sslctx;
} else if(ports->ftype == listen_type_udpancil ||
ports->ftype == listen_type_udpancil_dnscrypt)
} else if(ports->ftype == listen_type_udpancil)
cp = comm_point_create_udp_ancil(base, ports->fd,
front->udp_buff, cb, cb_arg);
if(!cp) {
@@ -1218,21 +1072,6 @@ listen_create(struct comm_base* base, struct listen_port* ports,
}
cp->dtenv = dtenv;
cp->do_not_close = 1;
#ifdef USE_DNSCRYPT
if (ports->ftype == listen_type_udp_dnscrypt ||
ports->ftype == listen_type_tcp_dnscrypt ||
ports->ftype == listen_type_udpancil_dnscrypt) {
cp->dnscrypt = 1;
cp->dnscrypt_buffer = sldns_buffer_new(bufsize);
if(!cp->dnscrypt_buffer) {
log_err("can't alloc dnscrypt_buffer");
comm_point_delete(cp);
listen_delete(front);
return NULL;
}
front->dnscrypt_udp_buff = cp->dnscrypt_buffer;
}
#endif
if(!listen_cp_insert(cp, front)) {
log_err("malloc failed");
comm_point_delete(cp);
@@ -1268,12 +1107,6 @@ listen_delete(struct listen_dnsport* front)
if(!front)
return;
listen_list_delete(front->cps);
#ifdef USE_DNSCRYPT
if(front->dnscrypt_udp_buff &&
front->udp_buff != front->dnscrypt_udp_buff) {
sldns_buffer_free(front->dnscrypt_udp_buff);
}
#endif
sldns_buffer_free(front->udp_buff);
free(front);
}
@@ -1317,8 +1150,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, reuseport,
cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->tcp_mss, cfg->ip_freebind)) {
listening_ports_free(list);
return NULL;
}
@@ -1331,8 +1163,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, reuseport,
cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->tcp_mss, cfg->ip_freebind)) {
listening_ports_free(list);
return NULL;
}
@@ -1347,8 +1178,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, reuseport,
cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->tcp_mss, cfg->ip_freebind)) {
listening_ports_free(list);
return NULL;
}
@@ -1361,8 +1191,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, reuseport,
cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->tcp_mss, cfg->ip_freebind)) {
listening_ports_free(list);
return NULL;
}
@@ -1390,16 +1219,10 @@ void listening_ports_free(struct listen_port* list)
size_t listen_get_mem(struct listen_dnsport* listen)
{
struct listen_list* p;
size_t s = sizeof(*listen) + sizeof(*listen->base) +
sizeof(*listen->udp_buff) +
sldns_buffer_capacity(listen->udp_buff);
#ifdef USE_DNSCRYPT
s += sizeof(*listen->dnscrypt_udp_buff);
if(listen->udp_buff != listen->dnscrypt_udp_buff){
s += sldns_buffer_capacity(listen->dnscrypt_udp_buff);
}
#endif
struct listen_list* p;
for(p = listen->cps; p; p = p->next) {
s += sizeof(*p);
s += comm_point_get_mem(p->com);
+6 -18
View File
@@ -59,9 +59,7 @@ struct listen_dnsport {
/** buffer shared by UDP connections, since there is only one
datagram at any time. */
struct sldns_buffer* udp_buff;
#ifdef USE_DNSCRYPT
struct sldns_buffer* dnscrypt_udp_buff;
#endif
/** list of comm points used to get incoming events */
struct listen_list* cps;
};
@@ -87,14 +85,7 @@ enum listen_type {
/** udp ipv6 (v4mapped) for use with ancillary data */
listen_type_udpancil,
/** ssl over tcp type */
listen_type_ssl,
/** udp type + dnscrypt*/
listen_type_udp_dnscrypt,
/** tcp type + dnscrypt */
listen_type_tcp_dnscrypt,
/** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/
listen_type_udpancil_dnscrypt
listen_type_ssl
};
/**
@@ -146,7 +137,7 @@ void listening_ports_free(struct listen_port* list);
*/
struct listen_dnsport* listen_create(struct comm_base* base,
struct listen_port* ports, size_t bufsize, int tcp_accept_count,
void* sslctx, struct dt_env *dtenv, comm_point_callback_type* cb,
void* sslctx, struct dt_env *dtenv, comm_point_callback_t* cb,
void* cb_arg);
/**
@@ -200,12 +191,11 @@ void listen_start_accept(struct listen_dnsport* listen);
* listening UDP port. Set to false on return if it failed to do so.
* @param transparent: set IP_TRANSPARENT socket option.
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @return: the socket. -1 on error.
*/
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv,
int snd, int listen, int* reuseport, int transparent, int freebind, int use_systemd);
int snd, int listen, int* reuseport, int transparent, int freebind);
/**
* Create and bind TCP listening socket
@@ -217,20 +207,18 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
* @param transparent: set IP_TRANSPARENT socket option.
* @param mss: maximum segment size of the socket. if zero, leaves the default.
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @return: the socket. -1 on error.
*/
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int freebind, int use_systemd);
int* reuseport, int transparent, int mss, int freebind);
/**
* Create and bind local listening socket
* @param path: path to the socket.
* @param noproto: on error, this is set true if cause is that local sockets
* are not supported.
* @param use_systemd: if true, fetch sockets from systemd.
* @return: the socket. -1 on error.
*/
int create_local_accept_sock(const char* path, int* noproto, int use_systemd);
int create_local_accept_sock(const char* path, int* noproto);
#endif /* LISTEN_DNSPORT_H */
+38 -80
View File
@@ -74,7 +74,7 @@ local_zones_create(void)
/** helper traverse to delete zones */
static void
lzdel(rbnode_type* n, void* ATTR_UNUSED(arg))
lzdel(rbnode_t* n, void* ATTR_UNUSED(arg))
{
struct local_zone* z = (struct local_zone*)n->key;
local_zone_delete(z);
@@ -165,7 +165,7 @@ local_zone_create(uint8_t* nm, size_t len, int labs,
return NULL;
}
rbtree_init(&z->data, &local_data_cmp);
lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_type));
lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_t));
/* also the zones->lock protects node, parent, name*, class */
return z;
}
@@ -187,9 +187,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
lock_rw_wrlock(&z->lock);
if(!rbtree_insert(&zones->ztree, &z->node)) {
struct local_zone* oldz;
char str[256];
dname_str(nm, str);
log_warn("duplicate local-zone %s", str);
log_warn("duplicate local-zone");
lock_rw_unlock(&z->lock);
/* save zone name locally before deallocation,
* otherwise, nm is gone if we zone_delete now. */
@@ -231,8 +229,9 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
return z;
}
int
rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
/** return name and class and rdata of rr; parses string */
static int
get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
uint8_t** rdata, size_t* rdata_len)
{
@@ -354,8 +353,8 @@ new_local_rrset(struct regional* region, struct local_data* node,
}
/** insert RR into RRset data structure; Wastes a couple of bytes */
int
rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
static int
insert_rr(struct regional* region, struct packed_rrset_data* pd,
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr)
{
size_t* oldlen = pd->rr_len;
@@ -457,8 +456,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
uint8_t rr[LDNS_RR_BUF_SIZE];
uint8_t* rdata;
size_t rdata_len;
if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
sizeof(rr), &rdata, &rdata_len)) {
if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr),
&rdata, &rdata_len)) {
log_err("bad local-data: %s", rrstr);
return 0;
}
@@ -514,7 +513,7 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
return 1;
}
return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
return insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
}
/** enter a data RR into auth data; a zone for it must exist */
@@ -630,7 +629,7 @@ lz_enter_override(struct local_zones* zones, char* zname, char* netblock,
/* create netblock addr_tree if not present yet */
if(!z->override_tree) {
z->override_tree = (struct rbtree_type*)regional_alloc_zero(
z->override_tree = (struct rbtree_t*)regional_alloc_zero(
z->region, sizeof(*z->override_tree));
if(!z->override_tree) {
lock_rw_unlock(&z->lock);
@@ -746,15 +745,12 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
}
/** enter default zones */
int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg)
static int
lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
{
struct local_zone* z;
const char** zstr;
/* Do not add any default */
if(cfg->local_zones_disable_default)
return 1;
/* this list of zones is from RFC 6303 and RFC 7686 */
/* block localhost level zones first, then onion and later the LAN zones */
@@ -1024,7 +1020,7 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
return 0;
}
/* apply default zones+content (unless disabled, or overridden) */
if(!local_zone_enter_defaults(zones, cfg)) {
if(!lz_enter_defaults(zones, cfg)) {
return 0;
}
/* enter local zone overrides */
@@ -1064,7 +1060,7 @@ local_zones_tags_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass,
uint8_t* taglist, size_t taglen, int ignoretags)
{
rbnode_type* res = NULL;
rbnode_t* res = NULL;
struct local_zone *result;
struct local_zone key;
int m;
@@ -1218,29 +1214,10 @@ local_encode(struct query_info* qinfo, struct module_env* env,
return 1;
}
/** encode local error answer */
static void
local_error_encode(struct query_info* qinfo, struct module_env* env,
struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
int rcode, int r)
{
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
rcode, edns, temp))
edns->opt_list = NULL;
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
}
/** find local data tag string match for the given type in the list */
int
local_data_find_tag_datas(const struct query_info* qinfo,
struct config_strlist* list, struct ub_packed_rrset_key* r,
struct regional* temp)
static int
find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
struct ub_packed_rrset_key* r, struct regional* temp)
{
struct config_strlist* p;
char buf[65536];
@@ -1317,24 +1294,13 @@ local_data_find_tag_datas(const struct query_info* qinfo,
sldns_wirerr_get_rdatawl(rr, len, 1),
d->rr_len[d->count]);
if(!d->rr_data[d->count])
return 0; /* out of memory */
if(!d) return 0; /* out of memory */
d->count++;
}
if(r->rk.dname)
return 1;
return 0;
}
static int
find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
struct ub_packed_rrset_key* r, struct regional* temp)
{
int result = local_data_find_tag_datas(qinfo, list, r, temp);
/* If we've found a non-exact alias type of local data, make a shallow
* copy of the RRset and remember it in qinfo to complete the alias
* chain later. */
if(result && qinfo->qtype != LDNS_RR_TYPE_CNAME &&
if(r->rk.dname && qinfo->qtype != LDNS_RR_TYPE_CNAME &&
r->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
qinfo->local_alias =
regional_alloc_zero(temp, sizeof(struct local_rrset));
@@ -1345,7 +1311,9 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
if(!qinfo->local_alias->rrset)
return 0; /* out of memory */
}
return result;
if(r->rk.dname)
return 1;
return 0;
}
/** answer local data match */
@@ -1446,8 +1414,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
return 1;
} else if(lz_type == local_zone_refuse
|| lz_type == local_zone_always_refuse) {
local_error_encode(qinfo, env, edns, buf, temp,
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA));
error_encode(buf, (LDNS_RCODE_REFUSED|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
} else if(lz_type == local_zone_static ||
lz_type == local_zone_redirect ||
@@ -1464,8 +1433,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
if(z->soa)
return local_encode(qinfo, env, edns, buf, temp,
z->soa, 0, rcode);
local_error_encode(qinfo, env, edns, buf, temp, rcode,
(rcode|BIT_AA));
error_encode(buf, (rcode|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
} else if(lz_type == local_zone_typetransparent
|| lz_type == local_zone_always_transparent) {
@@ -1481,8 +1451,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
if(z->soa)
return local_encode(qinfo, env, edns, buf, temp,
z->soa, 0, rcode);
local_error_encode(qinfo, env, edns, buf, temp, rcode,
(rcode|BIT_AA));
error_encode(buf, (rcode|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
}
@@ -1508,9 +1479,11 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,
static enum localzone_type
lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2,
uint8_t *tagactions, size_t tagactionssize, enum localzone_type lzt,
struct comm_reply* repinfo, struct rbtree_type* override_tree,
int* tag, char** tagname, int num_tags)
struct comm_reply* repinfo, struct rbtree_t* override_tree, int* tag,
char** tagname, int num_tags)
{
size_t i, j;
uint8_t tagmatch;
struct local_zone_override* lzo;
if(repinfo && override_tree) {
lzo = (struct local_zone_override*)addr_tree_lookup(
@@ -1523,19 +1496,6 @@ lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2,
}
if(!taglist || !taglist2)
return lzt;
return local_data_find_tag_action(taglist, taglen, taglist2, taglen2,
tagactions, tagactionssize, lzt, tag, tagname, num_tags);
}
enum localzone_type
local_data_find_tag_action(const uint8_t* taglist, size_t taglen,
const uint8_t* taglist2, size_t taglen2, const uint8_t* tagactions,
size_t tagactionssize, enum localzone_type lzt, int* tag,
char* const* tagname, int num_tags)
{
size_t i, j;
uint8_t tagmatch;
for(i=0; i<taglen && i<taglen2; i++) {
tagmatch = (taglist[i] & taglist2[i]);
for(j=0; j<8 && tagmatch>0; j++) {
@@ -1590,7 +1550,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
lock_rw_rdlock(&z->lock);
lzt = z->type;
}
if(view->local_zones && !z && !view->isfirst){
if(!z && !view->isfirst){
lock_rw_unlock(&view->lock);
return 0;
}
@@ -1675,8 +1635,6 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_always_refuse;
else if(strcmp(type, "always_nxdomain") == 0)
*t = local_zone_always_nxdomain;
else if(strcmp(type, "nodefault") == 0)
*t = local_zone_nodefault;
else return 0;
return 1;
}
+7 -124
View File
@@ -46,7 +46,6 @@
#include "util/storage/dnstree.h"
#include "util/module.h"
#include "services/view.h"
struct packed_rrset_data;
struct ub_packed_rrset_key;
struct regional;
struct config_file;
@@ -96,9 +95,9 @@ enum localzone_type {
*/
struct local_zones {
/** lock on the localzone tree */
lock_rw_type lock;
lock_rw_t lock;
/** rbtree of struct local_zone */
rbtree_type ztree;
rbtree_t ztree;
};
/**
@@ -106,7 +105,7 @@ struct local_zones {
*/
struct local_zone {
/** rbtree node, key is name and class */
rbnode_type node;
rbnode_t node;
/** parent zone, if any. */
struct local_zone* parent;
@@ -124,7 +123,7 @@ struct local_zone {
* For the node, parent, name, namelen, namelabs, dclass, you
* need to also hold the zones_tree lock to change them (or to
* delete this zone) */
lock_rw_type lock;
lock_rw_t lock;
/** how to process zone */
enum localzone_type type;
@@ -134,14 +133,14 @@ struct local_zone {
size_t taglen;
/** netblock addr_tree with struct local_zone_override information
* or NULL if there are no override elements */
struct rbtree_type* override_tree;
struct rbtree_t* override_tree;
/** in this region the zone's data is allocated.
* the struct local_zone itself is malloced. */
struct regional* region;
/** local data for this zone
* rbtree of struct local_data */
rbtree_type data;
rbtree_t data;
/** if data contains zone apex SOA data, this is a ptr to it. */
struct ub_packed_rrset_key* soa;
};
@@ -151,7 +150,7 @@ struct local_zone {
*/
struct local_data {
/** rbtree node, key is name only */
rbnode_type node;
rbnode_t node;
/** domain name */
uint8_t* name;
/** length of name */
@@ -390,120 +389,4 @@ void local_zones_del_data(struct local_zones* zones,
*/
int parse_dname(const char* str, uint8_t** res, size_t* len, int* labs);
/**
* Find local data tag string match for the given type (in qinfo) in the list.
* If found, 'r' will be filled with corresponding rrset information.
* @param qinfo: contains name, type, and class for the data
* @param list: stores local tag data to be searched
* @param r: rrset key to be filled for matched data
* @param temp: region to allocate rrset in 'r'
* @return 1 if a match is found and rrset is built; otherwise 0 including
* errors.
*/
int local_data_find_tag_datas(const struct query_info* qinfo,
struct config_strlist* list, struct ub_packed_rrset_key* r,
struct regional* temp);
/**
* See if two sets of tag lists (in the form of bitmap) have the same tag that
* has an action. If so, '*tag' will be set to the found tag index, and the
* corresponding action will be returned in the form of local zone type.
* Otherwise the passed type (lzt) will be returned as the default action.
* Pointers except tagactions must not be NULL.
* @param taglist: 1st list of tags
* @param taglen: size of taglist in bytes
* @param taglist2: 2nd list of tags
* @param taglen2: size of taglist2 in bytes
* @param tagactions: local data actions for tags. May be NULL.
* @param tagactionssize: length of the tagactions.
* @param lzt: default action (local zone type) if no tag action is found.
* @param tag: see above.
* @param tagname: array of tag name strings (for debug output).
* @param num_tags: number of items in tagname array.
* @return found tag action or the default action.
*/
enum localzone_type local_data_find_tag_action(const uint8_t* taglist,
size_t taglen, const uint8_t* taglist2, size_t taglen2,
const uint8_t* tagactions, size_t tagactionssize,
enum localzone_type lzt, int* tag, char* const* tagname, int num_tags);
/**
* Enter defaults to local zone.
* @param zones: to add defaults to
* @param cfg: containing list of zones to exclude from default set.
* @return 1 on success; 0 otherwise.
*/
int local_zone_enter_defaults(struct local_zones* zones,
struct config_file* cfg);
/**
* Parses resource record string into wire format, also returning its field values.
* @param str: input resource record
* @param nm: domain name field
* @param type: record type field
* @param dclass: record class field
* @param ttl: ttl field
* @param rr: buffer for the parsed rr in wire format
* @param len: buffer length
* @param rdata: rdata field
* @param rdata_len: rdata field length
* @return 1 on success; 0 otherwise.
*/
int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
uint8_t** rdata, size_t* rdata_len);
/**
* Insert specified rdata into the specified resource record.
* @param region: allocator
* @param pd: data portion of the destination resource record
* @param rdata: source rdata
* @param rdata_len: source rdata length
* @param ttl: time to live
* @param rrstr: resource record in text form (for logging)
* @return 1 on success; 0 otherwise.
*/
int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
/**
* Valid response ip actions for the IP-response-driven-action feature;
* defined here instead of in the respip module to enable sharing of enum
* values with the localzone_type enum.
* Note that these values except 'none' are the same as localzone types of
* the 'same semantics'. It's intentional as we use these values via
* access-control-tags, which can be shared for both response ip actions and
* local zones.
*/
enum respip_action {
/** no respip action */
respip_none = local_zone_unset,
/** don't answer */
respip_deny = local_zone_deny,
/** redirect as per provided data */
respip_redirect = local_zone_redirect,
/** log query source and answer query */
respip_inform = local_zone_inform,
/** log query source and don't answer query */
respip_inform_deny = local_zone_inform_deny,
/** resolve normally, even when there is response-ip data */
respip_always_transparent = local_zone_always_transparent,
/** answer with 'refused' response */
respip_always_refuse = local_zone_always_refuse,
/** answer with 'no such domain' response */
respip_always_nxdomain = local_zone_always_nxdomain,
/* The rest of the values are only possible as
* access-control-tag-action */
/** serves response data (if any), else, drops queries. */
respip_refuse = local_zone_refuse,
/** serves response data, else, nodata answer. */
respip_static = local_zone_static,
/** gives response data (if any), else nodata answer. */
respip_transparent = local_zone_transparent,
/** gives response data (if any), else nodata answer. */
respip_typetransparent = local_zone_typetransparent,
};
#endif /* SERVICES_LOCALZONE_H */
+42 -155
View File
@@ -59,7 +59,6 @@
#include "sldns/wire2str.h"
#include "services/localzone.h"
#include "util/data/dname.h"
#include "respip/respip.h"
/** subtract timers and the values do not overflow or become negative */
static void
@@ -125,64 +124,11 @@ timeval_smaller(const struct timeval* x, const struct timeval* y)
#endif
}
/*
* Compare two response-ip client info entries for the purpose of mesh state
* compare. It returns 0 if ci_a and ci_b are considered equal; otherwise
* 1 or -1 (they mean 'ci_a is larger/smaller than ci_b', respectively, but
* in practice it should be only used to mean they are different).
* We cannot share the mesh state for two queries if different response-ip
* actions can apply in the end, even if those queries are otherwise identical.
* For this purpose we compare tag lists and tag action lists; they should be
* identical to share the same state.
* For tag data, we don't look into the data content, as it can be
* expensive; unless tag data are not defined for both or they point to the
* exact same data in memory (i.e., they come from the same ACL entry), we
* consider these data different.
* Likewise, if the client info is associated with views, we don't look into
* the views. They are considered different unless they are exactly the same
* even if the views only differ in the names.
*/
static int
client_info_compare(const struct respip_client_info* ci_a,
const struct respip_client_info* ci_b)
{
int cmp;
if(!ci_a && !ci_b)
return 0;
if(ci_a && !ci_b)
return -1;
if(!ci_a && ci_b)
return 1;
if(ci_a->taglen != ci_b->taglen)
return (ci_a->taglen < ci_b->taglen) ? -1 : 1;
cmp = memcmp(ci_a->taglist, ci_b->taglist, ci_a->taglen);
if(cmp != 0)
return cmp;
if(ci_a->tag_actions_size != ci_b->tag_actions_size)
return (ci_a->tag_actions_size < ci_b->tag_actions_size) ?
-1 : 1;
cmp = memcmp(ci_a->tag_actions, ci_b->tag_actions,
ci_a->tag_actions_size);
if(cmp != 0)
return cmp;
if(ci_a->tag_datas != ci_b->tag_datas)
return ci_a->tag_datas < ci_b->tag_datas ? -1 : 1;
if(ci_a->view != ci_b->view)
return ci_a->view < ci_b->view ? -1 : 1;
/* For the unbound daemon these should be non-NULL and identical,
* but we check that just in case. */
if(ci_a->respip_set != ci_b->respip_set)
return ci_a->respip_set < ci_b->respip_set ? -1 : 1;
return 0;
}
int
mesh_state_compare(const void* ap, const void* bp)
{
struct mesh_state* a = (struct mesh_state*)ap;
struct mesh_state* b = (struct mesh_state*)bp;
int cmp;
if(a->unique < b->unique)
return -1;
@@ -209,10 +155,7 @@ mesh_state_compare(const void* ap, const void* bp)
if(!(a->s.query_flags&BIT_CD) && (b->s.query_flags&BIT_CD))
return 1;
cmp = query_info_compare(&a->s.qinfo, &b->s.qinfo);
if(cmp != 0)
return cmp;
return client_info_compare(a->s.client_info, b->s.client_info);
return query_info_compare(&a->s.qinfo, &b->s.qinfo);
}
int
@@ -260,7 +203,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
/** help mesh delete delete mesh states */
static void
mesh_delete_helper(rbnode_type* n)
mesh_delete_helper(rbnode_t* n)
{
struct mesh_state* mstate = (struct mesh_state*)n->key;
/* perform a full delete, not only 'cleanup' routine,
@@ -344,16 +287,16 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
}
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags,
struct edns_data* edns, struct comm_reply* rep, uint16_t qid)
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
uint16_t qid)
{
struct mesh_state* s = NULL;
int unique = unique_mesh_state(edns->opt_list, mesh->env);
int unique = edns_unique_mesh_state(edns->opt_list, mesh->env);
int was_detached = 0;
int was_noreply = 0;
int added = 0;
if(!unique)
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
/* does this create a new reply state? */
if(!s || s->list_select == mesh_no_list) {
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
@@ -378,10 +321,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
/* see if it already exists, if not, create one */
if(!s) {
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
struct rbnode_t* n;
#endif
s = mesh_state_create(mesh->env, qinfo, cinfo,
qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
log_err("mesh_state_create: out of memory; SERVFAIL");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
@@ -467,25 +409,23 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
int
mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
uint16_t qid, mesh_cb_func_type cb, void* cb_arg)
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
{
struct mesh_state* s = NULL;
int unique = unique_mesh_state(edns->opt_list, mesh->env);
int unique = edns_unique_mesh_state(edns->opt_list, mesh->env);
int was_detached = 0;
int was_noreply = 0;
int added = 0;
if(!unique)
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
/* there are no limits on the number of callbacks */
/* see if it already exists, if not, create one */
if(!s) {
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
struct rbnode_t* n;
#endif
s = mesh_state_create(mesh->env, qinfo, NULL,
qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
return 0;
}
@@ -536,10 +476,10 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, time_t leeway)
{
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
qflags&(BIT_RD|BIT_CD), 0, 0);
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD),
0, 0);
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
struct rbnode_t* n;
#endif
/* already exists, and for a different purpose perhaps.
* if mesh_no_list, keep it that way. */
@@ -557,8 +497,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
return;
}
s = mesh_state_create(mesh->env, qinfo, NULL,
qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
log_err("prefetch mesh_state_create: out of memory");
return;
@@ -607,8 +546,7 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
struct mesh_state*
mesh_state_create(struct module_env* env, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec)
uint16_t qflags, int prime, int valrec)
{
struct regional* region = alloc_reg_obtain(env->alloc);
struct mesh_state* mstate;
@@ -644,14 +582,6 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
alloc_reg_release(env->alloc, region);
return NULL;
}
if(cinfo) {
mstate->s.client_info = regional_alloc_init(region, cinfo,
sizeof(*cinfo));
if(!mstate->s.client_info) {
alloc_reg_release(env->alloc, region);
return NULL;
}
}
/* remove all weird bits from qflags */
mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD));
mstate->s.is_priming = prime;
@@ -799,7 +729,7 @@ void mesh_detach_subs(struct module_qstate* qstate)
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state_ref* ref, lookup;
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
struct rbnode_t* n;
#endif
lookup.node.key = &lookup;
lookup.s = qstate->mesh_info;
@@ -821,26 +751,24 @@ void mesh_detach_subs(struct module_qstate* qstate)
rbtree_init(&qstate->mesh_info->sub_set, &mesh_state_ref_compare);
}
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub)
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
{
/* find it, if not, create it */
struct mesh_area* mesh = qstate->env->mesh;
*sub = mesh_area_find(mesh, NULL, qinfo, qflags,
prime, valrec);
if(mesh_detect_cycle_found(qstate, *sub)) {
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime, valrec);
int was_detached;
if(mesh_detect_cycle_found(qstate, sub)) {
verbose(VERB_ALGO, "attach failed, cycle detected");
return 0;
}
if(!*sub) {
if(!sub) {
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
struct rbnode_t* n;
#endif
/* create a new one */
*sub = mesh_state_create(qstate->env, qinfo, NULL, qflags, prime,
valrec);
if(!*sub) {
sub = mesh_state_create(qstate->env, qinfo, qflags, prime, valrec);
if(!sub) {
log_err("mesh_attach_sub: out of memory");
return 0;
}
@@ -849,7 +777,7 @@ int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
#else
(void)
#endif
rbtree_insert(&mesh->all, &(*sub)->node);
rbtree_insert(&mesh->all, &sub->node);
log_assert(n != NULL);
/* set detached (it is now) */
mesh->num_detached_states++;
@@ -859,22 +787,11 @@ int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
#else
(void)
#endif
rbtree_insert(&mesh->run, &(*sub)->run_node);
rbtree_insert(&mesh->run, &sub->run_node);
log_assert(n != NULL);
*newq = &(*sub)->s;
*newq = &sub->s;
} else
*newq = NULL;
return 1;
}
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
{
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* sub = NULL;
int was_detached;
if(!mesh_add_sub(qstate, qinfo, qflags, prime, valrec, newq, &sub))
return 0;
was_detached = (sub->super_set.count == 0);
if(!mesh_state_attachment(qstate->mesh_info, sub))
return 0;
@@ -892,7 +809,7 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
int mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub)
{
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
struct rbnode_t* n;
#endif
struct mesh_state_ref* subref; /* points to sub, inserted in super */
struct mesh_state_ref* superref; /* points to super, inserted in sub */
@@ -1102,12 +1019,6 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
query_reply.c->buffer)) == 0)
m->s.env->mesh->ans_nodata++;
}
/* Log reply sent */
if(m->s.env->cfg->log_replies) {
log_reply_info(0, &m->s.qinfo, &r->query_reply.addr,
r->query_reply.addrlen, duration, 0,
r->query_reply.c->buffer);
}
}
void mesh_query_done(struct mesh_state* mstate)
@@ -1118,25 +1029,8 @@ void mesh_query_done(struct mesh_state* mstate)
struct reply_info* rep = (mstate->s.return_msg?
mstate->s.return_msg->rep:NULL);
for(r = mstate->reply_list; r; r = r->next) {
/* if a response-ip address block has been stored the
* information should be logged for each client. */
if(mstate->s.respip_action_info &&
mstate->s.respip_action_info->addrinfo) {
respip_inform_print(mstate->s.respip_action_info->addrinfo,
r->qname, mstate->s.qinfo.qtype,
mstate->s.qinfo.qclass, r->local_alias,
&r->query_reply);
}
/* if this query is determined to be dropped during the
* mesh processing, this is the point to take that action. */
if(mstate->s.is_drop)
comm_point_drop_reply(&r->query_reply);
else {
mesh_send_reply(mstate, mstate->s.return_rcode, rep,
r, prev);
prev = r;
}
mesh_send_reply(mstate, mstate->s.return_rcode, rep, r, prev);
prev = r;
}
mstate->replies_sent = 1;
for(c = mstate->cb_list; c; c = c->next) {
@@ -1160,8 +1054,7 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
}
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
struct respip_client_info* cinfo, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec)
struct query_info* qinfo, uint16_t qflags, int prime, int valrec)
{
struct mesh_state key;
struct mesh_state* result;
@@ -1175,14 +1068,13 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
* aggregate the state. Thus unique is set to NULL. (default when we
* desire aggregation).*/
key.unique = NULL;
key.s.client_info = cinfo;
result = (struct mesh_state*)rbtree_search(&mesh->all, &key);
return result;
}
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
sldns_buffer* buf, mesh_cb_func_type cb, void* cb_arg,
sldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg,
uint16_t qid, uint16_t qflags)
{
struct mesh_cb* r = regional_alloc(s->s.region,
@@ -1326,16 +1218,11 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
return mesh_continue(mesh, mstate, module_error, ev);
}
if(s == module_restart_next) {
int curmod = mstate->s.curmod;
for(; mstate->s.curmod < mesh->mods.num;
mstate->s.curmod++) {
fptr_ok(fptr_whitelist_mod_clear(
mesh->mods.mod[mstate->s.curmod]->clear));
(*mesh->mods.mod[mstate->s.curmod]->clear)
(&mstate->s, mstate->s.curmod);
mstate->s.minfo[mstate->s.curmod] = NULL;
}
mstate->s.curmod = curmod;
fptr_ok(fptr_whitelist_mod_clear(
mesh->mods.mod[mstate->s.curmod]->clear));
(*mesh->mods.mod[mstate->s.curmod]->clear)
(&mstate->s, mstate->s.curmod);
mstate->s.minfo[mstate->s.curmod] = NULL;
}
*ev = module_event_pass;
return 1;
@@ -1485,7 +1372,7 @@ mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* dep_m = NULL;
if(!mesh_state_is_unique(qstate->mesh_info))
dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
dep_m = mesh_area_find(mesh, qinfo, flags, prime, valrec);
return mesh_detect_cycle_found(qstate, dep_m);
}
+18 -57
View File
@@ -59,7 +59,6 @@ struct query_info;
struct reply_info;
struct outbound_entry;
struct timehist;
struct respip_client_info;
/**
* Maximum number of mesh state activations. Any more is likely an
@@ -84,9 +83,9 @@ struct mesh_area {
struct module_env* env;
/** set of runnable queries (mesh_state.run_node) */
rbtree_type run;
rbtree_t run;
/** rbtree of all current queries (mesh_state.node)*/
rbtree_type all;
rbtree_t all;
/** count of the total number of mesh_reply entries */
size_t num_reply_addrs;
@@ -155,9 +154,9 @@ struct mesh_area {
*/
struct mesh_state {
/** node in mesh_area all tree, key is this struct. Must be first. */
rbnode_type node;
rbnode_t node;
/** node in mesh_area runnable tree, key is this struct */
rbnode_type run_node;
rbnode_t run_node;
/** the query state. Note that the qinfo and query_flags
* may not change. */
struct module_qstate s;
@@ -167,10 +166,10 @@ struct mesh_state {
struct mesh_cb* cb_list;
/** set of superstates (that want this state's result)
* contains struct mesh_state_ref* */
rbtree_type super_set;
rbtree_t super_set;
/** set of substates (that this state needs to continue)
* contains struct mesh_state_ref* */
rbtree_type sub_set;
rbtree_t sub_set;
/** number of activations for the mesh state */
size_t num_activated;
@@ -194,7 +193,7 @@ struct mesh_state {
*/
struct mesh_state_ref {
/** node in rbtree for set, key is this structure */
rbnode_type node;
rbnode_t node;
/** the mesh state */
struct mesh_state* s;
};
@@ -225,7 +224,7 @@ struct mesh_reply {
* Mesh result callback func.
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
*/
typedef void (*mesh_cb_func_type)(void*, int, struct sldns_buffer*, enum sec_status,
typedef void (*mesh_cb_func_t)(void*, int, struct sldns_buffer*, enum sec_status,
char*);
/**
@@ -246,7 +245,7 @@ struct mesh_cb {
/** callback routine for results. if rcode != 0 buf has message.
* called as cb(cb_arg, rcode, buf, sec_state);
*/
mesh_cb_func_type cb;
mesh_cb_func_t cb;
/** user arg for callback */
void* cb_arg;
};
@@ -275,18 +274,14 @@ void mesh_delete(struct mesh_area* mesh);
*
* @param mesh: the mesh.
* @param qinfo: query from client.
* @param cinfo: additional information associated with the query client.
* 'cinfo' itself is ephemeral but data pointed to by its members
* can be assumed to be valid and unchanged until the query processing is
* completed.
* @param qflags: flags from client query.
* @param edns: edns data from client query.
* @param rep: where to reply to.
* @param qid: query id to reply with.
*/
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags,
struct edns_data* edns, struct comm_reply* rep, uint16_t qid);
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
uint16_t qid);
/**
* New query with callback. Create new query state if needed, and
@@ -305,7 +300,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
*/
int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, struct sldns_buffer* buf,
uint16_t qid, mesh_cb_func_type cb, void* cb_arg);
uint16_t qid, mesh_cb_func_t cb, void* cb_arg);
/**
* New prefetch message. Create new query state if needed.
@@ -370,35 +365,6 @@ void mesh_detach_subs(struct module_qstate* qstate);
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
/**
* Add detached query.
* Creates it if it does not exist already.
* Does not make super/sub references.
* Performs a cycle detection - for double check - and fails if there is one.
* Updates stat items in mesh_area structure.
* Pass if it is priming query or not.
* return:
* o if error (malloc) happened.
* o need to initialise the new state (module init; it is a new state).
* so that the next run of the query with this module is successful.
* o no init needed, attachment successful.
* o added subquery, created if it did not exist already.
*
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
* @param newq: If the new subquery needs initialisation, it is returned,
* otherwise NULL is returned.
* @param sub: The added mesh state, created if it did not exist already.
* @return: false on error, true if success (and init may be needed).
*/
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub);
/**
* Query state is done, send messages to reply entries.
* Encode messages using reply entry values and the querystate (with original
@@ -443,16 +409,14 @@ void mesh_state_delete(struct module_qstate* qstate);
* Does not put the mesh state into rbtrees and so on.
* @param env: module environment to set.
* @param qinfo: query info that the mesh is for.
* @param cinfo: control info for the query client (can be NULL).
* @param qflags: flags for query (RD / CD flag).
* @param prime: if true, it is a priming query, set is_priming on mesh state.
* @param valrec: if true, it is a validation recursion query, and sets
* is_valrec on the mesh state.
* @return: new mesh state or NULL on allocation error.
*/
struct mesh_state* mesh_state_create(struct module_env* env,
struct query_info* qinfo, struct respip_client_info* cinfo,
uint16_t qflags, int prime, int valrec);
struct mesh_state* mesh_state_create(struct module_env* env,
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
/**
* Check if the mesh state is unique.
@@ -487,17 +451,14 @@ void mesh_delete_all(struct mesh_area* mesh);
* Find a mesh state in the mesh area. Pass relevant flags.
*
* @param mesh: the mesh area to look in.
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result.
* @param qinfo: what query
* @param qflags: if RD / CD bit is set or not.
* @param prime: if it is a priming query.
* @param valrec: if it is a validation-recursion query.
* @return: mesh state or NULL if not found.
*/
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
struct respip_client_info* cinfo, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec);
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
/**
* Setup attachment super/sub relation between super and sub mesh state.
@@ -537,8 +498,8 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
* @return: 0 on alloc error.
*/
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
struct sldns_buffer* buf, mesh_cb_func_type cb, void* cb_arg,
uint16_t qid, uint16_t qflags);
struct sldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
uint16_t qflags);
/**
* Run the mesh. Run all runnable mesh states. Which can create new
+8 -41
View File
@@ -46,7 +46,6 @@
#include "dns64/dns64.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
#include "respip/respip.h"
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
@@ -54,12 +53,6 @@
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#endif
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#endif
/** count number of modules (words) in the string */
static int
@@ -129,20 +122,13 @@ module_list_avail(void)
static const char* names[] = {
"dns64",
#ifdef WITH_PYTHONMODULE
"python",
"python",
#endif
#ifdef USE_CACHEDB
"cachedb",
#endif
#ifdef USE_IPSECMOD
"ipsecmod",
#endif
#ifdef CLIENT_SUBNET
"subnetcache",
#endif
"respip",
"validator",
"iterator",
"validator",
"iterator",
NULL};
return names;
}
@@ -157,25 +143,18 @@ module_funcs_avail(void)
static struct module_func_block* (*fb[])(void) = {
&dns64_get_funcblock,
#ifdef WITH_PYTHONMODULE
&pythonmod_get_funcblock,
&pythonmod_get_funcblock,
#endif
#ifdef USE_CACHEDB
&cachedb_get_funcblock,
#endif
#ifdef USE_IPSECMOD
&ipsecmod_get_funcblock,
#endif
#ifdef CLIENT_SUBNET
&subnetmod_get_funcblock,
#endif
&respip_get_funcblock,
&val_get_funcblock,
&iter_get_funcblock,
&val_get_funcblock,
&iter_get_funcblock,
NULL};
return fb;
}
struct
struct
module_func_block* module_factory(const char** str)
{
int i = 0;
@@ -237,21 +216,9 @@ int
modstack_find(struct module_stack* stack, const char* name)
{
int i;
for(i=0; i<stack->num; i++) {
for(i=0; i<stack->num; i++) {
if(strcmp(stack->mod[i]->name, name) == 0)
return i;
}
return -1;
}
size_t
mod_get_mem(struct module_env* env, const char* name)
{
int m = modstack_find(&env->mesh->mods, name);
if(m != -1) {
fptr_ok(fptr_whitelist_mod_get_mem(env->mesh->
mods.mod[m]->get_mem));
return (*env->mesh->mods.mod[m]->get_mem)(env, m);
}
return 0;
}
-3
View File
@@ -110,7 +110,4 @@ void modstack_desetup(struct module_stack* stack, struct module_env* env);
*/
int modstack_find(struct module_stack* stack, const char* name);
/** fetch memory for a module by name, returns 0 if module not there */
size_t mod_get_mem(struct module_env* env, const char* name);
#endif /* SERVICES_MODSTACK_H */
+16 -33
View File
@@ -204,9 +204,6 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
{
struct pending_tcp* pend = w->outnet->tcp_free;
int s;
#ifdef SO_REUSEADDR
int on = 1;
#endif
log_assert(pend);
log_assert(pkt);
log_assert(w->addrlen > 0);
@@ -228,20 +225,13 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
return 0;
}
#ifdef SO_REUSEADDR
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0) {
verbose(VERB_ALGO, "outgoing tcp:"
" setsockopt(.. SO_REUSEADDR ..) failed");
}
#endif
if (w->outnet->tcp_mss > 0) {
#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
(void*)&w->outnet->tcp_mss,
(socklen_t)sizeof(w->outnet->tcp_mss)) < 0) {
verbose(VERB_ALGO, "outgoing tcp:"
" setsockopt(.. TCP_MAXSEG ..) failed");
" setsockopt(.. SO_REUSEADDR ..) failed");
}
#else
verbose(VERB_ALGO, "outgoing tcp:"
@@ -344,7 +334,7 @@ use_free_buffer(struct outside_network* outnet)
if(outnet->tcp_wait_last == w)
outnet->tcp_wait_last = NULL;
if(!outnet_tcp_take_into_use(w, w->pkt, w->pkt_len)) {
comm_point_callback_type* cb = w->cb;
comm_point_callback_t* cb = w->cb;
void* cb_arg = w->cb_arg;
waiting_tcp_delete(w);
fptr_ok(fptr_whitelist_pending_tcp(cb));
@@ -785,7 +775,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
/** helper pending delete */
static void
pending_node_del(rbnode_type* node, void* arg)
pending_node_del(rbnode_t* node, void* arg)
{
struct pending* pend = (struct pending*)node;
struct outside_network* outnet = (struct outside_network*)arg;
@@ -794,7 +784,7 @@ pending_node_del(rbnode_type* node, void* arg)
/** helper serviced delete */
static void
serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg))
serviced_node_del(rbnode_t* node, void* ATTR_UNUSED(arg))
{
struct serviced_query* sq = (struct serviced_query*)node;
struct service_callback* p = sq->cblist, *np;
@@ -976,13 +966,13 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
}
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
(struct sockaddr*)&sa, addrlen, 1, inuse, &noproto,
0, 0, 0, NULL, 0, freebind, 0);
0, 0, 0, NULL, 0, freebind);
} else {
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
sa->sin_port = (in_port_t)htons((uint16_t)port);
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
0, 0, 0, NULL, 0, 0, 0);
0, 0, 0, NULL, 0, 0);
}
return fd;
}
@@ -1134,7 +1124,7 @@ randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout)
struct pending*
pending_udp_query(struct serviced_query* sq, struct sldns_buffer* packet,
int timeout, comm_point_callback_type* cb, void* cb_arg)
int timeout, comm_point_callback_t* cb, void* cb_arg)
{
struct pending* pend = (struct pending*)calloc(1, sizeof(*pend));
if(!pend) return NULL;
@@ -1184,7 +1174,7 @@ outnet_tcptimer(void* arg)
{
struct waiting_tcp* w = (struct waiting_tcp*)arg;
struct outside_network* outnet = w->outnet;
comm_point_callback_type* cb;
comm_point_callback_t* cb;
void* cb_arg;
if(w->pkt) {
/* it is on the waiting list */
@@ -1207,7 +1197,7 @@ outnet_tcptimer(void* arg)
struct waiting_tcp*
pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
int timeout, comm_point_callback_type* callback, void* callback_arg)
int timeout, comm_point_callback_t* callback, void* callback_arg)
{
struct pending_tcp* pend = sq->outnet->tcp_free;
struct waiting_tcp* w;
@@ -1311,7 +1301,7 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
{
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
#ifdef UNBOUND_DEBUG
rbnode_type* ins;
rbnode_t* ins;
#endif
if(!sq)
return NULL;
@@ -1548,22 +1538,18 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)
static int
serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)
{
uint8_t* d1 = sldns_buffer_begin(pkt)+12;
uint8_t* d1 = sldns_buffer_at(pkt, 12);
uint8_t* d2 = qbuf+10;
uint8_t len1, len2;
int count = 0;
if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */
return 0;
log_assert(qbuflen >= 15 /* 10 header, root, type, class */);
len1 = *d1++;
len2 = *d2++;
if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */
return 0;
while(len1 != 0 || len2 != 0) {
if(LABEL_IS_PTR(len1)) {
/* check if we can read *d1 with compression ptr rest */
if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
return 0;
d1 = sldns_buffer_begin(pkt)+PTR_OFFSET(len1, *d1);
/* check if we can read the destination *d1 */
d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
return 0;
len1 = *d1++;
@@ -1577,9 +1563,6 @@ serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)
return 0;
if(len1 > LDNS_MAX_LABELLEN)
return 0;
/* check len1 + 1(next length) are okay to read */
if(d1+len1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
return 0;
log_assert(len1 <= LDNS_MAX_LABELLEN);
log_assert(len2 <= LDNS_MAX_LABELLEN);
log_assert(len1 == len2 && len1 != 0);
@@ -1604,7 +1587,7 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
uint8_t *backup_p = NULL;
size_t backlen = 0;
#ifdef UNBOUND_DEBUG
rbnode_type* rem =
rbnode_t* rem =
#else
(void)
#endif
@@ -2007,7 +1990,7 @@ outnet_serviced_query(struct outside_network* outnet,
int nocaps, int tcp_upstream, int ssl_upstream,
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,
comm_point_callback_t* callback, void* callback_arg, sldns_buffer* buff,
struct module_env* env)
{
struct serviced_query* sq;
+10 -10
View File
@@ -123,9 +123,9 @@ struct outside_network {
struct pending* udp_wait_last;
/** pending udp answers. sorted by id, addr */
rbtree_type* pending;
rbtree_t* pending;
/** serviced queries, sorted by qbuf, addr, dnssec */
rbtree_type* serviced;
rbtree_t* serviced;
/** host cache, pointer but not owned by outnet. */
struct infra_cache* infra;
/** where to get random numbers */
@@ -210,7 +210,7 @@ struct port_comm {
*/
struct pending {
/** redblacktree entry, key is the pending struct(id, addr). */
rbnode_type node;
rbnode_t node;
/** the ID for the query. int so that a value out of range can
* be used to signify a pending that is for certain not present in
* the rbtree. (and for which deletion is safe). */
@@ -224,7 +224,7 @@ struct pending {
/** timeout event */
struct comm_timer* timer;
/** callback for the timeout, error or reply to the message */
comm_point_callback_type* cb;
comm_point_callback_t* cb;
/** callback user argument */
void* cb_arg;
/** the outside network it is part of */
@@ -285,7 +285,7 @@ struct waiting_tcp {
/** length of query packet. */
size_t pkt_len;
/** callback for the timeout, error or reply to the message */
comm_point_callback_type* cb;
comm_point_callback_t* cb;
/** callback user argument */
void* cb_arg;
/** if it uses ssl upstream */
@@ -299,7 +299,7 @@ struct service_callback {
/** next in callback list */
struct service_callback* next;
/** callback function */
comm_point_callback_type* cb;
comm_point_callback_t* cb;
/** user argument for callback function */
void* cb_arg;
};
@@ -317,7 +317,7 @@ struct service_callback {
*/
struct serviced_query {
/** The rbtree node, key is this record */
rbnode_type node;
rbnode_t node;
/** The query that needs to be answered. Starts with flags u16,
* then qdcount, ..., including qname, qtype, qclass. Does not include
* EDNS record. */
@@ -443,7 +443,7 @@ void outside_network_quit_prepare(struct outside_network* outnet);
* @return: NULL on error for malloc or socket. Else the pending query object.
*/
struct pending* pending_udp_query(struct serviced_query* sq,
struct sldns_buffer* packet, int timeout, comm_point_callback_type* callback,
struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback,
void* callback_arg);
/**
@@ -459,7 +459,7 @@ struct pending* pending_udp_query(struct serviced_query* sq,
* @return: false on error for malloc or socket. Else the pending TCP object.
*/
struct waiting_tcp* pending_tcp_query(struct serviced_query* sq,
struct sldns_buffer* packet, int timeout, comm_point_callback_type* callback,
struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback,
void* callback_arg);
/**
@@ -504,7 +504,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
int nocaps, int tcp_upstream, int ssl_upstream,
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,
comm_point_callback_t* callback, void* callback_arg,
struct sldns_buffer* buff, struct module_env* env);
/**
+2 -45
View File
@@ -66,10 +66,6 @@ views_create(void)
return v;
}
/** This prototype is defined in in respip.h, but we want to avoid
* unnecessary dependencies */
void respip_set_delete(struct respip_set *set);
void
view_delete(struct view* v)
{
@@ -77,13 +73,12 @@ view_delete(struct view* v)
return;
lock_rw_destroy(&v->lock);
local_zones_delete(v->local_zones);
respip_set_delete(v->respip_set);
free(v->name);
free(v);
}
static void
delviewnode(rbnode_type* n, void* ATTR_UNUSED(arg))
delviewnode(rbnode_t* n, void* ATTR_UNUSED(arg))
{
struct view* v = (struct view*)n;
view_delete(v);
@@ -112,7 +107,7 @@ view_create(char* name)
return NULL;
}
lock_rw_init(&v->lock);
lock_protect(&v->lock, &v->name, sizeof(*v)-sizeof(rbnode_type));
lock_protect(&v->lock, &v->name, sizeof(*v)-sizeof(rbnode_t));
return v;
}
@@ -167,44 +162,6 @@ views_apply_cfg(struct views* vs, struct config_file* cfg)
lz_cfg.local_data = cv->local_data;
lz_cfg.local_zones_nodefault =
cv->local_zones_nodefault;
if(v->isfirst) {
/* Do not add defaults to view-specific
* local-zone when global local zone will be
* used. */
struct config_strlist* nd;
lz_cfg.local_zones_disable_default = 1;
/* Add nodefault zones to list of zones to add,
* so they will be used as if they are
* configured as type transparent */
for(nd = cv->local_zones_nodefault; nd;
nd = nd->next) {
char* nd_str, *nd_type;
nd_str = strdup(nd->str);
if(!nd_str) {
log_err("out of memory");
lock_rw_unlock(&v->lock);
return 0;
}
nd_type = strdup("nodefault");
if(!nd_type) {
log_err("out of memory");
free(nd_str);
lock_rw_unlock(&v->lock);
return 0;
}
if(!cfg_str2list_insert(
&lz_cfg.local_zones, nd_str,
nd_type)) {
log_err("failed to insert "
"default zones into "
"local-zone list");
free(nd_str);
free(nd_type);
lock_rw_unlock(&v->lock);
return 0;
}
}
}
if(!local_zones_apply_cfg(v->local_zones, &lz_cfg)){
lock_rw_unlock(&v->lock);
return 0;
+7 -9
View File
@@ -47,7 +47,6 @@
struct regional;
struct config_file;
struct config_view;
struct respip_set;
/**
@@ -55,9 +54,9 @@ struct respip_set;
*/
struct views {
/** lock on the view tree */
lock_rw_type lock;
lock_rw_t lock;
/** rbtree of struct view */
rbtree_type vtree;
rbtree_t vtree;
};
/**
@@ -65,22 +64,21 @@ struct views {
*/
struct view {
/** rbtree node, key is name */
rbnode_type node;
rbnode_t node;
/** view name.
* Has to be right after rbnode_t due to pointer arithmatic in
* view_create's lock protect */
char* name;
/** view specific local authority zones */
struct local_zones* local_zones;
/** response-ip configuration data for this view */
struct respip_set* respip_set;
/** Fallback to global local_zones when there is no match in the view
* specific tree. 1 for yes, 0 for no */
int isfirst;
/** lock on the data in the structure
* For the node and name you need to also hold the views_tree lock to
* change them. */
lock_rw_type lock;
* For the node and name you
* need to also hold the views_tree lock to change them (or to
* delete this view) */
lock_rw_t lock;
};
-21
View File
@@ -388,27 +388,6 @@ sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
}
#endif /* USE_ECDSA */
#ifdef USE_ED25519
EVP_PKEY*
sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
{
/* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
0x70, 0x03, 0x21, 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 != 32 || 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_ED25519 */
int
sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
const EVP_MD* md)
-9
View File
@@ -92,15 +92,6 @@ EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
*/
RSA *sldns_key_buf2rsa_raw(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 ED25519.
* \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_ed255192pkey_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.
-4
View File
@@ -120,10 +120,6 @@ sldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
if (line_nr) {
*line_nr = *line_nr + 1;
}
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
*t = '\0';
return -1;
}
*t++ = ' ';
prev_c = c;
continue;

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