Upgrade Unbound to 1.6.2. More to follow.
This commit is contained in:
commit
65b390aa03
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333559
@ -23,6 +23,8 @@ 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@
|
||||
@ -95,6 +97,9 @@ 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@
|
||||
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 \
|
||||
@ -104,6 +109,7 @@ 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 \
|
||||
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 \
|
||||
@ -112,8 +118,11 @@ 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 cachedb/cachedb.c $(CHECKLOCK_SRC) \
|
||||
$(DNSTAP_SRC)
|
||||
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)
|
||||
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 \
|
||||
@ -124,7 +133,8 @@ 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 \
|
||||
$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ)
|
||||
COMMON_OBJ_WITHOUT_NETCALL+=respip.lo
|
||||
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
|
||||
@ -148,15 +158,16 @@ 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/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \
|
||||
testcode/unitecs.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
|
||||
readhex.lo testpkts.lo unitldns.lo unitecs.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 remote.lo stats.lo unbound.lo \
|
||||
DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo shm_main.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@
|
||||
@ -180,7 +191,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 $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
|
||||
daemon.lo stats.lo shm_main.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ)
|
||||
LOCKVERIFY_SRC=testcode/lock_verify.c
|
||||
LOCKVERIFY_OBJ=lock_verify.lo
|
||||
@ -379,6 +390,13 @@ 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 \
|
||||
@ -584,7 +602,9 @@ 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!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
|
||||
> $(DEPEND_TMP)
|
||||
cp $(DEPEND_TARGET) $(DEPEND_TMP2)
|
||||
@ -608,11 +628,12 @@ dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_de
|
||||
$(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/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/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h
|
||||
rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
|
||||
@ -634,11 +655,12 @@ 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)/util/net_help.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
|
||||
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h
|
||||
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
|
||||
@ -651,7 +673,8 @@ 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)/util/net_help.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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
|
||||
@ -695,40 +718,46 @@ 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)/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/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
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/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
|
||||
listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.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
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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 \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/util/as112.h
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/dnscrypt/dnscrypt.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)/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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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
|
||||
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)/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 $(PYTHONMOD_HEADER)
|
||||
$(srcdir)/dnscrypt/dnscrypt.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 $(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
|
||||
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 \
|
||||
@ -736,19 +765,22 @@ 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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/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/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)/dnscrypt/dnscrypt.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/data/dname.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/dnstap/dnstap.h
|
||||
alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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 \
|
||||
@ -756,45 +788,61 @@ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/ut
|
||||
$(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)/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/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/util/iana_ports.inc
|
||||
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/iana_ports.inc
|
||||
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
|
||||
$(srcdir)/util/config_file.h util/configparser.h
|
||||
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
|
||||
shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
|
||||
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/worker.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/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
|
||||
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.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 $(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/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)
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/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/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 \
|
||||
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h \
|
||||
$(srcdir)/edns-subnet/edns-subnet.h
|
||||
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
|
||||
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
|
||||
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/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)/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
|
||||
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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 \
|
||||
|
||||
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 \
|
||||
@ -802,10 +850,11 @@ net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_he
|
||||
$(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)/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/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h
|
||||
regional.lo regional.o: $(srcdir)/util/regional.c config.h $(srcdir)/util/log.h $(srcdir)/util/regional.h
|
||||
rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h
|
||||
dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
|
||||
@ -813,7 +862,8 @@ 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)/util/module.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/dnscrypt/dnscrypt.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
|
||||
@ -821,14 +871,17 @@ slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/uti
|
||||
$(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)/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
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/util/log.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/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 \
|
||||
@ -840,9 +893,10 @@ 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)/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)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
|
||||
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \
|
||||
@ -857,8 +911,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)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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 \
|
||||
@ -895,8 +949,8 @@ val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.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)/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)/util/config_file.h $(srcdir)/sldns/keyraw.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
|
||||
val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
@ -910,9 +964,37 @@ dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(src
|
||||
$(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)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/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
|
||||
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h
|
||||
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h
|
||||
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h
|
||||
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
|
||||
@ -927,7 +1009,10 @@ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/r
|
||||
$(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)/services/cache/infra.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/random.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/respip/respip.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/services/view.h
|
||||
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
|
||||
@ -958,6 +1043,12 @@ 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
|
||||
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 \
|
||||
@ -967,68 +1058,72 @@ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/ac
|
||||
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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/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)/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)/daemon/worker.h $(srcdir)/libunbound/worker.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
|
||||
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
|
||||
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/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
|
||||
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/alloc.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/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)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/remote.h $(srcdir)/util/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
|
||||
$(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/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)/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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/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 \
|
||||
@ -1037,16 +1132,18 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(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)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/libworker.h
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/util/shm_side/shm_main.h
|
||||
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
|
||||
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
|
||||
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
|
||||
$(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \
|
||||
$(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.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
|
||||
testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
|
||||
@ -1055,9 +1152,10 @@ 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)/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)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/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 \
|
||||
@ -1066,8 +1164,9 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(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)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/libworker.h
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/util/shm_side/shm_main.h
|
||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
|
||||
@ -1076,44 +1175,47 @@ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/ac
|
||||
$(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)/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)/daemon/worker.h $(srcdir)/libunbound/worker.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
|
||||
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/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)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/testcode/testpkts.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
|
||||
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/testcode/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)/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 \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
|
||||
$(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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 $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
|
||||
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h
|
||||
pktview.lo pktview.o: $(srcdir)/testcode/pktview.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h \
|
||||
@ -1121,10 +1223,11 @@ 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)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h
|
||||
unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c config.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
@ -1132,13 +1235,14 @@ 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)/sldns/sbuffer.h $(PYTHONMOD_HEADER)
|
||||
$(srcdir)/services/view.h $(srcdir)/respip/respip.h $(srcdir)/sldns/sbuffer.h
|
||||
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/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)/dnscrypt/dnscrypt.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h
|
||||
context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
@ -1146,6 +1250,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)/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 \
|
||||
@ -1155,21 +1260,23 @@ 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)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/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
|
||||
$(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/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 \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
@ -1188,24 +1295,26 @@ perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir
|
||||
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/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \
|
||||
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h
|
||||
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
|
||||
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
|
||||
pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
|
||||
|
||||
$(srcdir)/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)/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
|
||||
$(srcdir)/daemon/worker.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/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
|
||||
|
@ -103,9 +103,20 @@ AC_DEFUN([AC_PROG_SWIG],[
|
||||
if test -z "$available_patch" ; then
|
||||
[available_patch=0]
|
||||
fi
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; then
|
||||
[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
|
||||
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
|
||||
|
@ -22,8 +22,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
|
@ -4,6 +4,9 @@
|
||||
/* Directory to chroot to */
|
||||
#define CHROOT_DIR "/var/unbound"
|
||||
|
||||
/* Define this to enable client subnet option. */
|
||||
/* #undef CLIENT_SUBNET */
|
||||
|
||||
/* Do sha512 definitions in config.h */
|
||||
/* #undef COMPAT_SHA512 */
|
||||
|
||||
@ -386,6 +389,9 @@
|
||||
/* Define to 1 if you have the `SHA512_Update' function. */
|
||||
/* #undef HAVE_SHA512_UPDATE */
|
||||
|
||||
/* Define to 1 if you have the `shmget' function. */
|
||||
#define HAVE_SHMGET 1
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
#define HAVE_SIGPROCMASK 1
|
||||
|
||||
@ -458,6 +464,9 @@
|
||||
/* Define to 1 if systemd should be used */
|
||||
/* #undef HAVE_SYSTEMD */
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#define HAVE_SYS_IPC_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
@ -467,6 +476,9 @@
|
||||
/* 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. */
|
||||
#define HAVE_SYS_SHM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
@ -583,7 +595,7 @@
|
||||
#define PACKAGE_NAME "unbound"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "unbound 1.6.1"
|
||||
#define PACKAGE_STRING "unbound 1.6.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "unbound"
|
||||
@ -592,7 +604,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.6.1"
|
||||
#define PACKAGE_VERSION "1.6.2"
|
||||
|
||||
/* default pidfile location */
|
||||
#define PIDFILE "/var/unbound/unbound.pid"
|
||||
@ -611,7 +623,7 @@
|
||||
#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
|
||||
|
||||
/* version number for resource files */
|
||||
#define RSRC_PACKAGE_VERSION 1,6,1,0
|
||||
#define RSRC_PACKAGE_VERSION 1,6,2,0
|
||||
|
||||
/* Directory to chdir to */
|
||||
#define RUN_DIR "/var/unbound"
|
||||
@ -652,6 +664,9 @@
|
||||
/* 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 dnstap support */
|
||||
/* #undef USE_DNSTAP */
|
||||
|
||||
@ -676,6 +691,9 @@
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
/* #undef USE_OSX_MSG_FASTOPEN */
|
||||
|
||||
/* Define this to enable SHA1 support. */
|
||||
#define USE_SHA1 1
|
||||
|
||||
/* Define this to enable SHA256 and SHA512 support. */
|
||||
#define USE_SHA2 1
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
/* 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
|
||||
|
||||
@ -385,6 +388,9 @@
|
||||
/* 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
|
||||
|
||||
@ -457,6 +463,9 @@
|
||||
/* 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
|
||||
|
||||
@ -466,6 +475,9 @@
|
||||
/* 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
|
||||
|
||||
@ -651,6 +663,9 @@
|
||||
/* 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 dnstap support */
|
||||
#undef USE_DNSTAP
|
||||
|
||||
@ -675,6 +690,9 @@
|
||||
/* 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
|
||||
|
||||
|
220
contrib/unbound/configure
vendored
220
contrib/unbound/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.6.1.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.6.2.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
|
||||
#
|
||||
@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.6.1'
|
||||
PACKAGE_STRING='unbound 1.6.1'
|
||||
PACKAGE_VERSION='1.6.2'
|
||||
PACKAGE_STRING='unbound 1.6.2'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -638,6 +638,9 @@ INSTALLTARGET
|
||||
ALLTARGET
|
||||
SOURCEFILE
|
||||
SOURCEDETERMINE
|
||||
DNSCRYPT_OBJ
|
||||
DNSCRYPT_SRC
|
||||
ENABLE_DNSCRYPT
|
||||
DNSTAP_OBJ
|
||||
DNSTAP_SRC
|
||||
opt_dnstap_socket_path
|
||||
@ -671,6 +674,8 @@ staticexe
|
||||
PC_LIBEVENT_DEPENDENCY
|
||||
UNBOUND_EVENT_UNINSTALL
|
||||
UNBOUND_EVENT_INSTALL
|
||||
SUBNET_HEADER
|
||||
SUBNET_OBJ
|
||||
SSLLIB
|
||||
HAVE_SSL
|
||||
CONFIG_DATE
|
||||
@ -840,7 +845,9 @@ with_pythonmodule
|
||||
with_nss
|
||||
with_nettle
|
||||
with_ssl
|
||||
enable_sha1
|
||||
enable_sha2
|
||||
enable_subnet
|
||||
enable_gost
|
||||
enable_ecdsa
|
||||
enable_dsa
|
||||
@ -857,6 +864,8 @@ enable_dnstap
|
||||
with_dnstap_socket_path
|
||||
with_protobuf_c
|
||||
with_libfstrm
|
||||
enable_dnscrypt
|
||||
with_libsodium
|
||||
enable_cachedb
|
||||
with_libunbound_only
|
||||
'
|
||||
@ -1420,7 +1429,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.6.1 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.6.2 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1485,7 +1494,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.6.1:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.6.2:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1515,7 +1524,10 @@ Optional Features:
|
||||
enable nonregional allocs, slow but exposes regional
|
||||
allocations to other memory purifiers, for debug
|
||||
purposes
|
||||
--disable-sha1 Disable SHA1 RRSIG support, does not disable nsec3
|
||||
support
|
||||
--disable-sha2 Disable SHA256 and SHA512 RRSIG support
|
||||
--enable-subnet Enable client subnet
|
||||
--disable-gost Disable GOST support
|
||||
--disable-ecdsa Disable ECDSA support
|
||||
--disable-dsa Disable DSA support
|
||||
@ -1532,6 +1544,7 @@ Optional Features:
|
||||
to it, smaller install size but libunbound export
|
||||
table is polluted by internal symbols
|
||||
--enable-dnstap Enable dnstap support (requires fstrm, protobuf-c)
|
||||
--enable-dnscrypt Enable dnscrypt support (requires libsodium)
|
||||
--enable-cachedb enable cachedb module that can use external cache
|
||||
storage
|
||||
|
||||
@ -1586,6 +1599,7 @@ Optional Packages:
|
||||
set default dnstap socket path
|
||||
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
|
||||
--with-libfstrm=path Path where libfstrm is installed, for dnstap
|
||||
--with-libsodium=path Path where libsodium is installed, for dnscrypt
|
||||
--with-libunbound-only do not build daemon and tool programs
|
||||
|
||||
Some influential environment variables:
|
||||
@ -1689,7 +1703,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.6.1
|
||||
unbound configure 1.6.2
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -2398,7 +2412,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.6.1, which was
|
||||
It was created by unbound $as_me 1.6.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2750,12 +2764,12 @@ UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=6
|
||||
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
UNBOUND_VERSION_MICRO=2
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=6
|
||||
LIBUNBOUND_REVISION=4
|
||||
LIBUNBOUND_AGE=4
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_AGE=5
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@ -2806,6 +2820,7 @@ LIBUNBOUND_AGE=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
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -4104,7 +4119,7 @@ fi
|
||||
if test $on_mingw = "no"; then
|
||||
ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
|
||||
else
|
||||
ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
|
||||
ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
|
||||
fi
|
||||
|
||||
# Check whether --with-conf_file was given.
|
||||
@ -4235,7 +4250,7 @@ else
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
|
||||
else
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key"
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
|
||||
fi
|
||||
|
||||
fi
|
||||
@ -4257,7 +4272,7 @@ else
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
|
||||
else
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem"
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
|
||||
fi
|
||||
|
||||
fi
|
||||
@ -14422,7 +14437,7 @@ CC=$lt_save_CC
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
@ -16717,8 +16732,7 @@ fi
|
||||
#
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
|
||||
$as_echo_n "checking for the distutils Python package... " >&6; }
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@ -16908,7 +16922,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5
|
||||
$as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
|
||||
elif test -n "" ; then
|
||||
elif test -n "2.0.1" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5
|
||||
$as_echo_n "checking for SWIG version... " >&6; }
|
||||
swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`
|
||||
@ -16916,7 +16930,7 @@ $as_echo_n "checking for SWIG version... " >&6; }
|
||||
$as_echo "$swig_version" >&6; }
|
||||
if test -n "$swig_version" ; then
|
||||
# Calculate the required version number components
|
||||
required=
|
||||
required=2.0.1
|
||||
required_major=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_major" ; then
|
||||
required_major=0
|
||||
@ -16947,12 +16961,23 @@ $as_echo "$swig_version" >&6; }
|
||||
if test -z "$available_patch" ; then
|
||||
available_patch=0
|
||||
fi
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&5
|
||||
$as_echo "$as_me: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG version >= is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
badversion=0
|
||||
if test $available_major -lt $required_major ; then
|
||||
badversion=1
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -lt $required_minor ; then
|
||||
badversion=1
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -eq $required_minor \
|
||||
-a $available_patch -lt $required_patch ; then
|
||||
badversion=1
|
||||
fi
|
||||
if test $badversion -eq 1 ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 2.0.1 is required. You have $swig_version. You should look at http://www.swig.org" >&5
|
||||
$as_echo "$as_me: WARNING: SWIG version >= 2.0.1 is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG version >= 2.0.1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: SWIG executable is '$SWIG'" >&5
|
||||
$as_echo "$as_me: SWIG executable is '$SWIG'" >&6;}
|
||||
@ -17697,6 +17722,22 @@ fi
|
||||
|
||||
|
||||
|
||||
# Check whether --enable-sha1 was given.
|
||||
if test "${enable_sha1+set}" = set; then :
|
||||
enableval=$enable_sha1;
|
||||
fi
|
||||
|
||||
case "$enable_sha1" in
|
||||
no)
|
||||
;;
|
||||
yes|*)
|
||||
|
||||
$as_echo "#define USE_SHA1 1" >>confdefs.h
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Check whether --enable-sha2 was given.
|
||||
if test "${enable_sha2+set}" = set; then :
|
||||
enableval=$enable_sha2;
|
||||
@ -17712,6 +17753,25 @@ $as_echo "#define USE_SHA2 1" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-subnet was given.
|
||||
if test "${enable_subnet+set}" = set; then :
|
||||
enableval=$enable_subnet;
|
||||
fi
|
||||
|
||||
case "$enable_subnet" in
|
||||
yes)
|
||||
|
||||
$as_echo "#define CLIENT_SUBNET 1" >>confdefs.h
|
||||
|
||||
SUBNET_OBJ="edns-subnet.lo subnetmod.lo addrtree.lo subnet-whitelist.lo"
|
||||
|
||||
SUBNET_HEADER='$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/addrtree.h'
|
||||
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# check wether gost also works
|
||||
|
||||
# Check whether --enable-gost was given.
|
||||
@ -19251,7 +19311,7 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@ -20170,6 +20230,105 @@ _ACEOF
|
||||
fi
|
||||
|
||||
|
||||
# check for dnscrypt if requested
|
||||
|
||||
# Check whether --enable-dnscrypt was given.
|
||||
if test "${enable_dnscrypt+set}" = set; then :
|
||||
enableval=$enable_dnscrypt; opt_dnscrypt=$enableval
|
||||
else
|
||||
opt_dnscrypt=no
|
||||
fi
|
||||
|
||||
|
||||
if test "x$opt_dnscrypt" != "xno"; then
|
||||
|
||||
# Check whether --with-libsodium was given.
|
||||
if test "${with_libsodium+set}" = set; then :
|
||||
withval=$with_libsodium;
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sodium_init" >&5
|
||||
$as_echo_n "checking for library containing sodium_init... " >&6; }
|
||||
if ${ac_cv_search_sodium_init+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char sodium_init ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return sodium_init ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' sodium; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_sodium_init=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_sodium_init+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_sodium_init+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_sodium_init=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sodium_init" >&5
|
||||
$as_echo "$ac_cv_search_sodium_init" >&6; }
|
||||
ac_res=$ac_cv_search_sodium_init
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "The sodium library was not found. Please install sodium!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
|
||||
$as_echo "#define USE_DNSCRYPT 1" >>confdefs.h
|
||||
|
||||
ENABLE_DNSCRYPT=1
|
||||
|
||||
|
||||
DNSCRYPT_SRC="dnscrypt/dnscrypt.c"
|
||||
|
||||
DNSCRYPT_OBJ="dnscrypt.lo"
|
||||
|
||||
|
||||
else
|
||||
|
||||
ENABLE_DNSCRYPT=0
|
||||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# check for cachedb if requested
|
||||
# Check whether --enable-cachedb was given.
|
||||
if test "${enable_cachedb+set}" = set; then :
|
||||
@ -20328,12 +20487,12 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.6.1
|
||||
version=1.6.2
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
|
||||
ac_config_files="$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 contrib/unbound.socket contrib/unbound.service"
|
||||
ac_config_files="$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_headers="$ac_config_headers config.h"
|
||||
|
||||
@ -20847,7 +21006,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.6.1, which was
|
||||
This file was extended by unbound $as_me 1.6.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -20913,7 +21072,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.6.1
|
||||
unbound config.status 1.6.2
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@ -21335,6 +21494,7 @@ do
|
||||
"doc/unbound-host.1") CONFIG_FILES="$CONFIG_FILES doc/unbound-host.1" ;;
|
||||
"smallapp/unbound-control-setup.sh") CONFIG_FILES="$CONFIG_FILES smallapp/unbound-control-setup.sh" ;;
|
||||
"dnstap/dnstap_config.h") CONFIG_FILES="$CONFIG_FILES dnstap/dnstap_config.h" ;;
|
||||
"dnscrypt/dnscrypt_config.h") CONFIG_FILES="$CONFIG_FILES dnscrypt/dnscrypt_config.h" ;;
|
||||
"contrib/libunbound.pc") CONFIG_FILES="$CONFIG_FILES contrib/libunbound.pc" ;;
|
||||
"contrib/unbound.socket") CONFIG_FILES="$CONFIG_FILES contrib/unbound.socket" ;;
|
||||
"contrib/unbound.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound.service" ;;
|
||||
|
@ -6,19 +6,20 @@ 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],[1])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=6
|
||||
LIBUNBOUND_REVISION=4
|
||||
LIBUNBOUND_AGE=4
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_AGE=5
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@ -69,6 +70,7 @@ LIBUNBOUND_AGE=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
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -120,7 +122,7 @@ fi
|
||||
if test $on_mingw = "no"; then
|
||||
ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
|
||||
else
|
||||
ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
|
||||
ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
|
||||
fi
|
||||
AC_ARG_WITH([conf_file],
|
||||
AC_HELP_STRING([--with-conf-file=path],
|
||||
@ -190,7 +192,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 (x86)\\Unbound\\root.key"
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
|
||||
fi
|
||||
)
|
||||
AC_SUBST(UNBOUND_ROOTKEY_FILE)
|
||||
@ -204,7 +206,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 (x86)\\Unbound\\icannbundle.pem"
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
|
||||
fi
|
||||
)
|
||||
AC_SUBST(UNBOUND_ROOTCERT_FILE)
|
||||
@ -304,7 +306,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],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
@ -550,7 +552,7 @@ if test x_$ub_test_python != x_no; then
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
AC_PROG_SWIG
|
||||
AC_PROG_SWIG(2.0.1)
|
||||
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])
|
||||
@ -709,6 +711,16 @@ 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)
|
||||
@ -718,6 +730,19 @@ 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])
|
||||
@ -1148,7 +1173,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])
|
||||
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([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
@ -1303,6 +1328,19 @@ 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
|
||||
@ -1606,6 +1644,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 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 dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
@ -1,8 +1,28 @@
|
||||
[Service]
|
||||
Type=notify
|
||||
NotifyAccess=main
|
||||
ExecStart=/home/vagrant/unbound_systemd/unbound
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStart=/home/vagrant/unbound_systemd/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=/etc/unbound /run
|
||||
RestrictAddressFamilies=AF_INET AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
#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"
|
||||
@ -86,6 +87,7 @@
|
||||
#include "util/tube.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "respip/respip.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
@ -561,6 +563,8 @@ 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");
|
||||
@ -570,15 +574,44 @@ 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.
|
||||
*/
|
||||
@ -605,6 +638,9 @@ 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");
|
||||
@ -619,6 +655,9 @@ daemon_fork(struct daemon* daemon)
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -638,6 +677,8 @@ 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() */
|
||||
@ -670,7 +711,6 @@ 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);
|
||||
|
@ -56,12 +56,19 @@ 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.
|
||||
@ -117,6 +124,15 @@ 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
|
||||
};
|
||||
|
||||
|
@ -242,6 +242,29 @@ 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
|
||||
#ifdef SHA256_DIGEST_LENGTH
|
||||
/* 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("coult not set cipher list with SSL_CTX_set_cipher_list");
|
||||
#endif
|
||||
|
||||
if (cfg->remote_control_use_cert == 0) {
|
||||
/* No certificates are requested */
|
||||
@ -775,6 +798,16 @@ print_stats(SSL* ssl, const char* nm, struct 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/
|
||||
@ -830,11 +863,15 @@ static int
|
||||
print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
|
||||
{
|
||||
int m;
|
||||
size_t msg, rrset, val, iter;
|
||||
size_t msg, rrset, val, iter, respip;
|
||||
#ifdef CLIENT_SUBNET
|
||||
size_t subnet = 0;
|
||||
#endif /* CLIENT_SUBNET */
|
||||
msg = slabhash_get_mem(daemon->env->msg_cache);
|
||||
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
|
||||
val=0;
|
||||
iter=0;
|
||||
respip=0;
|
||||
m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
if(m != -1) {
|
||||
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
|
||||
@ -849,6 +886,22 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
|
||||
iter = (*worker->env.mesh->mods.mod[m]->get_mem)
|
||||
(&worker->env, m);
|
||||
}
|
||||
m = modstack_find(&worker->env.mesh->mods, "respip");
|
||||
if(m != -1) {
|
||||
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
|
||||
mods.mod[m]->get_mem));
|
||||
respip = (*worker->env.mesh->mods.mod[m]->get_mem)
|
||||
(&worker->env, m);
|
||||
}
|
||||
#ifdef CLIENT_SUBNET
|
||||
m = modstack_find(&worker->env.mesh->mods, "subnet");
|
||||
if(m != -1) {
|
||||
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
|
||||
mods.mod[m]->get_mem));
|
||||
subnet = (*worker->env.mesh->mods.mod[m]->get_mem)
|
||||
(&worker->env, m);
|
||||
}
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
|
||||
return 0;
|
||||
@ -858,6 +911,12 @@ 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 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1342,6 +1401,13 @@ 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;
|
||||
}
|
||||
}
|
||||
do_zone_add(ssl, v->local_zones, arg2);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
@ -1360,6 +1426,11 @@ 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);
|
||||
}
|
||||
@ -1378,6 +1449,13 @@ 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);
|
||||
}
|
||||
@ -1396,6 +1474,11 @@ 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);
|
||||
}
|
||||
@ -2531,7 +2614,9 @@ do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg)
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_list_local_zones(ssl, v->local_zones);
|
||||
if(v->local_zones) {
|
||||
do_list_local_zones(ssl, v->local_zones);
|
||||
}
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
@ -2545,7 +2630,9 @@ do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg)
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_list_local_data(ssl, worker, v->local_zones);
|
||||
if(v->local_zones) {
|
||||
do_list_local_data(ssl, worker, v->local_zones);
|
||||
}
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
|
@ -232,6 +232,14 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
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;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#ifndef DAEMON_STATS_H
|
||||
#define DAEMON_STATS_H
|
||||
#include "util/timehist.h"
|
||||
#include "dnscrypt/dnscrypt_config.h"
|
||||
struct worker;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
@ -149,6 +150,16 @@ struct server_stats {
|
||||
size_t infra_cache_count;
|
||||
/** number of key cache entries */
|
||||
size_t key_cache_count;
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** number of queries that used dnscrypt */
|
||||
size_t num_query_dnscrypt_crypted;
|
||||
/** number of queries that queried dnscrypt certificates */
|
||||
size_t num_query_dnscrypt_cert;
|
||||
/** number of queries in clear text and not asking for the certificates */
|
||||
size_t num_query_dnscrypt_cleartext;
|
||||
/** number of malformed encrypted queries */
|
||||
size_t num_query_dnscrypt_crypted_malformed;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -69,9 +69,13 @@
|
||||
#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>
|
||||
@ -113,6 +117,9 @@ 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);
|
||||
@ -132,6 +139,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 */
|
||||
else iter += (*worker->env.mesh->mods.mod[i]->get_mem)
|
||||
(&worker->env, i);
|
||||
}
|
||||
@ -149,6 +162,17 @@ 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",
|
||||
@ -156,11 +180,15 @@ 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;
|
||||
@ -170,12 +198,27 @@ 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 */
|
||||
}
|
||||
|
||||
@ -510,17 +553,70 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** answer query from the cache */
|
||||
/** 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. */
|
||||
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))
|
||||
@ -600,7 +696,33 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
goto bail_out;
|
||||
if(!reply_info_answer_encode(qinfo, rep, id, flags,
|
||||
*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,
|
||||
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,
|
||||
@ -621,14 +743,18 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Reply to client and perform prefetch to keep cache up to date */
|
||||
/** 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). */
|
||||
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 */
|
||||
comm_point_send_reply(repinfo);
|
||||
if(sldns_buffer_limit(repinfo->c->buffer) != 0)
|
||||
comm_point_send_reply(repinfo);
|
||||
server_stats_prefetch(&worker->stats, worker);
|
||||
|
||||
/* create the prefetch in the mesh as a normal lookup without
|
||||
@ -643,36 +769,41 @@ 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, const char* str, struct edns_data* edns,
|
||||
chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
struct worker* worker)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
int i;
|
||||
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, 1); /* ancount */
|
||||
sldns_buffer_write_u16(pkt, (uint16_t)num); /* 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 */
|
||||
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);
|
||||
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_flip(pkt);
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@ -683,6 +814,70 @@ chaos_replystr(sldns_buffer* pkt, const char* str, struct edns_data* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer CH class queries.
|
||||
* @param w: worker
|
||||
@ -709,13 +904,13 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
char buf[MAXHOSTNAMELEN+1];
|
||||
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
|
||||
buf[MAXHOSTNAMELEN] = 0;
|
||||
chaos_replystr(pkt, buf, edns, w);
|
||||
chaos_replyonestr(pkt, buf, edns, w);
|
||||
} else {
|
||||
log_err("gethostname: %s", strerror(errno));
|
||||
chaos_replystr(pkt, "no hostname", edns, w);
|
||||
chaos_replyonestr(pkt, "no hostname", edns, w);
|
||||
}
|
||||
}
|
||||
else chaos_replystr(pkt, cfg->identity, edns, w);
|
||||
else chaos_replyonestr(pkt, cfg->identity, edns, w);
|
||||
return 1;
|
||||
}
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
@ -726,10 +921,19 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
if(cfg->hide_version)
|
||||
return 0;
|
||||
if(cfg->version==NULL || cfg->version[0]==0)
|
||||
chaos_replystr(pkt, PACKAGE_STRING, edns, w);
|
||||
else chaos_replystr(pkt, cfg->version, edns, w);
|
||||
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w);
|
||||
else chaos_replyonestr(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;
|
||||
}
|
||||
|
||||
@ -794,12 +998,60 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
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,
|
||||
@ -1036,16 +1288,43 @@ 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(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
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 */
|
||||
/* 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. */
|
||||
if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
|
||||
&& *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) {
|
||||
@ -1055,16 +1334,38 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
< *worker->env.now)
|
||||
leeway = 0;
|
||||
lock_rw_unlock(&e->lock);
|
||||
reply_and_prefetch(worker, &qinfo,
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway);
|
||||
rc = 0;
|
||||
if(!partial_rep) {
|
||||
rc = 0;
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply_rc;
|
||||
}
|
||||
} else if(!partial_rep) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply_rc;
|
||||
goto send_reply;
|
||||
}
|
||||
/* 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);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
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;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer from the cache failed");
|
||||
lock_rw_unlock(&e->lock);
|
||||
@ -1093,7 +1394,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
|
||||
/* grab a work request structure for this new request */
|
||||
mesh_new_client(worker->env.mesh, &qinfo,
|
||||
mesh_new_client(worker->env.mesh, &qinfo, cinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer));
|
||||
regional_free_all(worker->scratchpad);
|
||||
@ -1103,6 +1404,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
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,
|
||||
@ -1114,6 +1419,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1169,6 +1479,10 @@ 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);
|
||||
}
|
||||
|
@ -411,31 +411,6 @@ 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)
|
||||
{
|
||||
@ -707,7 +682,7 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
return;
|
||||
|
||||
/* allocate ub_key structures special or not */
|
||||
if(!repinfo_alloc_rrset_keys(cp, super->region)) {
|
||||
if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
32
contrib/unbound/dnscrypt/cert.h
Normal file
32
contrib/unbound/dnscrypt/cert.h
Normal file
@ -0,0 +1,32 @@
|
||||
#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 server_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t magic_query[8];
|
||||
uint8_t serial[4];
|
||||
uint8_t ts_begin[4];
|
||||
uint8_t ts_end[4];
|
||||
uint8_t end[64];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
531
contrib/unbound/dnscrypt/dnscrypt.c
Normal file
531
contrib/unbound/dnscrypt/dnscrypt.c
Normal file
@ -0,0 +1,531 @@
|
||||
|
||||
#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 <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 keypair that was found using dnsc_find_keypair.
|
||||
* 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] keypair the keypair 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 KeyPair *keypair,
|
||||
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 (crypto_box_beforenm(nmkey, nmkey, 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);
|
||||
|
||||
sldns_buffer_set_at(buffer,
|
||||
DNSCRYPT_QUERY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
0, crypto_box_BOXZEROBYTES);
|
||||
|
||||
if (crypto_box_open_afternm
|
||||
(buf + DNSCRYPT_QUERY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
buf + DNSCRYPT_QUERY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
len - DNSCRYPT_QUERY_BOX_OFFSET + crypto_box_BOXZEROBYTES, nonce,
|
||||
nmkey) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (*sldns_buffer_at(buffer, --len) == 0)
|
||||
;
|
||||
|
||||
if (*sldns_buffer_at(buffer, len) != 0x80) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
|
||||
memmove(sldns_buffer_begin(buffer),
|
||||
sldns_buffer_at(buffer, DNSCRYPT_QUERY_HEADER_SIZE),
|
||||
len - DNSCRYPT_QUERY_HEADER_SIZE);
|
||||
|
||||
sldns_buffer_set_position(buffer, 0);
|
||||
sldns_buffer_set_limit(buffer, len - DNSCRYPT_QUERY_HEADER_SIZE);
|
||||
|
||||
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 keypair 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] keypair the keypair 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 KeyPair *keypair,
|
||||
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,
|
||||
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 (crypto_box_afternm
|
||||
(boxed - crypto_box_BOXZEROBYTES, boxed - crypto_box_BOXZEROBYTES,
|
||||
len + crypto_box_ZEROBYTES, 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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++) {
|
||||
if(dnsc_read_from_file(
|
||||
head->str,
|
||||
(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 keypair matching a DNSCrypt query.
|
||||
* \param[in] dnscenv The DNSCrypt enviroment, which contains the list of keys
|
||||
* supported by the server.
|
||||
* \param[in] buffer The encrypted DNS query.
|
||||
* \return a KeyPair * if we found a key pair matching the query, NULL otherwise.
|
||||
*/
|
||||
static const KeyPair *
|
||||
dnsc_find_keypair(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
|
||||
{
|
||||
const KeyPair *keypairs = dnscenv->keypairs;
|
||||
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->keypairs_count; i++) {
|
||||
if (memcmp(keypairs[i].crypt_publickey, dnscrypt_header->magic_query,
|
||||
DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
|
||||
return &keypairs[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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the secret key files from `dnscrypt-secret-key` config and populates
|
||||
* a list of 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 keypair_id;
|
||||
|
||||
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);
|
||||
|
||||
keypair_id = 0U;
|
||||
for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) {
|
||||
char fingerprint[80];
|
||||
if(dnsc_read_from_file(
|
||||
head->str,
|
||||
(char *)(env->keypairs[keypair_id].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(env->keypairs[keypair_id].crypt_publickey,
|
||||
env->keypairs[keypair_id].crypt_secretkey) != 0) {
|
||||
fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str);
|
||||
}
|
||||
dnsc_key_to_fingerprint(fingerprint, env->keypairs[keypair_id].crypt_publickey);
|
||||
verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint);
|
||||
}
|
||||
return keypair_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->keypair = dnsc_find_keypair(dnscenv, c->buffer)) != NULL) {
|
||||
if(dnscrypt_server_uncurve(repinfo->keypair,
|
||||
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->keypair,
|
||||
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;
|
||||
}
|
102
contrib/unbound/dnscrypt/dnscrypt.h
Normal file
102
contrib/unbound/dnscrypt/dnscrypt.h
Normal file
@ -0,0 +1,102 @@
|
||||
#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;
|
||||
|
||||
struct dnsc_env {
|
||||
struct SignedCert *signed_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
|
25
contrib/unbound/dnscrypt/dnscrypt.m4
Normal file
25
contrib/unbound/dnscrypt/dnscrypt.m4
Normal file
@ -0,0 +1,25 @@
|
||||
# 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!]))
|
||||
$1
|
||||
else
|
||||
$2
|
||||
fi
|
||||
])
|
17
contrib/unbound/dnscrypt/dnscrypt_config.h.in
Normal file
17
contrib/unbound/dnscrypt/dnscrypt_config.h.in
Normal file
@ -0,0 +1,17 @@
|
||||
#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 */
|
Binary file not shown.
@ -1,5 +1,187 @@
|
||||
13 April 2017: Wouter
|
||||
- Fix #1250: inconsistent indentation in services/listen_dnsport.c.
|
||||
- tag for 1.6.2rc1
|
||||
|
||||
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.
|
||||
- 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.
|
||||
|
BIN
contrib/unbound/doc/IP-BasedActions.pdf
Normal file
BIN
contrib/unbound/doc/IP-BasedActions.pdf
Normal file
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
README for Unbound 1.6.1
|
||||
README for Unbound 1.6.2
|
||||
Copyright 2007 NLnet Labs
|
||||
http://unbound.net
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.6.1.
|
||||
# See unbound.conf(5) man page, version 1.6.2.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@ -19,6 +19,14 @@ 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
|
||||
|
||||
@ -309,6 +317,9 @@ 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: ""
|
||||
|
||||
@ -771,7 +782,28 @@ 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
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.6.1.
|
||||
# See unbound.conf(5) man page, version 1.6.2.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@ -19,6 +19,14 @@ 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
|
||||
|
||||
@ -309,6 +317,9 @@ 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: ""
|
||||
|
||||
@ -771,7 +782,28 @@ 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "libunbound" "3" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "libunbound" "3" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" libunbound.3 -- unbound library functions manual
|
||||
.\"
|
||||
@ -43,7 +43,7 @@
|
||||
.B ub_ctx_zone_remove,
|
||||
.B ub_ctx_data_add,
|
||||
.B ub_ctx_data_remove
|
||||
\- Unbound DNS validating resolver 1.6.1 functions.
|
||||
\- Unbound DNS validating resolver 1.6.2 functions.
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <unbound.h>
|
||||
.LP
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "libunbound" "3" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "libunbound" "3" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" libunbound.3 -- unbound library functions manual
|
||||
.\"
|
||||
@ -43,7 +43,7 @@
|
||||
.B ub_ctx_zone_remove,
|
||||
.B ub_ctx_data_add,
|
||||
.B ub_ctx_data_remove
|
||||
\- Unbound DNS validating resolver 1.6.1 functions.
|
||||
\- Unbound DNS validating resolver 1.6.2 functions.
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <unbound.h>
|
||||
.LP
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-anchor" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound-anchor" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-anchor" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound-anchor" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-checkconf" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound-checkconf" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-checkconf" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound-checkconf" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-control" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound-control" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-control.8 -- unbound remote control manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-control" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound-control" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-control.8 -- unbound remote control manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound\-host" "1" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound\-host" "1" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-host.1 -- unbound DNS lookup utility
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound\-host" "1" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound\-host" "1" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound-host.1 -- unbound DNS lookup utility
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound.8 -- unbound manual
|
||||
.\"
|
||||
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.B unbound
|
||||
\- Unbound DNS validating resolver 1.6.1.
|
||||
\- Unbound DNS validating resolver 1.6.2.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound
|
||||
.RB [ \-h ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound" "8" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound" "8" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound.8 -- unbound manual
|
||||
.\"
|
||||
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.B unbound
|
||||
\- Unbound DNS validating resolver 1.6.1.
|
||||
\- Unbound DNS validating resolver 1.6.2.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound
|
||||
.RB [ \-h ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound.conf" "5" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound.conf" "5" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound.conf.5 -- unbound.conf manual
|
||||
.\"
|
||||
@ -596,6 +596,9 @@ If enabled version.server and version.bind queries are refused.
|
||||
Set the version to report. If set to "", the default, then the package
|
||||
version is returned.
|
||||
.TP
|
||||
.B hide\-trustanchor: \fI<yes or no>
|
||||
If enabled trustanchor.unbound queries are refused.
|
||||
.TP
|
||||
.B target\-fetch\-policy: \fI<"list of numbers">
|
||||
Set the target fetch policy used by unbound to determine if it should fetch
|
||||
nameserver target addresses opportunistically. The policy is described per
|
||||
@ -782,7 +785,8 @@ frequently. The initial file can be one with contents as described in
|
||||
\fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated,
|
||||
so the unbound user must have write permission. Write permission to the file,
|
||||
but also to the directory it is in (to create a temporary file, which is
|
||||
necessary to deal with filesystem full events).
|
||||
necessary to deal with filesystem full events), it must also be inside the
|
||||
chroot (if that is used).
|
||||
.TP
|
||||
.B trust\-anchor: \fI<"Resource Record">
|
||||
A DS or DNSKEY RR for a key to use for validation. Multiple entries can be
|
||||
@ -1403,6 +1407,10 @@ global local\-zone elements.
|
||||
View specific local\-data elements. Has the same behaviour as the global
|
||||
local\-data elements.
|
||||
.TP
|
||||
.B local\-data\-ptr: \fI"IPaddr name"
|
||||
View specific local\-data\-ptr elements. Has the same behaviour as the global
|
||||
local\-data\-ptr elements.
|
||||
.TP
|
||||
.B view\-first: \fI<yes or no>
|
||||
If enabled, it attempts to use the global local\-zone and local\-data if there
|
||||
is no match in the view specific options.
|
||||
@ -1438,6 +1446,79 @@ It must be /96 or shorter. The default prefix is 64:ff9b::/96.
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
.SS "DNSCrypt Options"
|
||||
.LP
|
||||
The
|
||||
.B dnscrypt:
|
||||
clause give the settings of the dnscrypt channel. While those options are
|
||||
available, they are only meaningful if unbound was compiled with
|
||||
\fB\-\-enable\-dnscrypt\fR.
|
||||
Currently certificate and secret/public keys cannot be generated by unbound.
|
||||
You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
|
||||
.TP
|
||||
.B dnscrypt\-enable: \fI<yes or no>\fR
|
||||
Whether or not the \fBdnscrypt\fR config should be enabled. You may define
|
||||
configuration but not activate it.
|
||||
The default is no.
|
||||
.TP
|
||||
.B dnscrypt\-port: \fI<port number>
|
||||
On which port should \fBdnscrypt\fR should be activated. Note that you should
|
||||
have a matching \fBinterface\fR option defined in the \fBserver\fR section for
|
||||
this port.
|
||||
.TP
|
||||
.B dnscrypt\-provider: \fI<provider name>\fR
|
||||
The provider name to use to distribute certificates. This is of the form:
|
||||
\fB2.dnscrypt-cert.example.com.\fR. The name \fIMUST\fR end with a dot.
|
||||
.TP
|
||||
.B dnscrypt\-secret\-key: \fI<path to secret key file>\fR
|
||||
Path to the time limited secret key file. This option may be specified multiple
|
||||
times.
|
||||
.TP
|
||||
.B dnscrypt\-provider\-cert: \fI<path to cert file>\fR
|
||||
Path to the certificate related to the \fBdnscrypt\-secret\-key\fRs. This option
|
||||
may be specified multiple times.
|
||||
.SS "EDNS Client Subnet Module Options"
|
||||
.LP
|
||||
The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache
|
||||
validator iterator" directive and be compiled into the daemon to be
|
||||
enabled. These settings go in the \fBserver:\fR section.
|
||||
.LP
|
||||
If the destination address is whitelisted with Unbound will add the EDNS0 option
|
||||
to the query containing the relevant part of the client's address. When an
|
||||
answer contains the ECS option the response and the option are placed in a
|
||||
specialized cache. If the authority indicated no support, the response is stored
|
||||
in the regular cache.
|
||||
.LP
|
||||
Additionally, when a client includes the option in its queries, Unbound will
|
||||
forward the option to the authority regardless of the authorities presence in
|
||||
the whitelist. In this case the lookup in the regular cache is skipped.
|
||||
.LP
|
||||
The maximum size of the ECS cache is controlled by 'msg-cache-size' in the
|
||||
configuration file. On top of that, for each query only 100 different subnets
|
||||
are allowed to be stored for each address family. Exceeding that number, older
|
||||
entries will be purged from cache.
|
||||
.TP
|
||||
.B send\-client\-subnet: \fI<IP address>\fR
|
||||
Send client source address to this authority. Append /num to indicate a
|
||||
classless delegation netblock, for example like 10.2.3.4/24 or 2001::11/64. Can
|
||||
be given multiple times. Authorities not listed will not receive edns-subnet
|
||||
information.
|
||||
.TP
|
||||
.B client\-subnet\-always\-forward: \fI<yes or no>\fR
|
||||
Specify whether the ECS whitelist check (configured using
|
||||
\fBsend\-client\-subnet\fR) is applied for all queries, even if the triggering
|
||||
query contains an ECS record, or only for queries for which the ECS record is
|
||||
generated using the querier address (and therefore did not contain ECS data in
|
||||
the client query). If enabled, the whitelist check is skipped when the client
|
||||
query contains an ECS record. Default is no.
|
||||
.TP
|
||||
.B max\-client\-subnet\-ipv6: \fI<number>\fR
|
||||
Specifies the maximum prefix length of the client source address we are willing
|
||||
to expose to third parties for IPv6. Defaults to 56.
|
||||
.TP
|
||||
.B max\-client\-subnet\-ipv4: \fI<number>\fR
|
||||
Specifies the maximum prefix length of the client source address we are willing
|
||||
to expose to third parties for IPv4. Defaults to 24.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound.conf" "5" "Feb 21, 2017" "NLnet Labs" "unbound 1.6.1"
|
||||
.TH "unbound.conf" "5" "Apr 24, 2017" "NLnet Labs" "unbound 1.6.2"
|
||||
.\"
|
||||
.\" unbound.conf.5 -- unbound.conf manual
|
||||
.\"
|
||||
@ -596,6 +596,9 @@ If enabled version.server and version.bind queries are refused.
|
||||
Set the version to report. If set to "", the default, then the package
|
||||
version is returned.
|
||||
.TP
|
||||
.B hide\-trustanchor: \fI<yes or no>
|
||||
If enabled trustanchor.unbound queries are refused.
|
||||
.TP
|
||||
.B target\-fetch\-policy: \fI<"list of numbers">
|
||||
Set the target fetch policy used by unbound to determine if it should fetch
|
||||
nameserver target addresses opportunistically. The policy is described per
|
||||
@ -782,7 +785,8 @@ frequently. The initial file can be one with contents as described in
|
||||
\fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated,
|
||||
so the unbound user must have write permission. Write permission to the file,
|
||||
but also to the directory it is in (to create a temporary file, which is
|
||||
necessary to deal with filesystem full events).
|
||||
necessary to deal with filesystem full events), it must also be inside the
|
||||
chroot (if that is used).
|
||||
.TP
|
||||
.B trust\-anchor: \fI<"Resource Record">
|
||||
A DS or DNSKEY RR for a key to use for validation. Multiple entries can be
|
||||
@ -1403,6 +1407,10 @@ global local\-zone elements.
|
||||
View specific local\-data elements. Has the same behaviour as the global
|
||||
local\-data elements.
|
||||
.TP
|
||||
.B local\-data\-ptr: \fI"IPaddr name"
|
||||
View specific local\-data\-ptr elements. Has the same behaviour as the global
|
||||
local\-data\-ptr elements.
|
||||
.TP
|
||||
.B view\-first: \fI<yes or no>
|
||||
If enabled, it attempts to use the global local\-zone and local\-data if there
|
||||
is no match in the view specific options.
|
||||
@ -1438,6 +1446,79 @@ It must be /96 or shorter. The default prefix is 64:ff9b::/96.
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
.SS "DNSCrypt Options"
|
||||
.LP
|
||||
The
|
||||
.B dnscrypt:
|
||||
clause give the settings of the dnscrypt channel. While those options are
|
||||
available, they are only meaningful if unbound was compiled with
|
||||
\fB\-\-enable\-dnscrypt\fR.
|
||||
Currently certificate and secret/public keys cannot be generated by unbound.
|
||||
You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
|
||||
.TP
|
||||
.B dnscrypt\-enable: \fI<yes or no>\fR
|
||||
Whether or not the \fBdnscrypt\fR config should be enabled. You may define
|
||||
configuration but not activate it.
|
||||
The default is no.
|
||||
.TP
|
||||
.B dnscrypt\-port: \fI<port number>
|
||||
On which port should \fBdnscrypt\fR should be activated. Note that you should
|
||||
have a matching \fBinterface\fR option defined in the \fBserver\fR section for
|
||||
this port.
|
||||
.TP
|
||||
.B dnscrypt\-provider: \fI<provider name>\fR
|
||||
The provider name to use to distribute certificates. This is of the form:
|
||||
\fB2.dnscrypt-cert.example.com.\fR. The name \fIMUST\fR end with a dot.
|
||||
.TP
|
||||
.B dnscrypt\-secret\-key: \fI<path to secret key file>\fR
|
||||
Path to the time limited secret key file. This option may be specified multiple
|
||||
times.
|
||||
.TP
|
||||
.B dnscrypt\-provider\-cert: \fI<path to cert file>\fR
|
||||
Path to the certificate related to the \fBdnscrypt\-secret\-key\fRs. This option
|
||||
may be specified multiple times.
|
||||
.SS "EDNS Client Subnet Module Options"
|
||||
.LP
|
||||
The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache
|
||||
validator iterator" directive and be compiled into the daemon to be
|
||||
enabled. These settings go in the \fBserver:\fR section.
|
||||
.LP
|
||||
If the destination address is whitelisted with Unbound will add the EDNS0 option
|
||||
to the query containing the relevant part of the client's address. When an
|
||||
answer contains the ECS option the response and the option are placed in a
|
||||
specialized cache. If the authority indicated no support, the response is stored
|
||||
in the regular cache.
|
||||
.LP
|
||||
Additionally, when a client includes the option in its queries, Unbound will
|
||||
forward the option to the authority regardless of the authorities presence in
|
||||
the whitelist. In this case the lookup in the regular cache is skipped.
|
||||
.LP
|
||||
The maximum size of the ECS cache is controlled by 'msg-cache-size' in the
|
||||
configuration file. On top of that, for each query only 100 different subnets
|
||||
are allowed to be stored for each address family. Exceeding that number, older
|
||||
entries will be purged from cache.
|
||||
.TP
|
||||
.B send\-client\-subnet: \fI<IP address>\fR
|
||||
Send client source address to this authority. Append /num to indicate a
|
||||
classless delegation netblock, for example like 10.2.3.4/24 or 2001::11/64. Can
|
||||
be given multiple times. Authorities not listed will not receive edns-subnet
|
||||
information.
|
||||
.TP
|
||||
.B client\-subnet\-always\-forward: \fI<yes or no>\fR
|
||||
Specify whether the ECS whitelist check (configured using
|
||||
\fBsend\-client\-subnet\fR) is applied for all queries, even if the triggering
|
||||
query contains an ECS record, or only for queries for which the ECS record is
|
||||
generated using the querier address (and therefore did not contain ECS data in
|
||||
the client query). If enabled, the whitelist check is skipped when the client
|
||||
query contains an ECS record. Default is no.
|
||||
.TP
|
||||
.B max\-client\-subnet\-ipv6: \fI<number>\fR
|
||||
Specifies the maximum prefix length of the client source address we are willing
|
||||
to expose to third parties for IPv6. Defaults to 56.
|
||||
.TP
|
||||
.B max\-client\-subnet\-ipv4: \fI<number>\fR
|
||||
Specifies the maximum prefix length of the client source address we are willing
|
||||
to expose to third parties for IPv4. Defaults to 24.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
531
contrib/unbound/edns-subnet/addrtree.c
Normal file
531
contrib/unbound/edns-subnet/addrtree.c
Normal file
@ -0,0 +1,531 @@
|
||||
/*
|
||||
* 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);
|
||||
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
contrib/unbound/edns-subnet/addrtree.h
Normal file
187
contrib/unbound/edns-subnet/addrtree.h
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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
contrib/unbound/edns-subnet/edns-subnet.c
Normal file
65
contrib/unbound/edns-subnet/edns-subnet.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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
contrib/unbound/edns-subnet/edns-subnet.h
Normal file
67
contrib/unbound/edns-subnet/edns-subnet.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 */
|
153
contrib/unbound/edns-subnet/subnet-whitelist.c
Normal file
153
contrib/unbound/edns-subnet/subnet-whitelist.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
struct ednssubnet_upstream*
|
||||
upstream_create(void)
|
||||
{
|
||||
struct ednssubnet_upstream* upstream =
|
||||
(struct ednssubnet_upstream*)calloc(1,
|
||||
sizeof(struct ednssubnet_upstream));
|
||||
if(!upstream)
|
||||
return NULL;
|
||||
upstream->region = regional_create();
|
||||
if(!upstream->region) {
|
||||
upstream_delete(upstream);
|
||||
return NULL;
|
||||
}
|
||||
return upstream;
|
||||
}
|
||||
|
||||
void
|
||||
upstream_delete(struct ednssubnet_upstream* upstream)
|
||||
{
|
||||
if(!upstream)
|
||||
return;
|
||||
regional_destroy(upstream->region);
|
||||
free(upstream);
|
||||
}
|
||||
|
||||
/** insert new address into upstream structure */
|
||||
static int
|
||||
upstream_insert(struct ednssubnet_upstream* upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int net)
|
||||
{
|
||||
struct addr_tree_node* node = (struct addr_tree_node*)regional_alloc(
|
||||
upstream->region, sizeof(*node));
|
||||
if(!node)
|
||||
return 0;
|
||||
if(!addr_tree_insert(&upstream->tree, 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 ednssubnet_upstream* upstream, 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(upstream, &addr, addrlen, net)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read client_subnet config */
|
||||
static int
|
||||
read_upstream(struct ednssubnet_upstream* upstream, 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(upstream, p->str))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
upstream_apply_cfg(struct ednssubnet_upstream* upstream,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
regional_free_all(upstream->region);
|
||||
addr_tree_init(&upstream->tree);
|
||||
if(!read_upstream(upstream, cfg))
|
||||
return 0;
|
||||
addr_tree_init_parents(&upstream->tree);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
upstream_is_whitelisted(struct ednssubnet_upstream* upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
{
|
||||
return addr_tree_lookup(&upstream->tree, addr, addrlen) != NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
upstream_get_mem(struct ednssubnet_upstream* upstream)
|
||||
{
|
||||
if(!upstream) return 0;
|
||||
return sizeof(*upstream) + regional_get_mem(upstream->region);
|
||||
}
|
||||
|
||||
#endif /* CLIENT_SUBNET */
|
102
contrib/unbound/edns-subnet/subnet-whitelist.h
Normal file
102
contrib/unbound/edns-subnet/subnet-whitelist.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 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;
|
||||
|
||||
/**
|
||||
* ednssubnet_upstream structure
|
||||
*/
|
||||
struct ednssubnet_upstream {
|
||||
/** 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 tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create ednssubnet_upstream structure
|
||||
* @return new structure or NULL on error.
|
||||
*/
|
||||
struct ednssubnet_upstream* upstream_create(void);
|
||||
|
||||
/**
|
||||
* Delete ednssubnet_upstream structure.
|
||||
* @param upstream: to delete.
|
||||
*/
|
||||
void upstream_delete(struct ednssubnet_upstream* upstream);
|
||||
|
||||
/**
|
||||
* Process ednssubnet_upstream config.
|
||||
* @param upstream: where to store.
|
||||
* @param cfg: config options.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int upstream_apply_cfg(struct ednssubnet_upstream* upstream,
|
||||
struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* See if an address is whitelisted.
|
||||
* @param upstream: structure for address storage.
|
||||
* @param addr: address to check
|
||||
* @param addrlen: length of addr.
|
||||
* @return: true if the address is whitelisted for subnet option.
|
||||
*/
|
||||
int upstream_is_whitelisted(struct ednssubnet_upstream* upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Get memory used by ednssubnet_upstream structure.
|
||||
* @param upstream: structure for address storage.
|
||||
* @return bytes in use.
|
||||
*/
|
||||
size_t upstream_get_mem(struct ednssubnet_upstream* upstream);
|
||||
|
||||
#endif /* EDNSSUBNET_WHITELIST_H */
|
808
contrib/unbound/edns-subnet/subnetmod.c
Normal file
808
contrib/unbound/edns-subnet/subnetmod.c
Normal file
@ -0,0 +1,808 @@
|
||||
/*
|
||||
* 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* ATTR_UNUSED(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) ||
|
||||
upstream_is_whitelisted(sn_env->edns_subnet_upstreams,
|
||||
addr, addrlen))) {
|
||||
/* 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->edns_subnet_upstreams = upstream_create();
|
||||
if(!sn_env->edns_subnet_upstreams ||
|
||||
!upstream_apply_cfg(sn_env->edns_subnet_upstreams, 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");
|
||||
upstream_delete(sn_env->edns_subnet_upstreams);
|
||||
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);
|
||||
upstream_delete(sn_env->edns_subnet_upstreams);
|
||||
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) +
|
||||
upstream_get_mem(sn_env->edns_subnet_upstreams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
contrib/unbound/edns-subnet/subnetmod.h
Normal file
130
contrib/unbound/edns-subnet/subnetmod.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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 ednssubnet_upstream* edns_subnet_upstreams;
|
||||
/** 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 */
|
@ -372,6 +372,29 @@ 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.
|
||||
@ -454,14 +477,16 @@ 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)) {
|
||||
dname_strict_subdomain_c(*mname, r->rk.dname) &&
|
||||
!iter_find_rrset_in_prepend_answer(iq, r)) {
|
||||
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) {
|
||||
query_dname_compare(*mname, r->rk.dname) == 0 &&
|
||||
!iter_find_rrset_in_prepend_answer(iq, r)) {
|
||||
/* Add this relevant CNAME rrset to the prepend list.*/
|
||||
if(!iter_add_prepend_answer(qstate, iq, r))
|
||||
return 0;
|
||||
@ -1326,7 +1351,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)) {
|
||||
if(!(qstate->query_flags & BIT_RD) && iq->deleg_msg) {
|
||||
iq->response = iq->deleg_msg;
|
||||
if(verbosity >= VERB_ALGO && iq->response)
|
||||
log_dns_msg("no RD requested, using delegation msg",
|
||||
@ -2169,6 +2194,10 @@ 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)
|
||||
@ -2233,6 +2262,22 @@ 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) {
|
||||
@ -3161,6 +3206,10 @@ 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 */
|
||||
|
@ -310,7 +310,6 @@ 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);
|
||||
|
1179
contrib/unbound/respip/respip.c
Normal file
1179
contrib/unbound/respip/respip.c
Normal file
File diff suppressed because it is too large
Load Diff
230
contrib/unbound/respip/respip.h
Normal file
230
contrib/unbound/respip/respip.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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 */
|
8
contrib/unbound/services/cache/dns.c
vendored
8
contrib/unbound/services/cache/dns.c
vendored
@ -479,8 +479,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** generate dns_msg from cached message */
|
||||
static struct dns_msg*
|
||||
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,8 +524,11 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
|
||||
if(env)
|
||||
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
|
||||
r->rrset_count);
|
||||
else
|
||||
rrset_array_unlock(r->ref, r->rrset_count);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
14
contrib/unbound/services/cache/dns.h
vendored
14
contrib/unbound/services/cache/dns.h
vendored
@ -126,6 +126,20 @@ 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.
|
||||
|
@ -1056,15 +1056,25 @@ set_recvpktinfo(int s, int family)
|
||||
* @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 tcp_mss, int freebind, int use_systemd, int dnscrypt_port)
|
||||
{
|
||||
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) {
|
||||
@ -1086,7 +1096,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_udpancil)) {
|
||||
if(!port_insert(list, s,
|
||||
is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil)) {
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
@ -1105,7 +1116,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_udp)) {
|
||||
if(!port_insert(list, s,
|
||||
is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp)) {
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
@ -1130,7 +1142,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:
|
||||
listen_type_tcp)) {
|
||||
(is_dnscrypt?listen_type_tcp_dnscrypt:listen_type_tcp))) {
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
@ -1172,6 +1184,9 @@ 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;
|
||||
@ -1180,17 +1195,20 @@ 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)
|
||||
if(ports->ftype == listen_type_udp ||
|
||||
ports->ftype == listen_type_udp_dnscrypt)
|
||||
cp = comm_point_create_udp(base, ports->fd,
|
||||
front->udp_buff, cb, cb_arg);
|
||||
else if(ports->ftype == listen_type_tcp)
|
||||
else if(ports->ftype == listen_type_tcp ||
|
||||
ports->ftype == listen_type_tcp_dnscrypt)
|
||||
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)
|
||||
} else if(ports->ftype == listen_type_udpancil ||
|
||||
ports->ftype == listen_type_udpancil_dnscrypt)
|
||||
cp = comm_point_create_udp_ancil(base, ports->fd,
|
||||
front->udp_buff, cb, cb_arg);
|
||||
if(!cp) {
|
||||
@ -1200,6 +1218,21 @@ 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);
|
||||
@ -1235,6 +1268,12 @@ 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);
|
||||
}
|
||||
@ -1278,7 +1317,8 @@ 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->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1291,7 +1331,8 @@ 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->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1306,7 +1347,8 @@ 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->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1319,7 +1361,8 @@ 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->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1347,10 +1390,16 @@ 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);
|
||||
struct listen_list* p;
|
||||
#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
|
||||
for(p = listen->cps; p; p = p->next) {
|
||||
s += sizeof(*p);
|
||||
s += comm_point_get_mem(p->com);
|
||||
|
@ -59,7 +59,9 @@ 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;
|
||||
};
|
||||
@ -85,7 +87,14 @@ enum listen_type {
|
||||
/** udp ipv6 (v4mapped) for use with ancillary data */
|
||||
listen_type_udpancil,
|
||||
/** ssl over tcp type */
|
||||
listen_type_ssl
|
||||
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
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -229,9 +229,8 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
||||
return z;
|
||||
}
|
||||
|
||||
/** return name and class and rdata of rr; parses string */
|
||||
static int
|
||||
get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
|
||||
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)
|
||||
{
|
||||
@ -353,8 +352,8 @@ new_local_rrset(struct regional* region, struct local_data* node,
|
||||
}
|
||||
|
||||
/** insert RR into RRset data structure; Wastes a couple of bytes */
|
||||
static int
|
||||
insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
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)
|
||||
{
|
||||
size_t* oldlen = pd->rr_len;
|
||||
@ -456,8 +455,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(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr),
|
||||
&rdata, &rdata_len)) {
|
||||
if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
|
||||
sizeof(rr), &rdata, &rdata_len)) {
|
||||
log_err("bad local-data: %s", rrstr);
|
||||
return 0;
|
||||
}
|
||||
@ -513,7 +512,7 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
|
||||
return 1;
|
||||
}
|
||||
return insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
}
|
||||
|
||||
/** enter a data RR into auth data; a zone for it must exist */
|
||||
@ -1233,9 +1232,10 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
}
|
||||
|
||||
/** find local data tag string match for the given type in the list */
|
||||
static int
|
||||
find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
|
||||
struct ub_packed_rrset_key* r, struct regional* temp)
|
||||
int
|
||||
local_data_find_tag_datas(const struct query_info* qinfo,
|
||||
struct config_strlist* list, struct ub_packed_rrset_key* r,
|
||||
struct regional* temp)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
char buf[65536];
|
||||
@ -1312,13 +1312,24 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
|
||||
sldns_wirerr_get_rdatawl(rr, len, 1),
|
||||
d->rr_len[d->count]);
|
||||
if(!d->rr_data[d->count])
|
||||
if(!d) return 0; /* out of memory */
|
||||
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(r->rk.dname && qinfo->qtype != LDNS_RR_TYPE_CNAME &&
|
||||
if(result && 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));
|
||||
@ -1329,9 +1340,7 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
|
||||
if(!qinfo->local_alias->rrset)
|
||||
return 0; /* out of memory */
|
||||
}
|
||||
if(r->rk.dname)
|
||||
return 1;
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** answer local data match */
|
||||
@ -1497,8 +1506,6 @@ lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2,
|
||||
struct comm_reply* repinfo, struct rbtree_type* 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(
|
||||
@ -1511,6 +1518,19 @@ 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++) {
|
||||
|
@ -46,6 +46,7 @@
|
||||
#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;
|
||||
@ -389,4 +390,111 @@ 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);
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
@ -59,6 +59,7 @@
|
||||
#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
|
||||
@ -124,11 +125,64 @@ 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;
|
||||
@ -155,7 +209,10 @@ mesh_state_compare(const void* ap, const void* bp)
|
||||
if(!(a->s.query_flags&BIT_CD) && (b->s.query_flags&BIT_CD))
|
||||
return 1;
|
||||
|
||||
return query_info_compare(&a->s.qinfo, &b->s.qinfo);
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
@ -287,16 +344,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,
|
||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||
uint16_t qid)
|
||||
struct respip_client_info* cinfo, uint16_t qflags,
|
||||
struct edns_data* edns, struct comm_reply* rep, uint16_t qid)
|
||||
{
|
||||
struct mesh_state* s = NULL;
|
||||
int unique = edns_unique_mesh_state(edns->opt_list, mesh->env);
|
||||
int unique = 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, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, cinfo, 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)) {
|
||||
@ -323,7 +380,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
||||
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,
|
||||
@ -412,12 +470,13 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qid, mesh_cb_func_type cb, void* cb_arg)
|
||||
{
|
||||
struct mesh_state* s = NULL;
|
||||
int unique = edns_unique_mesh_state(edns->opt_list, mesh->env);
|
||||
int unique = 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, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, NULL, 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 */
|
||||
@ -425,7 +484,8 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@ -476,8 +536,8 @@ 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, qinfo, qflags&(BIT_RD|BIT_CD),
|
||||
0, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
@ -497,7 +557,8 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
@ -546,7 +607,8 @@ 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,
|
||||
uint16_t qflags, int prime, int valrec)
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec)
|
||||
{
|
||||
struct regional* region = alloc_reg_obtain(env->alloc);
|
||||
struct mesh_state* mstate;
|
||||
@ -582,6 +644,14 @@ 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;
|
||||
@ -756,7 +826,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
{
|
||||
/* find it, if not, create it */
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime, valrec);
|
||||
struct mesh_state* sub = mesh_area_find(mesh, NULL, qinfo, qflags,
|
||||
prime, valrec);
|
||||
int was_detached;
|
||||
if(mesh_detect_cycle_found(qstate, sub)) {
|
||||
verbose(VERB_ALGO, "attach failed, cycle detected");
|
||||
@ -767,7 +838,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
/* create a new one */
|
||||
sub = mesh_state_create(qstate->env, qinfo, qflags, prime, valrec);
|
||||
sub = mesh_state_create(qstate->env, qinfo, NULL, qflags, prime,
|
||||
valrec);
|
||||
if(!sub) {
|
||||
log_err("mesh_attach_sub: out of memory");
|
||||
return 0;
|
||||
@ -1035,8 +1107,25 @@ 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) {
|
||||
mesh_send_reply(mstate, mstate->s.return_rcode, rep, r, prev);
|
||||
prev = r;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
for(c = mstate->cb_list; c; c = c->next) {
|
||||
@ -1060,7 +1149,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
|
||||
}
|
||||
|
||||
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime, int valrec)
|
||||
struct respip_client_info* cinfo, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, int valrec)
|
||||
{
|
||||
struct mesh_state key;
|
||||
struct mesh_state* result;
|
||||
@ -1074,6 +1164,7 @@ 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;
|
||||
@ -1224,11 +1315,16 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
|
||||
return mesh_continue(mesh, mstate, module_error, ev);
|
||||
}
|
||||
if(s == module_restart_next) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
*ev = module_event_pass;
|
||||
return 1;
|
||||
@ -1378,7 +1474,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, qinfo, flags, prime, valrec);
|
||||
dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
|
||||
return mesh_detect_cycle_found(qstate, dep_m);
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ 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
|
||||
@ -274,14 +275,18 @@ 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,
|
||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||
uint16_t qid);
|
||||
struct respip_client_info* cinfo, 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
|
||||
@ -409,6 +414,7 @@ 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
|
||||
@ -416,7 +422,8 @@ void mesh_state_delete(struct module_qstate* qstate);
|
||||
* @return: new mesh state or NULL on allocation error.
|
||||
*/
|
||||
struct mesh_state* mesh_state_create(struct module_env* env,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
|
||||
struct query_info* qinfo, struct respip_client_info* cinfo,
|
||||
uint16_t qflags, int prime, int valrec);
|
||||
|
||||
/**
|
||||
* Check if the mesh state is unique.
|
||||
@ -451,6 +458,8 @@ 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.
|
||||
@ -458,7 +467,8 @@ void mesh_delete_all(struct mesh_area* mesh);
|
||||
* @return: mesh state or NULL if not found.
|
||||
*/
|
||||
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
|
||||
struct respip_client_info* cinfo, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, int valrec);
|
||||
|
||||
/**
|
||||
* Setup attachment super/sub relation between super and sub mesh state.
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "dns64/dns64.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "validator/validator.h"
|
||||
#include "respip/respip.h"
|
||||
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
#include "pythonmod/pythonmod.h"
|
||||
@ -53,6 +54,9 @@
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#endif
|
||||
|
||||
/** count number of modules (words) in the string */
|
||||
static int
|
||||
@ -127,6 +131,10 @@ module_list_avail(void)
|
||||
#ifdef USE_CACHEDB
|
||||
"cachedb",
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
"subnetcache",
|
||||
#endif
|
||||
"respip",
|
||||
"validator",
|
||||
"iterator",
|
||||
NULL};
|
||||
@ -148,6 +156,10 @@ module_funcs_avail(void)
|
||||
#ifdef USE_CACHEDB
|
||||
&cachedb_get_funcblock,
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
&subnetmod_get_funcblock,
|
||||
#endif
|
||||
&respip_get_funcblock,
|
||||
&val_get_funcblock,
|
||||
&iter_get_funcblock,
|
||||
NULL};
|
||||
@ -216,7 +228,7 @@ 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;
|
||||
}
|
||||
|
@ -66,6 +66,10 @@ 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)
|
||||
{
|
||||
@ -73,6 +77,7 @@ 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);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@
|
||||
struct regional;
|
||||
struct config_file;
|
||||
struct config_view;
|
||||
struct respip_set;
|
||||
|
||||
|
||||
/**
|
||||
@ -71,6 +72,8 @@ struct view {
|
||||
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;
|
||||
|
@ -372,6 +372,8 @@ enum sldns_enum_algorithm
|
||||
LDNS_ECC_GOST = 12, /* RFC 5933 */
|
||||
LDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
|
||||
LDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
|
||||
LDNS_ED25519 = 15, /* RFC 8080 */
|
||||
LDNS_ED448 = 16, /* RFC 8080 */
|
||||
LDNS_INDIRECT = 252,
|
||||
LDNS_PRIVATEDNS = 253,
|
||||
LDNS_PRIVATEOID = 254
|
||||
@ -420,7 +422,8 @@ enum sldns_enum_edns_option
|
||||
LDNS_EDNS_DAU = 5, /* RFC6975 */
|
||||
LDNS_EDNS_DHU = 6, /* RFC6975 */
|
||||
LDNS_EDNS_N3U = 7, /* RFC6975 */
|
||||
LDNS_EDNS_CLIENT_SUBNET = 8, /* draft-vandergaast-edns-client-subnet */
|
||||
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
||||
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
||||
LDNS_EDNS_PADDING = 12 /* RFC7830 */
|
||||
};
|
||||
typedef enum sldns_enum_edns_option sldns_edns_option;
|
||||
|
@ -33,6 +33,7 @@ sldns_buffer_new(size_t capacity)
|
||||
buffer->_position = 0;
|
||||
buffer->_limit = buffer->_capacity = capacity;
|
||||
buffer->_fixed = 0;
|
||||
buffer->_vfixed = 0;
|
||||
buffer->_status_err = 0;
|
||||
|
||||
sldns_buffer_invariant(buffer);
|
||||
@ -48,6 +49,7 @@ sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size)
|
||||
buffer->_position = 0;
|
||||
buffer->_limit = buffer->_capacity = size;
|
||||
buffer->_fixed = 0;
|
||||
buffer->_vfixed = 0;
|
||||
buffer->_data = malloc(size);
|
||||
if(!buffer->_data) {
|
||||
buffer->_status_err = 1;
|
||||
@ -66,6 +68,17 @@ sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size)
|
||||
buffer->_data = data;
|
||||
buffer->_capacity = buffer->_limit = size;
|
||||
buffer->_fixed = 1;
|
||||
buffer->_vfixed = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sldns_buffer_init_vfixed_frm_data(sldns_buffer *buffer, void *data, size_t size)
|
||||
{
|
||||
memset(buffer, 0, sizeof(*buffer));
|
||||
buffer->_data = data;
|
||||
buffer->_capacity = buffer->_limit = size;
|
||||
buffer->_fixed = 1;
|
||||
buffer->_vfixed = 1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -74,7 +87,7 @@ sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity)
|
||||
void *data;
|
||||
|
||||
sldns_buffer_invariant(buffer);
|
||||
assert(buffer->_position <= capacity);
|
||||
assert(buffer->_position <= capacity && !buffer->_fixed);
|
||||
|
||||
data = (uint8_t *) realloc(buffer->_data, capacity);
|
||||
if (!data) {
|
||||
@ -126,7 +139,7 @@ sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...)
|
||||
if (written == -1) {
|
||||
buffer->_status_err = 1;
|
||||
return -1;
|
||||
} else if ((size_t) written >= remaining) {
|
||||
} else if (!buffer->_vfixed && (size_t) written >= remaining) {
|
||||
if (!sldns_buffer_reserve(buffer, (size_t) written + 1)) {
|
||||
buffer->_status_err = 1;
|
||||
return -1;
|
||||
|
@ -87,6 +87,19 @@ sldns_write_uint32(void *dst, uint32_t data)
|
||||
}
|
||||
|
||||
|
||||
INLINE void
|
||||
sldns_write_uint48(void *dst, uint64_t data)
|
||||
{
|
||||
uint8_t *p = (uint8_t *) dst;
|
||||
p[0] = (uint8_t) ((data >> 40) & 0xff);
|
||||
p[1] = (uint8_t) ((data >> 32) & 0xff);
|
||||
p[2] = (uint8_t) ((data >> 24) & 0xff);
|
||||
p[3] = (uint8_t) ((data >> 16) & 0xff);
|
||||
p[4] = (uint8_t) ((data >> 8) & 0xff);
|
||||
p[5] = (uint8_t) (data & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \file sbuffer.h
|
||||
*
|
||||
@ -117,6 +130,17 @@ struct sldns_buffer
|
||||
/** If the buffer is fixed it cannot be resized */
|
||||
unsigned _fixed : 1;
|
||||
|
||||
/** If the buffer is vfixed, no more than capacity bytes willl be
|
||||
* written to _data, however the _position counter will be updated
|
||||
* with the amount that would have been written in consecutive
|
||||
* writes. This allows for a modus operandi in which a sequence is
|
||||
* written on a fixed capacity buffer (perhaps with _data on stack).
|
||||
* When everything could be written, then the _data is immediately
|
||||
* usable, if not, then a buffer could be allocated sized precisely
|
||||
* to fit the data for a second attempt.
|
||||
*/
|
||||
unsigned _vfixed : 1;
|
||||
|
||||
/** The current state of the buffer. If writing to the buffer fails
|
||||
* for any reason, this value is changed. This way, you can perform
|
||||
* multiple writes in sequence and check for success afterwards. */
|
||||
@ -134,9 +158,9 @@ INLINE void
|
||||
sldns_buffer_invariant(sldns_buffer *buffer)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer->_position <= buffer->_limit);
|
||||
assert(buffer->_position <= buffer->_limit || buffer->_vfixed);
|
||||
assert(buffer->_limit <= buffer->_capacity);
|
||||
assert(buffer->_data != NULL);
|
||||
assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -168,6 +192,19 @@ void sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size);
|
||||
*/
|
||||
void sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Setup a buffer with the data pointed to. No data copied, no memory allocs.
|
||||
* The buffer is "virtually" fixed. Writes beyond size (the capacity) will
|
||||
* only update position, but no data will be written beyond capacity. This
|
||||
* allows to determine how big the buffer should have been to contain all the
|
||||
* written data, by looking at the position with sldns_buffer_position(),
|
||||
* similarly to the return value of POSIX's snprintf.
|
||||
* \param[in] buffer pointer to the buffer to put the data in
|
||||
* \param[in] data the data to encapsulate in the buffer
|
||||
* \param[in] size the size of the data
|
||||
*/
|
||||
void sldns_buffer_init_vfixed_frm_data(sldns_buffer *buffer, void *data, size_t size);
|
||||
|
||||
/**
|
||||
* clears the buffer and make it ready for writing. The buffer's limit
|
||||
* is set to the capacity and the position is set to 0.
|
||||
@ -231,7 +268,7 @@ sldns_buffer_position(sldns_buffer *buffer)
|
||||
INLINE void
|
||||
sldns_buffer_set_position(sldns_buffer *buffer, size_t mark)
|
||||
{
|
||||
assert(mark <= buffer->_limit);
|
||||
assert(mark <= buffer->_limit || buffer->_vfixed);
|
||||
buffer->_position = mark;
|
||||
}
|
||||
|
||||
@ -245,7 +282,7 @@ sldns_buffer_set_position(sldns_buffer *buffer, size_t mark)
|
||||
INLINE void
|
||||
sldns_buffer_skip(sldns_buffer *buffer, ssize_t count)
|
||||
{
|
||||
assert(buffer->_position + count <= buffer->_limit);
|
||||
assert(buffer->_position + count <= buffer->_limit || buffer->_vfixed);
|
||||
buffer->_position += count;
|
||||
}
|
||||
|
||||
@ -317,7 +354,7 @@ int sldns_buffer_reserve(sldns_buffer *buffer, size_t amount);
|
||||
INLINE uint8_t *
|
||||
sldns_buffer_at(const sldns_buffer *buffer, size_t at)
|
||||
{
|
||||
assert(at <= buffer->_limit);
|
||||
assert(at <= buffer->_limit || buffer->_vfixed);
|
||||
return buffer->_data + at;
|
||||
}
|
||||
|
||||
@ -367,8 +404,8 @@ INLINE size_t
|
||||
sldns_buffer_remaining_at(sldns_buffer *buffer, size_t at)
|
||||
{
|
||||
sldns_buffer_invariant(buffer);
|
||||
assert(at <= buffer->_limit);
|
||||
return buffer->_limit - at;
|
||||
assert(at <= buffer->_limit || buffer->_vfixed);
|
||||
return at < buffer->_limit ? buffer->_limit - at : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -420,10 +457,42 @@ sldns_buffer_available(sldns_buffer *buffer, size_t count)
|
||||
INLINE void
|
||||
sldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count)
|
||||
{
|
||||
assert(sldns_buffer_available_at(buffer, at, count));
|
||||
if (!buffer->_vfixed)
|
||||
assert(sldns_buffer_available_at(buffer, at, count));
|
||||
else if (sldns_buffer_remaining_at(buffer, at) == 0)
|
||||
return;
|
||||
else if (count > sldns_buffer_remaining_at(buffer, at)) {
|
||||
memcpy(buffer->_data + at, data,
|
||||
sldns_buffer_remaining_at(buffer, at));
|
||||
return;
|
||||
}
|
||||
memcpy(buffer->_data + at, data, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the given byte to the buffer at the specified position
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position (in number of bytes) to write the data at
|
||||
* \param[in] c the byte to set to the buffer
|
||||
* \param[in] count the number of bytes of bytes to write
|
||||
*/
|
||||
|
||||
INLINE void
|
||||
sldns_buffer_set_at(sldns_buffer *buffer, size_t at, int c, size_t count)
|
||||
{
|
||||
if (!buffer->_vfixed)
|
||||
assert(sldns_buffer_available_at(buffer, at, count));
|
||||
else if (sldns_buffer_remaining_at(buffer, at) == 0)
|
||||
return;
|
||||
else if (count > sldns_buffer_remaining_at(buffer, at)) {
|
||||
memset(buffer->_data + at, c,
|
||||
sldns_buffer_remaining_at(buffer, at));
|
||||
return;
|
||||
}
|
||||
memset(buffer->_data + at, c, count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* writes count bytes of data to the current position of the buffer
|
||||
* \param[in] buffer the buffer
|
||||
@ -469,6 +538,7 @@ sldns_buffer_write_string(sldns_buffer *buffer, const char *str)
|
||||
INLINE void
|
||||
sldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data)
|
||||
{
|
||||
if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
|
||||
assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
|
||||
buffer->_data[at] = data;
|
||||
}
|
||||
@ -494,6 +564,7 @@ sldns_buffer_write_u8(sldns_buffer *buffer, uint8_t data)
|
||||
INLINE void
|
||||
sldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data)
|
||||
{
|
||||
if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
|
||||
assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
|
||||
sldns_write_uint16(buffer->_data + at, data);
|
||||
}
|
||||
@ -519,10 +590,25 @@ sldns_buffer_write_u16(sldns_buffer *buffer, uint16_t data)
|
||||
INLINE void
|
||||
sldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data)
|
||||
{
|
||||
if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
|
||||
assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
|
||||
sldns_write_uint32(buffer->_data + at, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 6 byte integer at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at the position in the buffer
|
||||
* \param[in] data the (lower) 48 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
sldns_buffer_write_u48_at(sldns_buffer *buffer, size_t at, uint64_t data)
|
||||
{
|
||||
if (buffer->_vfixed && at + 6 > buffer->_limit) return;
|
||||
assert(sldns_buffer_available_at(buffer, at, 6));
|
||||
sldns_write_uint48(buffer->_data + at, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 4 byte integer at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
@ -535,6 +621,18 @@ sldns_buffer_write_u32(sldns_buffer *buffer, uint32_t data)
|
||||
buffer->_position += sizeof(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the given 6 byte integer at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] data the 48 bits to write
|
||||
*/
|
||||
INLINE void
|
||||
sldns_buffer_write_u48(sldns_buffer *buffer, uint64_t data)
|
||||
{
|
||||
sldns_buffer_write_u48_at(buffer, buffer->_position, data);
|
||||
buffer->_position += 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* copies count bytes of data at the given position to the given data-array
|
||||
* \param[in] buffer the buffer
|
||||
|
@ -47,6 +47,8 @@ static sldns_lookup_table sldns_algorithms_data[] = {
|
||||
{ LDNS_ECC_GOST, "ECC-GOST"},
|
||||
{ LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
|
||||
{ LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
|
||||
{ LDNS_ED25519, "ED25519"},
|
||||
{ LDNS_ED448, "ED448"},
|
||||
{ LDNS_INDIRECT, "INDIRECT" },
|
||||
{ LDNS_PRIVATEDNS, "PRIVATEDNS" },
|
||||
{ LDNS_PRIVATEOID, "PRIVATEOID" },
|
||||
@ -165,6 +167,7 @@ static sldns_lookup_table sldns_edns_options_data[] = {
|
||||
{ 6, "DHU" },
|
||||
{ 7, "N3U" },
|
||||
{ 8, "edns-client-subnet" },
|
||||
{ 11, "edns-tcp-keepalive"},
|
||||
{ 12, "Padding" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
@ -270,6 +273,12 @@ int sldns_wire2str_rcode_buf(int rcode, char* s, size_t slen)
|
||||
return sldns_wire2str_rcode_print(&s, &slen, rcode);
|
||||
}
|
||||
|
||||
int sldns_wire2str_opcode_buf(int opcode, char* s, size_t slen)
|
||||
{
|
||||
/* use arguments as temporary variables */
|
||||
return sldns_wire2str_opcode_print(&s, &slen, opcode);
|
||||
}
|
||||
|
||||
int sldns_wire2str_dname_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
|
||||
{
|
||||
/* use arguments as temporary variables */
|
||||
@ -1838,6 +1847,25 @@ int sldns_wire2str_edns_subnet_print(char** s, size_t* sl, uint8_t* data,
|
||||
return w;
|
||||
}
|
||||
|
||||
static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl, uint8_t* data,
|
||||
size_t len)
|
||||
{
|
||||
int w = 0;
|
||||
uint16_t timeout;
|
||||
if(!(len == 0 || len == 2)) {
|
||||
w += sldns_str_print(s, sl, "malformed keepalive ");
|
||||
w += print_hex_buf(s, sl, data, len);
|
||||
return w;
|
||||
}
|
||||
if(len == 0 ) {
|
||||
w += sldns_str_print(s, sl, "no timeout value (only valid for client option) ");
|
||||
} else {
|
||||
timeout = sldns_read_uint16(data);
|
||||
w += sldns_str_print(s, sl, "timeout value in units of 100ms %u", (int)timeout);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
int sldns_wire2str_edns_option_print(char** s, size_t* sl,
|
||||
uint16_t option_code, uint8_t* optdata, size_t optlen)
|
||||
{
|
||||
@ -1866,6 +1894,9 @@ int sldns_wire2str_edns_option_print(char** s, size_t* sl,
|
||||
case LDNS_EDNS_CLIENT_SUBNET:
|
||||
w += sldns_wire2str_edns_subnet_print(s, sl, optdata, optlen);
|
||||
break;
|
||||
case LDNS_EDNS_KEEPALIVE:
|
||||
w += sldns_wire2str_edns_keepalive_print(s, sl, optdata, optlen);
|
||||
break;
|
||||
case LDNS_EDNS_PADDING:
|
||||
w += print_hex_buf(s, sl, optdata, optlen);
|
||||
break;
|
||||
|
@ -441,6 +441,17 @@ int sldns_wire2str_class_buf(uint16_t rrclass, char* str, size_t len);
|
||||
*/
|
||||
int sldns_wire2str_rcode_buf(int rcode, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert host format opcode to a string. 'QUERY', 'NOTIFY', 'UPDATE'.
|
||||
* With user buffer.
|
||||
* @param opcode: opcode as integer in host order
|
||||
* @param str: the string to write to.
|
||||
* @param len: length of str.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger or equal than str_len if output was truncated.
|
||||
*/
|
||||
int sldns_wire2str_opcode_buf(int opcode, char* str, size_t len);
|
||||
|
||||
/**
|
||||
* Convert wire dname to a string, "example.com.". With user buffer.
|
||||
* @param dname: the dname in uncompressed wireformat.
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "validator/validator.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/view.h"
|
||||
#include "respip/respip.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
@ -141,6 +143,27 @@ localzonechecks(struct config_file* cfg)
|
||||
local_zones_delete(zs);
|
||||
}
|
||||
|
||||
/** check view and response-ip configuration */
|
||||
static void
|
||||
view_and_respipchecks(struct config_file* cfg)
|
||||
{
|
||||
struct views* views = NULL;
|
||||
struct respip_set* respip = NULL;
|
||||
int ignored = 0;
|
||||
if(!(views = views_create()))
|
||||
fatal_exit("Could not create views: out of memory");
|
||||
if(!(respip = respip_set_create()))
|
||||
fatal_exit("Could not create respip set: out of memory");
|
||||
if(!views_apply_cfg(views, cfg))
|
||||
fatal_exit("Could not set up views");
|
||||
if(!respip_global_apply_cfg(respip, cfg))
|
||||
fatal_exit("Could not setup respip set");
|
||||
if(!respip_views_apply_cfg(views, cfg, &ignored))
|
||||
fatal_exit("Could not setup per-view respip sets");
|
||||
views_delete(views);
|
||||
respip_set_delete(respip);
|
||||
}
|
||||
|
||||
/** emit warnings for IP in hosts */
|
||||
static void
|
||||
warn_hosts(const char* typ, struct config_stub* list)
|
||||
@ -407,10 +430,16 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
free(cfg->chrootdir);
|
||||
cfg->chrootdir = NULL;
|
||||
|
||||
/* There should be no reason for 'respip' module not to work with
|
||||
* dns64, but it's not explicitly confirmed, so the combination is
|
||||
* excluded below. It's simply unknown yet for the combination of
|
||||
* respip and other modules. */
|
||||
if(strcmp(cfg->module_conf, "iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator iterator") != 0
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
&& strcmp(cfg->module_conf, "python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python validator iterator") != 0
|
||||
@ -426,6 +455,8 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
&& strcmp(cfg->module_conf, "cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(USE_CACHEDB)
|
||||
&& strcmp(cfg->module_conf, "python dns64 cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dns64 validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python cachedb iterator") != 0
|
||||
@ -435,6 +466,18 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
&& strcmp(cfg->module_conf, "cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator python cachedb iterator") != 0
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
&& strcmp(cfg->module_conf, "subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET)
|
||||
&& strcmp(cfg->module_conf, "python subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0
|
||||
#endif
|
||||
) {
|
||||
fatal_exit("module conf '%s' is not known to work",
|
||||
@ -464,6 +507,7 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
}
|
||||
|
||||
localzonechecks(cfg);
|
||||
view_and_respipchecks(cfg);
|
||||
}
|
||||
|
||||
/** check forwards */
|
||||
|
@ -58,7 +58,17 @@
|
||||
#include "util/config_file.h"
|
||||
#include "util/locks.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
|
||||
#ifdef HAVE_SYS_IPC_H
|
||||
#include "sys/ipc.h"
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SHM_H
|
||||
#include "sys/shm.h"
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
@ -81,6 +91,9 @@ usage(void)
|
||||
printf(" (this flushes data, stats, requestlist)\n");
|
||||
printf(" stats print statistics\n");
|
||||
printf(" stats_noreset peek at statistics\n");
|
||||
#ifdef HAVE_SHMGET
|
||||
printf(" stats_shm print statistics using shm\n");
|
||||
#endif
|
||||
printf(" status display status of server\n");
|
||||
printf(" verbosity <number> change logging detail\n");
|
||||
printf(" log_reopen close and open the logfile\n");
|
||||
@ -89,6 +102,9 @@ usage(void)
|
||||
printf(" local_data <RR data...> add local data, for example\n");
|
||||
printf(" local_data www.example.com A 192.0.2.1\n");
|
||||
printf(" local_data_remove <name> remove local RR data from name\n");
|
||||
printf(" local_zones, local_zones_remove, local_datas, local_datas_remove\n");
|
||||
printf(" same, but read list from stdin\n");
|
||||
printf(" (one entry per line).\n");
|
||||
printf(" dump_cache print cache to stdout\n");
|
||||
printf(" load_cache load cache from stdin\n");
|
||||
printf(" lookup <name> print nameservers for name\n");
|
||||
@ -138,6 +154,256 @@ usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SHMGET
|
||||
/** what to put on statistics lines between var and value, ": " or "=" */
|
||||
#define SQ "="
|
||||
/** if true, inhibits a lot of =0 lines from the stats output */
|
||||
static const int inhibit_zero = 1;
|
||||
/** divide sum of timers to get average */
|
||||
static void
|
||||
timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
size_t leftover;
|
||||
if(d == 0) {
|
||||
avg->tv_sec = 0;
|
||||
avg->tv_usec = 0;
|
||||
return;
|
||||
}
|
||||
avg->tv_sec = sum->tv_sec / d;
|
||||
avg->tv_usec = sum->tv_usec / d;
|
||||
/* handle fraction from seconds divide */
|
||||
leftover = sum->tv_sec - avg->tv_sec*d;
|
||||
avg->tv_usec += (leftover*1000000)/d;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** print unsigned long stats value */
|
||||
#define PR_UL_NM(str, var) printf("%s."str SQ"%lu\n", nm, (unsigned long)(var));
|
||||
#define PR_UL(str, var) printf(str SQ"%lu\n", (unsigned long)(var));
|
||||
#define PR_UL_SUB(str, nm, var) printf(str".%s"SQ"%lu\n", nm, (unsigned long)(var));
|
||||
#define PR_TIMEVAL(str, var) printf(str SQ ARG_LL "d.%6.6d\n", \
|
||||
(long long)var.tv_sec, (int)var.tv_usec);
|
||||
#define PR_LL(str, var) printf(str SQ ARG_LL"d\n", (long long)(var));
|
||||
|
||||
/** print stat block */
|
||||
static void pr_stats(const char* nm, struct stats_info* s)
|
||||
{
|
||||
struct timeval avg;
|
||||
PR_UL_NM("num.queries", s->svr.num_queries);
|
||||
PR_UL_NM("num.queries_ip_ratelimited",
|
||||
s->svr.num_queries_ip_ratelimited);
|
||||
PR_UL_NM("num.cachehits",
|
||||
s->svr.num_queries - s->svr.num_queries_missed_cache);
|
||||
PR_UL_NM("num.cachemiss", s->svr.num_queries_missed_cache);
|
||||
PR_UL_NM("num.prefetch", s->svr.num_queries_prefetch);
|
||||
PR_UL_NM("num.zero_ttl", s->svr.zero_ttl_responses);
|
||||
PR_UL_NM("num.recursivereplies", s->mesh_replies_sent);
|
||||
#ifdef USE_DNSCRYPT
|
||||
PR_UL_NM("num.dnscrypt.crypted", s->svr.num_query_dnscrypt_crypted);
|
||||
PR_UL_NM("num.dnscrypt.cert", s->svr.num_query_dnscrypt_cert);
|
||||
PR_UL_NM("num.dnscrypt.cleartext", s->svr.num_query_dnscrypt_cleartext);
|
||||
PR_UL_NM("num.dnscrypt.malformed",
|
||||
s->svr.num_query_dnscrypt_crypted_malformed);
|
||||
#endif
|
||||
printf("%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/
|
||||
(s->svr.num_queries_missed_cache+
|
||||
s->svr.num_queries_prefetch) : 0.0);
|
||||
PR_UL_NM("requestlist.max", s->svr.max_query_list_size);
|
||||
PR_UL_NM("requestlist.overwritten", s->mesh_jostled);
|
||||
PR_UL_NM("requestlist.exceeded", s->mesh_dropped);
|
||||
PR_UL_NM("requestlist.current.all", s->mesh_num_states);
|
||||
PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states);
|
||||
timeval_divide(&avg, &s->mesh_replies_sum_wait, s->mesh_replies_sent);
|
||||
printf("%s.", nm);
|
||||
PR_TIMEVAL("recursion.time.avg", avg);
|
||||
printf("%s.recursion.time.median"SQ"%g\n", nm, s->mesh_time_median);
|
||||
PR_UL_NM("tcpusage", s->svr.tcp_accept_usage);
|
||||
}
|
||||
|
||||
/** print uptime */
|
||||
static void print_uptime(struct shm_stat_info* shm_stat)
|
||||
{
|
||||
PR_TIMEVAL("time.now", shm_stat->time.now);
|
||||
PR_TIMEVAL("time.up", shm_stat->time.up);
|
||||
PR_TIMEVAL("time.elapsed", shm_stat->time.elapsed);
|
||||
}
|
||||
|
||||
/** print memory usage */
|
||||
static void print_mem(struct shm_stat_info* shm_stat)
|
||||
{
|
||||
PR_LL("mem.cache.rrset", shm_stat->mem.rrset);
|
||||
PR_LL("mem.cache.message", shm_stat->mem.msg);
|
||||
PR_LL("mem.cache.iterator", shm_stat->mem.iter);
|
||||
PR_LL("mem.cache.validator", shm_stat->mem.val);
|
||||
#ifdef CLIENT_SUBNET
|
||||
PR_LL("mem.cache.subnet", shm_stat->mem.subnet);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** print histogram */
|
||||
static void print_hist(struct stats_info* s)
|
||||
{
|
||||
struct timehist* hist;
|
||||
size_t i;
|
||||
hist = timehist_setup();
|
||||
if(!hist)
|
||||
fatal_exit("out of memory");
|
||||
timehist_import(hist, s->svr.hist, NUM_BUCKETS_HIST);
|
||||
for(i=0; i<hist->num; i++) {
|
||||
printf("histogram.%6.6d.%6.6d.to.%6.6d.%6.6d=%lu\n",
|
||||
(int)hist->buckets[i].lower.tv_sec,
|
||||
(int)hist->buckets[i].lower.tv_usec,
|
||||
(int)hist->buckets[i].upper.tv_sec,
|
||||
(int)hist->buckets[i].upper.tv_usec,
|
||||
(unsigned long)hist->buckets[i].count);
|
||||
}
|
||||
timehist_delete(hist);
|
||||
}
|
||||
|
||||
/** print extended */
|
||||
static void print_extended(struct stats_info* s)
|
||||
{
|
||||
int i;
|
||||
char nm[16];
|
||||
|
||||
/* TYPE */
|
||||
for(i=0; i<STATS_QTYPE_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.qtype[i] == 0)
|
||||
continue;
|
||||
sldns_wire2str_type_buf((uint16_t)i, nm, sizeof(nm));
|
||||
PR_UL_SUB("num.query.type", nm, s->svr.qtype[i]);
|
||||
}
|
||||
if(!inhibit_zero || s->svr.qtype_big) {
|
||||
PR_UL("num.query.type.other", s->svr.qtype_big);
|
||||
}
|
||||
|
||||
/* CLASS */
|
||||
for(i=0; i<STATS_QCLASS_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.qclass[i] == 0)
|
||||
continue;
|
||||
sldns_wire2str_class_buf((uint16_t)i, nm, sizeof(nm));
|
||||
PR_UL_SUB("num.query.class", nm, s->svr.qclass[i]);
|
||||
}
|
||||
if(!inhibit_zero || s->svr.qclass_big) {
|
||||
PR_UL("num.query.class.other", s->svr.qclass_big);
|
||||
}
|
||||
|
||||
/* OPCODE */
|
||||
for(i=0; i<STATS_OPCODE_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.qopcode[i] == 0)
|
||||
continue;
|
||||
sldns_wire2str_opcode_buf(i, nm, sizeof(nm));
|
||||
PR_UL_SUB("num.query.opcode", nm, s->svr.qopcode[i]);
|
||||
}
|
||||
|
||||
/* transport */
|
||||
PR_UL("num.query.tcp", s->svr.qtcp);
|
||||
PR_UL("num.query.tcpout", s->svr.qtcp_outgoing);
|
||||
PR_UL("num.query.ipv6", s->svr.qipv6);
|
||||
|
||||
/* flags */
|
||||
PR_UL("num.query.flags.QR", s->svr.qbit_QR);
|
||||
PR_UL("num.query.flags.AA", s->svr.qbit_AA);
|
||||
PR_UL("num.query.flags.TC", s->svr.qbit_TC);
|
||||
PR_UL("num.query.flags.RD", s->svr.qbit_RD);
|
||||
PR_UL("num.query.flags.RA", s->svr.qbit_RA);
|
||||
PR_UL("num.query.flags.Z", s->svr.qbit_Z);
|
||||
PR_UL("num.query.flags.AD", s->svr.qbit_AD);
|
||||
PR_UL("num.query.flags.CD", s->svr.qbit_CD);
|
||||
PR_UL("num.query.edns.present", s->svr.qEDNS);
|
||||
PR_UL("num.query.edns.DO", s->svr.qEDNS_DO);
|
||||
|
||||
/* RCODE */
|
||||
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;
|
||||
sldns_wire2str_rcode_buf(i, nm, sizeof(nm));
|
||||
PR_UL_SUB("num.answer.rcode", nm, s->svr.ans_rcode[i]);
|
||||
}
|
||||
if(!inhibit_zero || s->svr.ans_rcode_nodata) {
|
||||
PR_UL("num.answer.rcode.nodata", s->svr.ans_rcode_nodata);
|
||||
}
|
||||
/* validation */
|
||||
PR_UL("num.answer.secure", s->svr.ans_secure);
|
||||
PR_UL("num.answer.bogus", s->svr.ans_bogus);
|
||||
PR_UL("num.rrset.bogus", s->svr.rrset_bogus);
|
||||
/* threat detection */
|
||||
PR_UL("unwanted.queries", s->svr.unwanted_queries);
|
||||
PR_UL("unwanted.replies", s->svr.unwanted_replies);
|
||||
/* cache counts */
|
||||
PR_UL("msg.cache.count", s->svr.msg_cache_count);
|
||||
PR_UL("rrset.cache.count", s->svr.rrset_cache_count);
|
||||
PR_UL("infra.cache.count", s->svr.infra_cache_count);
|
||||
PR_UL("key.cache.count", s->svr.key_cache_count);
|
||||
}
|
||||
|
||||
/** print statistics out of memory structures */
|
||||
static void do_stats_shm(struct config_file* cfg, struct stats_info* stats,
|
||||
struct shm_stat_info* shm_stat)
|
||||
{
|
||||
int i;
|
||||
char nm[16];
|
||||
for(i=0; i<cfg->num_threads; i++) {
|
||||
snprintf(nm, sizeof(nm), "thread%d", i);
|
||||
pr_stats(nm, &stats[i+1]);
|
||||
}
|
||||
pr_stats("total", &stats[0]);
|
||||
print_uptime(shm_stat);
|
||||
if(cfg->stat_extended) {
|
||||
print_mem(shm_stat);
|
||||
print_hist(stats);
|
||||
print_extended(stats);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SHMGET */
|
||||
|
||||
/** print statistics from shm memory segment */
|
||||
static void print_stats_shm(const char* cfgfile)
|
||||
{
|
||||
#ifdef HAVE_SHMGET
|
||||
struct config_file* cfg;
|
||||
struct stats_info* stats;
|
||||
struct shm_stat_info* shm_stat;
|
||||
int id_ctl, id_arr;
|
||||
/* read config */
|
||||
if(!(cfg = config_create()))
|
||||
fatal_exit("out of memory");
|
||||
if(!config_read(cfg, cfgfile, NULL))
|
||||
fatal_exit("could not read config file");
|
||||
/* get shm segments */
|
||||
id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R|SHM_W);
|
||||
if(id_ctl == -1) {
|
||||
fatal_exit("shmget(%d): %s", cfg->shm_key, strerror(errno));
|
||||
}
|
||||
id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R|SHM_W);
|
||||
if(id_arr == -1) {
|
||||
fatal_exit("shmget(%d): %s", cfg->shm_key+1, strerror(errno));
|
||||
}
|
||||
shm_stat = (struct shm_stat_info*)shmat(id_ctl, NULL, 0);
|
||||
if(shm_stat == (void*)-1) {
|
||||
fatal_exit("shmat(%d): %s", id_ctl, strerror(errno));
|
||||
}
|
||||
stats = (struct stats_info*)shmat(id_arr, NULL, 0);
|
||||
if(stats == (void*)-1) {
|
||||
fatal_exit("shmat(%d): %s", id_arr, strerror(errno));
|
||||
}
|
||||
|
||||
/* print the stats */
|
||||
do_stats_shm(cfg, stats, shm_stat);
|
||||
|
||||
/* shutdown */
|
||||
shmdt(shm_stat);
|
||||
shmdt(stats);
|
||||
config_delete(cfg);
|
||||
#else
|
||||
(void)cfgfile;
|
||||
#endif /* HAVE_SHMGET */
|
||||
}
|
||||
|
||||
/** exit with ssl error */
|
||||
static void ssl_err(const char* s)
|
||||
{
|
||||
@ -160,13 +426,13 @@ setup_ctx(struct config_file* cfg)
|
||||
if(!s_cert || !c_key || !c_cert)
|
||||
fatal_exit("out of memory");
|
||||
}
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if(!ctx)
|
||||
ssl_err("could not allocate SSL_CTX pointer");
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
|
||||
!= SSL_OP_NO_SSLv2)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv2");
|
||||
if(cfg->remote_control_use_cert) {
|
||||
if(cfg->remote_control_use_cert) {
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
|
||||
!= SSL_OP_NO_SSLv3)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv3");
|
||||
@ -441,44 +707,10 @@ int main(int argc, char* argv[])
|
||||
log_init(NULL, 0, NULL);
|
||||
checklock_start();
|
||||
#ifdef USE_WINSOCK
|
||||
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0)
|
||||
fatal_exit("WSAStartup failed: %s", wsa_strerror(r));
|
||||
/* use registry config file in preference to compiletime location */
|
||||
if(!(cfgfile=w_lookup_reg_str("Software\\Unbound", "ConfigFile")))
|
||||
cfgfile = CONFIGFILE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
ERR_load_SSL_strings();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(0, NULL);
|
||||
#endif
|
||||
|
||||
if(!RAND_status()) {
|
||||
/* try to seed it */
|
||||
unsigned char buf[256];
|
||||
unsigned int seed=(unsigned)time(NULL) ^ (unsigned)getpid();
|
||||
unsigned int v = seed;
|
||||
size_t i;
|
||||
for(i=0; i<256/sizeof(v); i++) {
|
||||
memmove(buf+i*sizeof(v), &v, sizeof(v));
|
||||
v = v*seed + (unsigned int)i;
|
||||
}
|
||||
RAND_seed(buf, 256);
|
||||
log_warn("no entropy, seeding openssl PRNG with time\n");
|
||||
}
|
||||
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:s:qh")) != -1) {
|
||||
switch(c) {
|
||||
@ -508,11 +740,51 @@ int main(int argc, char* argv[])
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
if(argc >= 1 && strcmp(argv[0], "stats_shm")==0) {
|
||||
print_stats_shm(cfgfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0)
|
||||
fatal_exit("WSAStartup failed: %s", wsa_strerror(r));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
ERR_load_SSL_strings();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(0, NULL);
|
||||
#endif
|
||||
|
||||
if(!RAND_status()) {
|
||||
/* try to seed it */
|
||||
unsigned char buf[256];
|
||||
unsigned int seed=(unsigned)time(NULL) ^ (unsigned)getpid();
|
||||
unsigned int v = seed;
|
||||
size_t i;
|
||||
for(i=0; i<256/sizeof(v); i++) {
|
||||
memmove(buf+i*sizeof(v), &v, sizeof(v));
|
||||
v = v*seed + (unsigned int)i;
|
||||
}
|
||||
RAND_seed(buf, 256);
|
||||
log_warn("no entropy, seeding openssl PRNG with time\n");
|
||||
}
|
||||
|
||||
ret = go(cfgfile, svr, quiet, argc, argv);
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
WSACleanup();
|
||||
#endif
|
||||
checklock_stop();
|
||||
return ret;
|
||||
|
@ -62,6 +62,9 @@
|
||||
#ifdef HAVE_GLOB_H
|
||||
# include <glob.h>
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/edns-subnet.h"
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@ -173,6 +176,13 @@ config_create(void)
|
||||
cfg->out_ifs = NULL;
|
||||
cfg->stubs = NULL;
|
||||
cfg->forwards = NULL;
|
||||
#ifdef CLIENT_SUBNET
|
||||
cfg->client_subnet = NULL;
|
||||
cfg->client_subnet_opcode = LDNS_EDNS_CLIENT_SUBNET;
|
||||
cfg->client_subnet_always_forward = 0;
|
||||
cfg->max_client_subnet_ipv4 = 24;
|
||||
cfg->max_client_subnet_ipv6 = 56;
|
||||
#endif
|
||||
cfg->views = NULL;
|
||||
cfg->acls = NULL;
|
||||
cfg->harden_short_bufsize = 0;
|
||||
@ -189,6 +199,7 @@ config_create(void)
|
||||
cfg->unwanted_threshold = 0;
|
||||
cfg->hide_identity = 0;
|
||||
cfg->hide_version = 0;
|
||||
cfg->hide_trustanchor = 0;
|
||||
cfg->identity = NULL;
|
||||
cfg->version = NULL;
|
||||
cfg->auto_trust_anchor_file_list = NULL;
|
||||
@ -237,7 +248,11 @@ config_create(void)
|
||||
if(!(cfg->control_cert_file = strdup(RUN_DIR"/unbound_control.pem")))
|
||||
goto error_exit;
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
if(!(cfg->module_conf = strdup("subnetcache validator iterator"))) goto error_exit;
|
||||
#else
|
||||
if(!(cfg->module_conf = strdup("validator iterator"))) goto error_exit;
|
||||
#endif
|
||||
if(!(cfg->val_nsec3_key_iterations =
|
||||
strdup("1024 150 2048 500 4096 2500"))) goto error_exit;
|
||||
#if defined(DNSTAP_SOCKET_PATH)
|
||||
@ -257,6 +272,13 @@ config_create(void)
|
||||
cfg->ratelimit_factor = 10;
|
||||
cfg->qname_minimisation = 0;
|
||||
cfg->qname_minimisation_strict = 0;
|
||||
cfg->shm_enable = 0;
|
||||
cfg->shm_key = 11777;
|
||||
cfg->dnscrypt = 0;
|
||||
cfg->dnscrypt_port = 0;
|
||||
cfg->dnscrypt_provider = NULL;
|
||||
cfg->dnscrypt_provider_cert = NULL;
|
||||
cfg->dnscrypt_secret_key = NULL;
|
||||
return cfg;
|
||||
error_exit:
|
||||
config_delete(cfg);
|
||||
@ -380,6 +402,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("log-identity:", log_identity)
|
||||
else S_YNO("extended-statistics:", stat_extended)
|
||||
else S_YNO("statistics-cumulative:", stat_cumulative)
|
||||
else S_YNO("shm-enable:", shm_enable)
|
||||
else S_NUMBER_OR_ZERO("shm-key:", shm_key)
|
||||
else S_YNO("do-ip4:", do_ip4)
|
||||
else S_YNO("do-ip6:", do_ip6)
|
||||
else S_YNO("do-udp:", do_udp)
|
||||
@ -433,6 +457,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("pidfile:", pidfile)
|
||||
else S_YNO("hide-identity:", hide_identity)
|
||||
else S_YNO("hide-version:", hide_version)
|
||||
else S_YNO("hide-trustanchor:", hide_trustanchor)
|
||||
else S_STR("identity:", identity)
|
||||
else S_STR("version:", version)
|
||||
else S_STRLIST("root-hints:", root_hints)
|
||||
@ -492,6 +517,12 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("module-config:", module_conf)
|
||||
else S_STR("python-script:", python_script)
|
||||
else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check)
|
||||
#ifdef CLIENT_SUBNET
|
||||
/* Can't set max subnet prefix here, since that value is used when
|
||||
* generating the address tree. */
|
||||
/* No client-subnet-always-forward here, module registration depends on
|
||||
* this option. */
|
||||
#endif
|
||||
else if(strcmp(opt, "ip-ratelimit:") == 0) {
|
||||
IS_NUMBER_OR_ZERO; cfg->ip_ratelimit = atoi(val);
|
||||
infra_ip_ratelimit=cfg->ip_ratelimit;
|
||||
@ -535,7 +566,9 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
* stub-ssl-upstream, forward-zone,
|
||||
* name, forward-addr, forward-host,
|
||||
* ratelimit-for-domain, ratelimit-below-domain,
|
||||
* local-zone-tag, access-control-view */
|
||||
* local-zone-tag, access-control-view
|
||||
* send-client-subnet client-subnet-always-forward
|
||||
* max-client-subnet-ipv4 max-client-subnet-ipv6 */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -697,6 +730,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_DEC(opt, "statistics-interval", stat_interval)
|
||||
else O_YNO(opt, "statistics-cumulative", stat_cumulative)
|
||||
else O_YNO(opt, "extended-statistics", stat_extended)
|
||||
else O_YNO(opt, "shm-enable", shm_enable)
|
||||
else O_DEC(opt, "shm-key", shm_key)
|
||||
else O_YNO(opt, "use-syslog", use_syslog)
|
||||
else O_STR(opt, "log-identity", log_identity)
|
||||
else O_YNO(opt, "log-time-ascii", log_time_ascii)
|
||||
@ -753,6 +788,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_STR(opt, "pidfile", pidfile)
|
||||
else O_YNO(opt, "hide-identity", hide_identity)
|
||||
else O_YNO(opt, "hide-version", hide_version)
|
||||
else O_YNO(opt, "hide-trustanchor", hide_trustanchor)
|
||||
else O_STR(opt, "identity", identity)
|
||||
else O_STR(opt, "version", version)
|
||||
else O_STR(opt, "target-fetch-policy", target_fetch_policy)
|
||||
@ -804,6 +840,13 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_UNS(opt, "val-override-date", val_date_override)
|
||||
else O_YNO(opt, "minimal-responses", minimal_responses)
|
||||
else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
|
||||
#ifdef CLIENT_SUBNET
|
||||
else O_LST(opt, "send-client-subnet", client_subnet)
|
||||
else O_DEC(opt, "max-client-subnet-ipv4", max_client_subnet_ipv4)
|
||||
else O_DEC(opt, "max-client-subnet-ipv6", max_client_subnet_ipv6)
|
||||
else O_YNO(opt, "client-subnet-always-forward:",
|
||||
client_subnet_always_forward)
|
||||
#endif
|
||||
else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones)
|
||||
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
|
||||
else O_DEC(opt, "max-udp-size", max_udp_size)
|
||||
@ -826,6 +869,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_IFC(opt, "define-tag", num_tags, tagname)
|
||||
else O_LTG(opt, "local-zone-tag", local_zone_tags)
|
||||
else O_LTG(opt, "access-control-tag", acl_tags)
|
||||
else O_LTG(opt, "response-ip-tag", respip_tags)
|
||||
else O_LS3(opt, "local-zone-override", local_zone_overrides)
|
||||
else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
|
||||
else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
|
||||
@ -934,6 +978,8 @@ config_read(struct config_file* cfg, const char* filename, const char* chroot)
|
||||
ub_c_parse();
|
||||
fclose(in);
|
||||
|
||||
if(!cfg->dnscrypt) cfg->dnscrypt_port = 0;
|
||||
|
||||
if(cfg_parser->errors != 0) {
|
||||
fprintf(stderr, "read %s failed: %d errors in configuration file\n",
|
||||
fname, cfg_parser->errors);
|
||||
@ -1083,6 +1129,9 @@ config_delete(struct config_file* cfg)
|
||||
config_delviews(cfg->views);
|
||||
config_delstrlist(cfg->donotqueryaddrs);
|
||||
config_delstrlist(cfg->root_hints);
|
||||
#ifdef CLIENT_SUBNET
|
||||
config_delstrlist(cfg->client_subnet);
|
||||
#endif
|
||||
free(cfg->identity);
|
||||
free(cfg->version);
|
||||
free(cfg->module_conf);
|
||||
@ -1106,6 +1155,7 @@ config_delete(struct config_file* cfg)
|
||||
config_del_strarray(cfg->tagname, cfg->num_tags);
|
||||
config_del_strbytelist(cfg->local_zone_tags);
|
||||
config_del_strbytelist(cfg->acl_tags);
|
||||
config_del_strbytelist(cfg->respip_tags);
|
||||
config_deltrplstrlist(cfg->acl_tag_actions);
|
||||
config_deltrplstrlist(cfg->acl_tag_datas);
|
||||
config_delstrlist(cfg->control_ifs);
|
||||
|
@ -172,6 +172,18 @@ struct config_file {
|
||||
struct config_view* views;
|
||||
/** list of donotquery addresses, linked list */
|
||||
struct config_strlist* donotqueryaddrs;
|
||||
#ifdef CLIENT_SUBNET
|
||||
/** list of servers we send edns-client-subnet option to and
|
||||
* accept option from, linked list */
|
||||
struct config_strlist* client_subnet;
|
||||
/** opcode assigned by IANA for edns0-client-subnet option */
|
||||
uint16_t client_subnet_opcode;
|
||||
/** Do not check whitelist if incoming query contains an ECS record */
|
||||
int client_subnet_always_forward;
|
||||
/** Subnet length we are willing to give up privacy for */
|
||||
uint8_t max_client_subnet_ipv4;
|
||||
uint8_t max_client_subnet_ipv6;
|
||||
#endif
|
||||
/** list of access control entries, linked list */
|
||||
struct config_str2list* acls;
|
||||
/** use default localhost donotqueryaddr entries */
|
||||
@ -238,6 +250,8 @@ struct config_file {
|
||||
int hide_identity;
|
||||
/** do not report version (version.server, version.bind) */
|
||||
int hide_version;
|
||||
/** do not report trustanchor (trustanchor.unbound) */
|
||||
int hide_trustanchor;
|
||||
/** identity, hostname is returned if "". */
|
||||
char* identity;
|
||||
/** version, package version returned if "". */
|
||||
@ -321,6 +335,12 @@ struct config_file {
|
||||
struct config_str3list* acl_tag_datas;
|
||||
/** list of aclname, view*/
|
||||
struct config_str2list* acl_view;
|
||||
/** list of IP-netblock, tagbitlist */
|
||||
struct config_strbytelist* respip_tags;
|
||||
/** list of response-driven access control entries, linked list */
|
||||
struct config_str2list* respip_actions;
|
||||
/** RRs configured for response-driven access controls */
|
||||
struct config_str2list* respip_data;
|
||||
/** tag list, array with tagname[i] is malloced string */
|
||||
char** tagname;
|
||||
/** number of items in the taglist */
|
||||
@ -422,6 +442,22 @@ struct config_file {
|
||||
/** minimise QNAME in strict mode, minimise according to RFC.
|
||||
* Do not apply fallback */
|
||||
int qname_minimisation_strict;
|
||||
/** SHM data - true if shm is enabled */
|
||||
int shm_enable;
|
||||
/** SHM data - key for the shm */
|
||||
int shm_key;
|
||||
|
||||
/** DNSCrypt */
|
||||
/** true to enable dnscrypt */
|
||||
int dnscrypt;
|
||||
/** port on which to provide dnscrypt service */
|
||||
int dnscrypt_port;
|
||||
/** provider name 2.dnscrypt-cert.example.com */
|
||||
char* dnscrypt_provider;
|
||||
/** dnscrypt secret keys 1.key */
|
||||
struct config_strlist* dnscrypt_secret_key;
|
||||
/** dnscrypt provider certs 1.cert */
|
||||
struct config_strlist* dnscrypt_provider_cert;
|
||||
};
|
||||
|
||||
/** from cfg username, after daemonise setup performed */
|
||||
@ -447,7 +483,7 @@ struct config_stub {
|
||||
int isprime;
|
||||
/** if forward-first is set (failover to without if fails) */
|
||||
int isfirst;
|
||||
/* use SSL for queries to this stub */
|
||||
/** use SSL for queries to this stub */
|
||||
int ssl_upstream;
|
||||
};
|
||||
|
||||
@ -468,6 +504,10 @@ struct config_view {
|
||||
/** Fallback to global local_zones when there is no match in the view
|
||||
* view specific tree. 1 for yes, 0 for no */
|
||||
int isfirst;
|
||||
/** predefined actions for particular IP address responses */
|
||||
struct config_str2list* respip_actions;
|
||||
/** data complementing the 'redirect' response IP actions */
|
||||
struct config_str2list* respip_data;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -964,6 +1004,6 @@ void w_config_adjust_directory(struct config_file* cfg);
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
/** debug option for unit tests. */
|
||||
extern int fake_dsa;
|
||||
extern int fake_dsa, fake_sha1;
|
||||
|
||||
#endif /* UTIL_CONFIG_FILE_H */
|
||||
|
@ -301,8 +301,14 @@ view-first{COLON} { YDVAR(1, VAR_VIEW_FIRST) }
|
||||
do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
|
||||
do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
|
||||
access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) }
|
||||
send-client-subnet{COLON} { YDVAR(1, VAR_SEND_CLIENT_SUBNET) }
|
||||
client-subnet-always-forward{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_ALWAYS_FORWARD) }
|
||||
client-subnet-opcode{COLON} { YDVAR(1, VAR_CLIENT_SUBNET_OPCODE) }
|
||||
max-client-subnet-ipv4{COLON} { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV4) }
|
||||
max-client-subnet-ipv6{COLON} { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV6) }
|
||||
hide-identity{COLON} { YDVAR(1, VAR_HIDE_IDENTITY) }
|
||||
hide-version{COLON} { YDVAR(1, VAR_HIDE_VERSION) }
|
||||
hide-trustanchor{COLON} { YDVAR(1, VAR_HIDE_TRUSTANCHOR) }
|
||||
identity{COLON} { YDVAR(1, VAR_IDENTITY) }
|
||||
version{COLON} { YDVAR(1, VAR_VERSION) }
|
||||
module-config{COLON} { YDVAR(1, VAR_MODULE_CONF) }
|
||||
@ -321,6 +327,7 @@ val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) }
|
||||
ignore-cd-flag{COLON} { YDVAR(1, VAR_IGNORE_CD_FLAG) }
|
||||
serve-expired{COLON} { YDVAR(1, VAR_SERVE_EXPIRED) }
|
||||
fake-dsa{COLON} { YDVAR(1, VAR_FAKE_DSA) }
|
||||
fake-sha1{COLON} { YDVAR(1, VAR_FAKE_SHA1) }
|
||||
val-log-level{COLON} { YDVAR(1, VAR_VAL_LOG_LEVEL) }
|
||||
key-cache-size{COLON} { YDVAR(1, VAR_KEY_CACHE_SIZE) }
|
||||
key-cache-slabs{COLON} { YDVAR(1, VAR_KEY_CACHE_SLABS) }
|
||||
@ -344,6 +351,8 @@ insecure-lan-zones{COLON} { YDVAR(1, VAR_INSECURE_LAN_ZONES) }
|
||||
statistics-interval{COLON} { YDVAR(1, VAR_STATISTICS_INTERVAL) }
|
||||
statistics-cumulative{COLON} { YDVAR(1, VAR_STATISTICS_CUMULATIVE) }
|
||||
extended-statistics{COLON} { YDVAR(1, VAR_EXTENDED_STATISTICS) }
|
||||
shm-enable{COLON} { YDVAR(1, VAR_SHM_ENABLE) }
|
||||
shm-key{COLON} { YDVAR(1, VAR_SHM_KEY) }
|
||||
remote-control{COLON} { YDVAR(0, VAR_REMOTE_CONTROL) }
|
||||
control-enable{COLON} { YDVAR(1, VAR_CONTROL_ENABLE) }
|
||||
control-interface{COLON} { YDVAR(1, VAR_CONTROL_INTERFACE) }
|
||||
@ -398,6 +407,15 @@ ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
|
||||
ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
|
||||
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
|
||||
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
|
||||
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) }
|
||||
dnscrypt{COLON} { YDVAR(0, VAR_DNSCRYPT) }
|
||||
dnscrypt-enable{COLON} { YDVAR(1, VAR_DNSCRYPT_ENABLE) }
|
||||
dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) }
|
||||
dnscrypt-provider{COLON} { YDVAR(1, VAR_DNSCRYPT_PROVIDER) }
|
||||
dnscrypt-secret-key{COLON} { YDVAR(1, VAR_DNSCRYPT_SECRET_KEY) }
|
||||
dnscrypt-provider-cert{COLON} { YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
@ -51,6 +51,8 @@
|
||||
int ub_c_lex(void);
|
||||
void ub_c_error(const char *message);
|
||||
|
||||
static void validate_respip_action(const char* action);
|
||||
|
||||
/* these need to be global, otherwise they cannot be used inside yacc */
|
||||
extern struct config_parser_state* cfg_parser;
|
||||
|
||||
@ -122,27 +124,34 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
||||
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||
%token VAR_DISABLE_DNSSEC_LAME_CHECK
|
||||
%token VAR_IP_RATELIMIT VAR_IP_RATELIMIT_SLABS VAR_IP_RATELIMIT_SIZE
|
||||
%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
|
||||
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
|
||||
%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
|
||||
%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ALWAYS_FORWARD
|
||||
%token VAR_CLIENT_SUBNET_OPCODE
|
||||
%token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
|
||||
%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
|
||||
%token VAR_QNAME_MINIMISATION VAR_QNAME_MINIMISATION_STRICT VAR_IP_FREEBIND
|
||||
%token VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG VAR_ACCESS_CONTROL_TAG
|
||||
%token VAR_LOCAL_ZONE_OVERRIDE VAR_ACCESS_CONTROL_TAG_ACTION
|
||||
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA
|
||||
%token VAR_LOG_IDENTITY
|
||||
%token VAR_USE_SYSTEMD
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
|
||||
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR
|
||||
%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
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
toplevelvar: serverstart contents_server | stubstart contents_stub |
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc | dtstart contents_dt | viewstart
|
||||
contents_view
|
||||
contents_view |
|
||||
dnscstart contents_dnsc
|
||||
;
|
||||
|
||||
/* server: declaration */
|
||||
@ -205,7 +214,10 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_ip_ratelimit_size | server_ratelimit_size |
|
||||
server_ratelimit_for_domain |
|
||||
server_ratelimit_below_domain | server_ratelimit_factor |
|
||||
server_ip_ratelimit_factor |
|
||||
server_ip_ratelimit_factor | server_send_client_subnet |
|
||||
server_client_subnet_always_forward |
|
||||
server_client_subnet_opcode |
|
||||
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
|
||||
server_caps_whitelist | server_cache_max_negative_ttl |
|
||||
server_permit_small_holddown | server_qname_minimisation |
|
||||
server_ip_freebind | server_define_tag | server_local_zone_tag |
|
||||
@ -213,7 +225,10 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_local_zone_override | server_access_control_tag_action |
|
||||
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_fake_dsa | server_log_identity | server_use_systemd |
|
||||
server_response_ip_tag | server_response_ip | server_response_ip_data |
|
||||
server_shm_enable | server_shm_key | server_fake_sha1 |
|
||||
server_hide_trustanchor
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
@ -265,7 +280,8 @@ viewstart: VAR_VIEW
|
||||
;
|
||||
contents_view: contents_view content_view
|
||||
| ;
|
||||
content_view: view_name | view_local_zone | view_local_data | view_first
|
||||
content_view: view_name | view_local_zone | view_local_data | view_first |
|
||||
view_response_ip | view_response_ip_data | view_local_data_ptr
|
||||
;
|
||||
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
||||
{
|
||||
@ -314,6 +330,26 @@ server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_shm_enable: VAR_SHM_ENABLE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_shm_enable:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->shm_enable = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_shm_key: VAR_SHM_KEY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_shm_key:%s)\n", $2));
|
||||
if(strcmp($2, "") == 0 || strcmp($2, "0") == 0)
|
||||
cfg_parser->cfg->shm_key = 0;
|
||||
else if(atoi($2) == 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->shm_key = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_port: VAR_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_port:%s)\n", $2));
|
||||
@ -323,6 +359,78 @@ server_port: VAR_PORT STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_send_client_subnet: VAR_SEND_CLIENT_SUBNET STRING_ARG
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
OUTYY(("P(server_send_client_subnet:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->client_subnet, $2))
|
||||
fatal_exit("out of memory adding client-subnet");
|
||||
#else
|
||||
OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
|
||||
#endif
|
||||
}
|
||||
;
|
||||
server_client_subnet_always_forward:
|
||||
VAR_CLIENT_SUBNET_ALWAYS_FORWARD STRING_ARG
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
OUTYY(("P(server_client_subnet_always_forward:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else
|
||||
cfg_parser->cfg->client_subnet_always_forward =
|
||||
(strcmp($2, "yes")==0);
|
||||
#else
|
||||
OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_client_subnet_opcode: VAR_CLIENT_SUBNET_OPCODE STRING_ARG
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
OUTYY(("P(client_subnet_opcode:%s)\n", $2));
|
||||
OUTYY(("P(Depricated option, ignoring)\n"));
|
||||
#else
|
||||
OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_max_client_subnet_ipv4: VAR_MAX_CLIENT_SUBNET_IPV4 STRING_ARG
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
OUTYY(("P(max_client_subnet_ipv4:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("IPv4 subnet length expected");
|
||||
else if (atoi($2) > 32)
|
||||
cfg_parser->cfg->max_client_subnet_ipv4 = 32;
|
||||
else if (atoi($2) < 0)
|
||||
cfg_parser->cfg->max_client_subnet_ipv4 = 0;
|
||||
else cfg_parser->cfg->max_client_subnet_ipv4 = (uint8_t)atoi($2);
|
||||
#else
|
||||
OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_max_client_subnet_ipv6: VAR_MAX_CLIENT_SUBNET_IPV6 STRING_ARG
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
OUTYY(("P(max_client_subnet_ipv6:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("Ipv6 subnet length expected");
|
||||
else if (atoi($2) > 128)
|
||||
cfg_parser->cfg->max_client_subnet_ipv6 = 128;
|
||||
else if (atoi($2) < 0)
|
||||
cfg_parser->cfg->max_client_subnet_ipv6 = 0;
|
||||
else cfg_parser->cfg->max_client_subnet_ipv6 = (uint8_t)atoi($2);
|
||||
#else
|
||||
OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_interface: VAR_INTERFACE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_interface:%s)\n", $2));
|
||||
@ -700,6 +808,15 @@ server_hide_version: VAR_HIDE_VERSION STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_hide_trustanchor: VAR_HIDE_TRUSTANCHOR STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_hide_trustanchor:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->hide_trustanchor = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_identity: VAR_IDENTITY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_identity:%s)\n", $2));
|
||||
@ -1236,6 +1353,19 @@ server_fake_dsa: VAR_FAKE_DSA STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_fake_sha1: VAR_FAKE_SHA1 STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_fake_sha1:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
#ifdef HAVE_SSL
|
||||
else fake_sha1 = (strcmp($2, "yes")==0);
|
||||
if(fake_sha1)
|
||||
log_warn("test option fake_sha1 is enabled");
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_val_log_level:%s)\n", $2));
|
||||
@ -1509,6 +1639,25 @@ server_access_control_view: VAR_ACCESS_CONTROL_VIEW STRING_ARG STRING_ARG
|
||||
}
|
||||
}
|
||||
;
|
||||
server_response_ip_tag: VAR_RESPONSE_IP_TAG STRING_ARG STRING_ARG
|
||||
{
|
||||
size_t len = 0;
|
||||
uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
|
||||
&len);
|
||||
free($3);
|
||||
OUTYY(("P(response_ip_tag:%s)\n", $2));
|
||||
if(!bitlist)
|
||||
yyerror("could not parse tags, (define-tag them first)");
|
||||
if(bitlist) {
|
||||
if(!cfg_strbytelist_insert(
|
||||
&cfg_parser->cfg->respip_tags,
|
||||
$2, bitlist, len)) {
|
||||
yyerror("out of memory");
|
||||
free($2);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
server_ip_ratelimit: VAR_IP_RATELIMIT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ip_ratelimit:%s)\n", $2));
|
||||
@ -1769,6 +1918,24 @@ view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
||||
}
|
||||
}
|
||||
;
|
||||
view_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(view_response_ip:%s %s)\n", $2, $3));
|
||||
validate_respip_action($3);
|
||||
if(!cfg_str2list_insert(
|
||||
&cfg_parser->cfg->views->respip_actions, $2, $3))
|
||||
fatal_exit("out of memory adding per-view "
|
||||
"response-ip action");
|
||||
}
|
||||
;
|
||||
view_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(view_response_ip_data:%s)\n", $2));
|
||||
if(!cfg_str2list_insert(
|
||||
&cfg_parser->cfg->views->respip_data, $2, $3))
|
||||
fatal_exit("out of memory adding response-ip-data");
|
||||
}
|
||||
;
|
||||
view_local_data: VAR_LOCAL_DATA STRING_ARG
|
||||
{
|
||||
OUTYY(("P(view_local_data:%s)\n", $2));
|
||||
@ -1778,6 +1945,21 @@ view_local_data: VAR_LOCAL_DATA STRING_ARG
|
||||
}
|
||||
}
|
||||
;
|
||||
view_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
|
||||
{
|
||||
char* ptr;
|
||||
OUTYY(("P(view_local_data_ptr:%s)\n", $2));
|
||||
ptr = cfg_ptr_reverse($2);
|
||||
free($2);
|
||||
if(ptr) {
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->views->
|
||||
local_data, ptr))
|
||||
fatal_exit("out of memory adding local-data");
|
||||
} else {
|
||||
yyerror("local-data-ptr could not be reversed");
|
||||
}
|
||||
}
|
||||
;
|
||||
view_first: VAR_VIEW_FIRST STRING_ARG
|
||||
{
|
||||
OUTYY(("P(view-first:%s)\n", $2));
|
||||
@ -2010,6 +2192,91 @@ server_log_identity: VAR_LOG_IDENTITY STRING_ARG
|
||||
cfg_parser->cfg->log_identity = $2;
|
||||
}
|
||||
;
|
||||
server_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_response_ip:%s %s)\n", $2, $3));
|
||||
validate_respip_action($3);
|
||||
if(!cfg_str2list_insert(&cfg_parser->cfg->respip_actions,
|
||||
$2, $3))
|
||||
fatal_exit("out of memory adding response-ip");
|
||||
}
|
||||
;
|
||||
server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_response_ip_data:%s)\n", $2));
|
||||
if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
|
||||
$2, $3))
|
||||
fatal_exit("out of memory adding response-ip-data");
|
||||
}
|
||||
;
|
||||
dnscstart: VAR_DNSCRYPT
|
||||
{
|
||||
OUTYY(("\nP(dnscrypt:)\n"));
|
||||
OUTYY(("\nP(dnscrypt:)\n"));
|
||||
}
|
||||
;
|
||||
contents_dnsc: contents_dnsc content_dnsc
|
||||
| ;
|
||||
content_dnsc:
|
||||
dnsc_dnscrypt_enable | dnsc_dnscrypt_port | dnsc_dnscrypt_provider |
|
||||
dnsc_dnscrypt_secret_key | dnsc_dnscrypt_provider_cert
|
||||
;
|
||||
dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dnsc_dnscrypt_enable:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnscrypt = (strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
|
||||
dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dnsc_dnscrypt_port:%s)\n", $2));
|
||||
|
||||
if(atoi($2) == 0)
|
||||
yyerror("port number expected");
|
||||
else cfg_parser->cfg->dnscrypt_port = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
dnsc_dnscrypt_provider: VAR_DNSCRYPT_PROVIDER STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dnsc_dnscrypt_provider:%s)\n", $2));
|
||||
free(cfg_parser->cfg->dnscrypt_provider);
|
||||
cfg_parser->cfg->dnscrypt_provider = $2;
|
||||
}
|
||||
;
|
||||
dnsc_dnscrypt_provider_cert: VAR_DNSCRYPT_PROVIDER_CERT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dnsc_dnscrypt_provider_cert:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, $2))
|
||||
fatal_exit("out of memory adding dnscrypt-provider-cert");
|
||||
}
|
||||
;
|
||||
dnsc_dnscrypt_secret_key: VAR_DNSCRYPT_SECRET_KEY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dnsc_dnscrypt_secret_key:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, $2))
|
||||
fatal_exit("out of memory adding dnscrypt-secret-key");
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
/* parse helper routines could be here */
|
||||
static void
|
||||
validate_respip_action(const char* action)
|
||||
{
|
||||
if(strcmp(action, "deny")!=0 &&
|
||||
strcmp(action, "redirect")!=0 &&
|
||||
strcmp(action, "inform")!=0 &&
|
||||
strcmp(action, "inform_deny")!=0 &&
|
||||
strcmp(action, "always_transparent")!=0 &&
|
||||
strcmp(action, "always_refuse")!=0 &&
|
||||
strcmp(action, "always_nxdomain")!=0)
|
||||
{
|
||||
yyerror("response-ip action: expected deny, redirect, "
|
||||
"inform, inform_deny, always_transparent, "
|
||||
"always_refuse or always_nxdomain");
|
||||
}
|
||||
}
|
||||
|
@ -459,6 +459,10 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
owner_labs = dname_count_labels(key->rk.dname);
|
||||
owner_pos = sldns_buffer_position(pkt);
|
||||
|
||||
/* For an rrset with a fixed TTL, use the rrset's TTL as given */
|
||||
if((key->rk.flags & PACKED_RRSET_FIXEDTTL) != 0)
|
||||
timenow = 0;
|
||||
|
||||
if(do_data) {
|
||||
const sldns_rr_descriptor* c = type_rdata_compressable(key);
|
||||
for(i=0; i<data->count; i++) {
|
||||
|
@ -133,9 +133,8 @@ parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** allocate (special) rrset keys, return 0 on error */
|
||||
static int
|
||||
repinfo_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
|
||||
int
|
||||
reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
|
||||
struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
@ -438,7 +437,7 @@ parse_create_msg(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
return 0;
|
||||
if(!parse_create_repinfo(msg, rep, region))
|
||||
return 0;
|
||||
if(!repinfo_alloc_rrset_keys(*rep, alloc, region))
|
||||
if(!reply_info_alloc_rrset_keys(*rep, alloc, region))
|
||||
return 0;
|
||||
if(!parse_copy_decompress(pkt, msg, *rep, region))
|
||||
return 0;
|
||||
@ -688,7 +687,7 @@ reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc,
|
||||
if(!cp)
|
||||
return NULL;
|
||||
/* allocate ub_key structures special or not */
|
||||
if(!repinfo_alloc_rrset_keys(cp, alloc, region)) {
|
||||
if(!reply_info_alloc_rrset_keys(cp, alloc, region)) {
|
||||
if(!region)
|
||||
reply_info_parsedelete(cp, alloc);
|
||||
return NULL;
|
||||
@ -984,19 +983,20 @@ int edns_opt_list_remove(struct edns_option** list, uint16_t code)
|
||||
}
|
||||
|
||||
static int inplace_cb_reply_call_generic(
|
||||
struct inplace_cb_reply* callback_list, enum inplace_cb_list_type type,
|
||||
struct inplace_cb* callback_list, enum inplace_cb_list_type type,
|
||||
struct query_info* qinfo, struct module_qstate* qstate,
|
||||
struct reply_info* rep, int rcode, struct edns_data* edns,
|
||||
struct regional* region)
|
||||
{
|
||||
struct inplace_cb_reply* cb;
|
||||
struct inplace_cb* cb;
|
||||
struct edns_option* opt_list_out = NULL;
|
||||
if(qstate)
|
||||
opt_list_out = qstate->edns_opts_front_out;
|
||||
for(cb=callback_list; cb; cb=cb->next) {
|
||||
fptr_ok(fptr_whitelist_inplace_cb_reply_generic(cb->cb, type));
|
||||
(void)(*cb->cb)(qinfo, qstate, rep, rcode, edns, &opt_list_out, region,
|
||||
cb->cb_arg);
|
||||
fptr_ok(fptr_whitelist_inplace_cb_reply_generic(
|
||||
(inplace_cb_reply_func_type*)cb->cb, type));
|
||||
(void)(*(inplace_cb_reply_func_type*)cb->cb)(qinfo, qstate, rep,
|
||||
rcode, edns, &opt_list_out, region, cb->id, cb->cb_arg);
|
||||
}
|
||||
edns->opt_list = opt_list_out;
|
||||
return 1;
|
||||
@ -1049,11 +1049,40 @@ int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo,
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
|
||||
struct regional* region)
|
||||
{
|
||||
struct inplace_cb_query* cb = env->inplace_cb_lists[inplace_cb_query];
|
||||
struct inplace_cb* cb = env->inplace_cb_lists[inplace_cb_query];
|
||||
for(; cb; cb=cb->next) {
|
||||
fptr_ok(fptr_whitelist_inplace_cb_query(cb->cb));
|
||||
(void)(*cb->cb)(qinfo, flags, qstate, addr, addrlen, zone, zonelen,
|
||||
region, cb->cb_arg);
|
||||
fptr_ok(fptr_whitelist_inplace_cb_query(
|
||||
(inplace_cb_query_func_type*)cb->cb));
|
||||
(void)(*(inplace_cb_query_func_type*)cb->cb)(qinfo, flags,
|
||||
qstate, addr, addrlen, zone, zonelen, region,
|
||||
cb->id, cb->cb_arg);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int inplace_cb_edns_back_parsed_call(struct module_env* env,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
struct inplace_cb* cb =
|
||||
env->inplace_cb_lists[inplace_cb_edns_back_parsed];
|
||||
for(; cb; cb=cb->next) {
|
||||
fptr_ok(fptr_whitelist_inplace_cb_edns_back_parsed(
|
||||
(inplace_cb_edns_back_parsed_func_type*)cb->cb));
|
||||
(void)(*(inplace_cb_edns_back_parsed_func_type*)cb->cb)(qstate,
|
||||
cb->id, cb->cb_arg);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int inplace_cb_query_response_call(struct module_env* env,
|
||||
struct module_qstate* qstate, struct dns_msg* response) {
|
||||
struct inplace_cb* cb =
|
||||
env->inplace_cb_lists[inplace_cb_query_response];
|
||||
for(; cb; cb=cb->next) {
|
||||
fptr_ok(fptr_whitelist_inplace_cb_query_response(
|
||||
(inplace_cb_query_response_func_type*)cb->cb));
|
||||
(void)(*(inplace_cb_query_response_func_type*)cb->cb)(qstate,
|
||||
response, cb->id, cb->cb_arg);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1148,6 +1177,7 @@ struct edns_option* edns_opt_copy_alloc(struct edns_option* list)
|
||||
if(s->opt_data) {
|
||||
s->opt_data = memdup(s->opt_data, s->opt_len);
|
||||
if(!s->opt_data) {
|
||||
free(s);
|
||||
edns_opt_list_free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -50,13 +50,13 @@ struct iovec;
|
||||
struct regional;
|
||||
struct edns_data;
|
||||
struct edns_option;
|
||||
struct inplace_cb_reply;
|
||||
struct inplace_cb_query;
|
||||
struct inplace_cb;
|
||||
struct module_qstate;
|
||||
struct module_env;
|
||||
struct msg_parse;
|
||||
struct rrset_parse;
|
||||
struct local_rrset;
|
||||
struct dns_msg;
|
||||
|
||||
/** calculate the prefetch TTL as 90% of original. Calculation
|
||||
* without numerical overflow (uin32_t) */
|
||||
@ -356,6 +356,21 @@ struct msgreply_entry* query_info_entrysetup(struct query_info* q,
|
||||
struct reply_info* reply_info_copy(struct reply_info* rep,
|
||||
struct alloc_cache* alloc, struct regional* region);
|
||||
|
||||
/**
|
||||
* Allocate (special) rrset keys.
|
||||
* @param rep: reply info in which the rrset keys to be allocated, rrset[]
|
||||
* array should have bee allocated with NULL pointers.
|
||||
* @param alloc: how to allocate rrset keys.
|
||||
* Not used if region!=NULL, it can be NULL in that case.
|
||||
* @param region: if this parameter is NULL then the alloc is used.
|
||||
* otherwise, rrset keys are allocated in this region.
|
||||
* In a region, no special rrset key structures are needed (not shared).
|
||||
* and no rrset_ref array in the reply needs to be built up.
|
||||
* @return 1 on success, 0 on error
|
||||
*/
|
||||
int reply_info_alloc_rrset_keys(struct reply_info* rep,
|
||||
struct alloc_cache* alloc, struct regional* region);
|
||||
|
||||
/**
|
||||
* Copy a parsed rrset into given key, decompressing and allocating rdata.
|
||||
* @param pkt: packet for decompression
|
||||
@ -607,6 +622,29 @@ int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo,
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
|
||||
struct regional* region);
|
||||
|
||||
/**
|
||||
* Call the registered functions in the inplace_cb_edns_back_parsed linked list.
|
||||
* This function is going to get called after parsing the EDNS data on the
|
||||
* reply from a nameserver.
|
||||
* @param env: module environment.
|
||||
* @param qstate: module qstate.
|
||||
* @return false on failure (a callback function returned an error).
|
||||
*/
|
||||
int inplace_cb_edns_back_parsed_call(struct module_env* env,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Call the registered functions in the inplace_cb_query_reponse linked list.
|
||||
* This function is going to get called after receiving a reply from a
|
||||
* nameserver.
|
||||
* @param env: module environment.
|
||||
* @param qstate: module qstate.
|
||||
* @param response: received response
|
||||
* @return false on failure (a callback function returned an error).
|
||||
*/
|
||||
int inplace_cb_query_response_call(struct module_env* env,
|
||||
struct module_qstate* qstate, struct dns_msg* response);
|
||||
|
||||
/**
|
||||
* Copy edns option list allocated to the new region
|
||||
*/
|
||||
|
@ -57,6 +57,10 @@ typedef uint64_t rrset_id_type;
|
||||
* this is set on SOA rrsets in the authority section, to keep its TTL separate
|
||||
* from the SOA in the answer section from a direct SOA query or ANY query. */
|
||||
#define PACKED_RRSET_SOA_NEG 0x4
|
||||
/** This rrset is considered to have a fixed TTL; its TTL doesn't have to be
|
||||
* updated on encoding in a reply. This flag is not expected to be set in
|
||||
* cached data. */
|
||||
#define PACKED_RRSET_FIXEDTTL 0x80000000
|
||||
|
||||
/** number of rrs and rrsets for integer overflow protection. More than
|
||||
* this is not really possible (64K packet has much less RRs and RRsets) in
|
||||
@ -83,6 +87,7 @@ struct packed_rrset_key {
|
||||
* o PACKED_RRSET_NSEC_AT_APEX
|
||||
* o PACKED_RRSET_PARENT_SIDE
|
||||
* o PACKED_RRSET_SOA_NEG
|
||||
* o PACKED_RRSET_FIXEDTTL (not supposed to be cached)
|
||||
*/
|
||||
uint32_t flags;
|
||||
/** the rrset type in network format */
|
||||
|
@ -75,6 +75,7 @@
|
||||
#ifdef UB_ON_WINDOWS
|
||||
#include "winrc/win_svc.h"
|
||||
#endif
|
||||
#include "respip/respip.h"
|
||||
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
#include "pythonmod/pythonmod.h"
|
||||
@ -82,6 +83,9 @@
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#endif
|
||||
|
||||
int
|
||||
fptr_whitelist_comm_point(comm_point_callback_type *fptr)
|
||||
@ -218,6 +222,9 @@ fptr_whitelist_hash_sizefunc(lruhash_sizefunc_type fptr)
|
||||
else if(fptr == &rate_sizefunc) return 1;
|
||||
else if(fptr == &ip_rate_sizefunc) return 1;
|
||||
else if(fptr == &test_slabhash_sizefunc) return 1;
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &msg_cache_sizefunc) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -256,6 +263,9 @@ fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_type fptr)
|
||||
else if(fptr == &key_entry_deldatafunc) return 1;
|
||||
else if(fptr == &rate_deldatafunc) return 1;
|
||||
else if(fptr == &test_slabhash_deldata) return 1;
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnet_data_delete) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -318,11 +328,15 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
|
||||
if(fptr == &iter_init) return 1;
|
||||
else if(fptr == &val_init) return 1;
|
||||
else if(fptr == &dns64_init) return 1;
|
||||
else if(fptr == &respip_init) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_init) return 1;
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else if(fptr == &cachedb_init) return 1;
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnetmod_init) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -333,11 +347,15 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||
if(fptr == &iter_deinit) return 1;
|
||||
else if(fptr == &val_deinit) return 1;
|
||||
else if(fptr == &dns64_deinit) return 1;
|
||||
else if(fptr == &respip_deinit) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_deinit) return 1;
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else if(fptr == &cachedb_deinit) return 1;
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnetmod_deinit) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -349,11 +367,15 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
||||
if(fptr == &iter_operate) return 1;
|
||||
else if(fptr == &val_operate) return 1;
|
||||
else if(fptr == &dns64_operate) return 1;
|
||||
else if(fptr == &respip_operate) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_operate) return 1;
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else if(fptr == &cachedb_operate) return 1;
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnetmod_operate) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -365,11 +387,15 @@ fptr_whitelist_mod_inform_super(void (*fptr)(
|
||||
if(fptr == &iter_inform_super) return 1;
|
||||
else if(fptr == &val_inform_super) return 1;
|
||||
else if(fptr == &dns64_inform_super) return 1;
|
||||
else if(fptr == &respip_inform_super) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_inform_super) return 1;
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else if(fptr == &cachedb_inform_super) return 1;
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnetmod_inform_super) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -381,11 +407,15 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
|
||||
if(fptr == &iter_clear) return 1;
|
||||
else if(fptr == &val_clear) return 1;
|
||||
else if(fptr == &dns64_clear) return 1;
|
||||
else if(fptr == &respip_clear) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_clear) return 1;
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else if(fptr == &cachedb_clear) return 1;
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnetmod_clear) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -396,11 +426,15 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
|
||||
if(fptr == &iter_get_mem) return 1;
|
||||
else if(fptr == &val_get_mem) return 1;
|
||||
else if(fptr == &dns64_get_mem) return 1;
|
||||
else if(fptr == &respip_get_mem) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_get_mem) return 1;
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
else if(fptr == &cachedb_get_mem) return 1;
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
else if(fptr == &subnetmod_get_mem) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -462,7 +496,37 @@ int fptr_whitelist_inplace_cb_reply_generic(inplace_cb_reply_func_type* fptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* ATTR_UNUSED(fptr))
|
||||
int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr)
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
if(fptr == &ecs_whitelist_check)
|
||||
return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fptr_whitelist_inplace_cb_edns_back_parsed(
|
||||
inplace_cb_edns_back_parsed_func_type* fptr)
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
if(fptr == &ecs_edns_back_parsed)
|
||||
return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fptr_whitelist_inplace_cb_query_response(
|
||||
inplace_cb_query_response_func_type* fptr)
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
if(fptr == &ecs_query_response)
|
||||
return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -351,6 +351,22 @@ int fptr_whitelist_inplace_cb_reply_generic(inplace_cb_reply_func_type* fptr,
|
||||
*/
|
||||
int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr);
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for inplace_cb_edns_back_parsed func values.
|
||||
* @param fptr: function pointer to check.
|
||||
* @return false if not in whitelist.
|
||||
*/
|
||||
int fptr_whitelist_inplace_cb_edns_back_parsed(
|
||||
inplace_cb_edns_back_parsed_func_type* fptr);
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for inplace_cb_query_response func values.
|
||||
* @param fptr: function pointer to check.
|
||||
* @return false if not in whitelist.
|
||||
*/
|
||||
int fptr_whitelist_inplace_cb_query_response(
|
||||
inplace_cb_query_response_func_type* fptr);
|
||||
|
||||
/** Due to module breakage by fptr wlist, these test app declarations
|
||||
* are presented here */
|
||||
/**
|
||||
|
@ -661,6 +661,7 @@
|
||||
847,
|
||||
848,
|
||||
853,
|
||||
854,
|
||||
860,
|
||||
861,
|
||||
862,
|
||||
@ -3776,6 +3777,7 @@
|
||||
4188,
|
||||
4191,
|
||||
4192,
|
||||
4197,
|
||||
4199,
|
||||
4300,
|
||||
4301,
|
||||
@ -4455,6 +4457,7 @@
|
||||
6446,
|
||||
6455,
|
||||
6456,
|
||||
6464,
|
||||
6471,
|
||||
6480,
|
||||
6481,
|
||||
@ -4571,6 +4574,7 @@
|
||||
7013,
|
||||
7014,
|
||||
7015,
|
||||
7016,
|
||||
7019,
|
||||
7020,
|
||||
7021,
|
||||
@ -4729,6 +4733,7 @@
|
||||
8002,
|
||||
8003,
|
||||
8005,
|
||||
8006,
|
||||
8008,
|
||||
8019,
|
||||
8020,
|
||||
|
@ -123,121 +123,29 @@ edns_register_option(uint16_t opt_code, int bypass_cache_stage,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
inplace_cb_reply_register_generic(inplace_cb_reply_func_type* cb,
|
||||
enum inplace_cb_list_type type, void* cb_arg, struct module_env* env)
|
||||
int
|
||||
inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
|
||||
struct module_env* env, int id)
|
||||
{
|
||||
struct inplace_cb_reply* callback;
|
||||
struct inplace_cb_reply** prevp;
|
||||
struct inplace_cb* callback;
|
||||
struct inplace_cb** prevp;
|
||||
if(env->worker) {
|
||||
log_err("invalid edns callback registration: "
|
||||
"trying to register callback after module init phase");
|
||||
return 0;
|
||||
}
|
||||
|
||||
callback = (struct inplace_cb_reply*)calloc(1, sizeof(*callback));
|
||||
callback = (struct inplace_cb*)calloc(1, sizeof(*callback));
|
||||
if(callback == NULL) {
|
||||
log_err("out of memory during edns callback registration.");
|
||||
return 0;
|
||||
}
|
||||
callback->id = id;
|
||||
callback->next = NULL;
|
||||
callback->cb = cb;
|
||||
callback->cb_arg = cb_arg;
|
||||
callback->cb_arg = cbarg;
|
||||
|
||||
prevp = (struct inplace_cb_reply**) &env->inplace_cb_lists[type];
|
||||
/* append at end of list */
|
||||
while(*prevp != NULL)
|
||||
prevp = &((*prevp)->next);
|
||||
*prevp = callback;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_reply_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env)
|
||||
{
|
||||
return inplace_cb_reply_register_generic(cb, inplace_cb_reply, cb_arg,
|
||||
env);
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_reply_cache_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env)
|
||||
{
|
||||
return inplace_cb_reply_register_generic(cb, inplace_cb_reply_cache,
|
||||
cb_arg, env);
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_reply_local_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env)
|
||||
{
|
||||
return inplace_cb_reply_register_generic(cb, inplace_cb_reply_local,
|
||||
cb_arg, env);
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_reply_servfail_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env)
|
||||
{
|
||||
return inplace_cb_reply_register_generic(cb, inplace_cb_reply_servfail,
|
||||
cb_arg, env);
|
||||
}
|
||||
|
||||
static void
|
||||
inplace_cb_reply_delete_generic(struct module_env* env,
|
||||
enum inplace_cb_list_type type)
|
||||
{
|
||||
struct inplace_cb_reply* curr = env->inplace_cb_lists[type];
|
||||
struct inplace_cb_reply* tmp;
|
||||
/* delete list */
|
||||
while(curr) {
|
||||
tmp = curr->next;
|
||||
free(curr);
|
||||
curr = tmp;
|
||||
}
|
||||
/* update head pointer */
|
||||
env->inplace_cb_lists[type] = NULL;
|
||||
}
|
||||
|
||||
void inplace_cb_reply_delete(struct module_env* env)
|
||||
{
|
||||
inplace_cb_reply_delete_generic(env, inplace_cb_reply);
|
||||
}
|
||||
|
||||
void inplace_cb_reply_cache_delete(struct module_env* env)
|
||||
{
|
||||
inplace_cb_reply_delete_generic(env, inplace_cb_reply_cache);
|
||||
}
|
||||
|
||||
void inplace_cb_reply_servfail_delete(struct module_env* env)
|
||||
{
|
||||
inplace_cb_reply_delete_generic(env, inplace_cb_reply_servfail);
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_query_register(inplace_cb_query_func_type* cb, void* cb_arg,
|
||||
struct module_env* env)
|
||||
{
|
||||
struct inplace_cb_query* callback;
|
||||
struct inplace_cb_query** prevp;
|
||||
if(env->worker) {
|
||||
log_err("invalid edns callback registration: "
|
||||
"trying to register callback after module init phase");
|
||||
return 0;
|
||||
}
|
||||
|
||||
callback = (struct inplace_cb_query*)calloc(1, sizeof(*callback));
|
||||
if(callback == NULL) {
|
||||
log_err("out of memory during edns callback registration.");
|
||||
return 0;
|
||||
}
|
||||
callback->next = NULL;
|
||||
callback->cb = cb;
|
||||
callback->cb_arg = cb_arg;
|
||||
|
||||
prevp = (struct inplace_cb_query**)
|
||||
&env->inplace_cb_lists[inplace_cb_query];
|
||||
prevp = (struct inplace_cb**) &env->inplace_cb_lists[type];
|
||||
/* append at end of list */
|
||||
while(*prevp != NULL)
|
||||
prevp = &((*prevp)->next);
|
||||
@ -246,27 +154,30 @@ inplace_cb_query_register(inplace_cb_query_func_type* cb, void* cb_arg,
|
||||
}
|
||||
|
||||
void
|
||||
inplace_cb_query_delete(struct module_env* env)
|
||||
inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type,
|
||||
int id)
|
||||
{
|
||||
struct inplace_cb_query* curr = env->inplace_cb_lists[inplace_cb_query];
|
||||
struct inplace_cb_query* tmp;
|
||||
/* delete list */
|
||||
while(curr) {
|
||||
tmp = curr->next;
|
||||
free(curr);
|
||||
curr = tmp;
|
||||
}
|
||||
/* update head pointer */
|
||||
env->inplace_cb_lists[inplace_cb_query] = NULL;
|
||||
}
|
||||
struct inplace_cb* temp = env->inplace_cb_lists[type];
|
||||
struct inplace_cb* prev = NULL;
|
||||
|
||||
void
|
||||
inplace_cb_lists_delete(struct module_env* env)
|
||||
{
|
||||
inplace_cb_reply_delete(env);
|
||||
inplace_cb_reply_cache_delete(env);
|
||||
inplace_cb_reply_servfail_delete(env);
|
||||
inplace_cb_query_delete(env);
|
||||
while(temp) {
|
||||
if(temp->id == id) {
|
||||
if(!prev) {
|
||||
env->inplace_cb_lists[type] = temp->next;
|
||||
free(temp);
|
||||
temp = env->inplace_cb_lists[type];
|
||||
}
|
||||
else {
|
||||
prev->next = temp->next;
|
||||
free(temp);
|
||||
temp = prev->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prev = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct edns_known_option*
|
||||
@ -292,9 +203,11 @@ edns_bypass_cache_stage(struct edns_option* list, struct module_env* env)
|
||||
}
|
||||
|
||||
int
|
||||
edns_unique_mesh_state(struct edns_option* list, struct module_env* env)
|
||||
unique_mesh_state(struct edns_option* list, struct module_env* env)
|
||||
{
|
||||
size_t i;
|
||||
if(env->unique_mesh)
|
||||
return 1;
|
||||
for(; list; list=list->next)
|
||||
for(i=0; i<env->edns_known_options_num; i++)
|
||||
if(env->edns_known_options[i].opt_code == list->opt_code &&
|
||||
|
@ -174,6 +174,9 @@ struct val_anchors;
|
||||
struct val_neg_cache;
|
||||
struct iter_forwards;
|
||||
struct iter_hints;
|
||||
struct respip_set;
|
||||
struct respip_client_info;
|
||||
struct respip_addr_info;
|
||||
|
||||
/** Maximum number of modules in operation */
|
||||
#define MAX_MODULE 16
|
||||
@ -194,6 +197,11 @@ enum inplace_cb_list_type {
|
||||
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_query_response,
|
||||
/* Inplace callback for when EDNS is parsed on a reply 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
|
||||
@ -210,6 +218,19 @@ struct edns_known_option {
|
||||
int no_aggregation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inplace callback list of registered routines to be called.
|
||||
*/
|
||||
struct inplace_cb {
|
||||
/** next in list */
|
||||
struct inplace_cb* next;
|
||||
/** Inplace callback routine */
|
||||
void* cb;
|
||||
void* cb_arg;
|
||||
/** module id */
|
||||
int id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inplace callback function called before replying.
|
||||
* Called as func(edns, qstate, opt_list_out, qinfo, reply_info, rcode,
|
||||
@ -229,24 +250,7 @@ struct edns_known_option {
|
||||
typedef int inplace_cb_reply_func_type(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, void* python_callback);
|
||||
|
||||
/**
|
||||
* Inplace callback list of registered routines to be called before replying
|
||||
* with a resolved query.
|
||||
*/
|
||||
struct inplace_cb_reply {
|
||||
/** next in list */
|
||||
struct inplace_cb_reply* next;
|
||||
/**
|
||||
* Inplace callback routine for cache stage response.
|
||||
* called as cb(qinfo, qstate, qinfo, reply_info, rcode, edns,
|
||||
* opt_list_out, region, python_callback);
|
||||
* python_callback is only used for registering a python callback function.
|
||||
*/
|
||||
inplace_cb_reply_func_type* cb;
|
||||
void* cb_arg;
|
||||
};
|
||||
struct regional* region, int id, void* callback);
|
||||
|
||||
/**
|
||||
* Inplace callback function called before sending the query to a nameserver.
|
||||
@ -268,24 +272,30 @@ struct inplace_cb_reply {
|
||||
typedef int inplace_cb_query_func_type(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,
|
||||
void* python_callback);
|
||||
int id, void* callback);
|
||||
|
||||
/**
|
||||
* Inplace callback list of registered routines to be called before quering a
|
||||
* nameserver.
|
||||
* Inplace callback function called after parsing edns on query reply.
|
||||
* Called as func(qstate, cb_args)
|
||||
* Where:
|
||||
* qstate: the query state
|
||||
* id: module id
|
||||
* cb_args: argument passed when registering callback.
|
||||
*/
|
||||
struct inplace_cb_query {
|
||||
/** next in list */
|
||||
struct inplace_cb_query* next;
|
||||
/**
|
||||
* Inplace callback routine for cache stage response.
|
||||
* called as cb(qinfo, flags, qstate, addr, addrlen, zone, zonelen,
|
||||
* region, python_callback);
|
||||
* python_callback is only used for registering a python callback function.
|
||||
*/
|
||||
inplace_cb_query_func_type* cb;
|
||||
void* cb_arg;
|
||||
};
|
||||
typedef int inplace_cb_edns_back_parsed_func_type(struct module_qstate* qstate,
|
||||
int id, void* cb_args);
|
||||
|
||||
/**
|
||||
* Inplace callback function called after parsing query response.
|
||||
* Called as func(qstate, id, cb_args)
|
||||
* Where:
|
||||
* qstate: the query state
|
||||
* response: query response
|
||||
* id: module id
|
||||
* cb_args: argument passed when registering callback.
|
||||
*/
|
||||
typedef int inplace_cb_query_response_func_type(struct module_qstate* qstate,
|
||||
struct dns_msg* response, int id, void* cb_args);
|
||||
|
||||
/**
|
||||
* Module environment.
|
||||
@ -442,7 +452,7 @@ struct module_env {
|
||||
void* modinfo[MAX_MODULE];
|
||||
|
||||
/* Shared linked list of inplace callback functions */
|
||||
void* inplace_cb_lists[inplace_cb_types_total];
|
||||
struct inplace_cb* inplace_cb_lists[inplace_cb_types_total];
|
||||
|
||||
/**
|
||||
* Shared array of known edns options (size MAX_KNOWN_EDNS_OPTS).
|
||||
@ -451,6 +461,9 @@ struct module_env {
|
||||
struct edns_known_option* edns_known_options;
|
||||
/* Number of known edns options */
|
||||
size_t edns_known_options_num;
|
||||
|
||||
/* Make every mesh state unique, do not aggregate mesh states. */
|
||||
int unique_mesh;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -508,6 +521,8 @@ struct sock_list {
|
||||
struct sockaddr_storage addr;
|
||||
};
|
||||
|
||||
struct respip_action_info;
|
||||
|
||||
/**
|
||||
* Module state, per query.
|
||||
*/
|
||||
@ -562,6 +577,19 @@ struct module_qstate {
|
||||
int no_cache_lookup;
|
||||
/** whether modules should store answer in the cache */
|
||||
int no_cache_store;
|
||||
|
||||
/**
|
||||
* Attributes of clients that share the qstate that may affect IP-based
|
||||
* actions.
|
||||
*/
|
||||
struct respip_client_info* client_info;
|
||||
|
||||
/** Extended result of response-ip action processing, mainly
|
||||
* for logging purposes. */
|
||||
struct respip_action_info* respip_action_info;
|
||||
|
||||
/** whether the reply should be dropped */
|
||||
int is_drop;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -680,85 +708,28 @@ int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
|
||||
int no_aggregation, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Register an inplace callback function called before replying with a resolved
|
||||
* query.
|
||||
* Register an inplace callback function.
|
||||
* @param cb: pointer to the callback function.
|
||||
* @param cb_arg: optional argument for the callback function.
|
||||
* @param type: inplace callback type.
|
||||
* @param cbarg: argument for the callback function, or NULL.
|
||||
* @param env: the module environment.
|
||||
* @param id: module id.
|
||||
* @return true on success, false on failure (out of memory or trying to
|
||||
* register after the environment is copied to the threads.)
|
||||
*/
|
||||
int inplace_cb_reply_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env);
|
||||
int
|
||||
inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
|
||||
struct module_env* env, int id);
|
||||
|
||||
/**
|
||||
* Register an inplace callback function called before replying from the cache.
|
||||
* @param cb: pointer to the callback function.
|
||||
* @param cb_arg: optional argument for the callback function.
|
||||
* Delete callback for specified type and module id.
|
||||
* @param env: the module environment.
|
||||
* @return true on success, false on failure (out of memory or trying to
|
||||
* register after the environment is copied to the threads.)
|
||||
* @param type: inplace callback type.
|
||||
* @param id: module id.
|
||||
*/
|
||||
int inplace_cb_reply_cache_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Register an inplace callback function called before replying with local
|
||||
* data or Chaos reply.
|
||||
* @param cb: pointer to the callback function.
|
||||
* @param cb_arg: optional argument for the callback function.
|
||||
* @param env: the module environment.
|
||||
* @return true on success, false on failure (out of memory or trying to
|
||||
* register after the environment is copied to the threads.)
|
||||
*/
|
||||
int inplace_cb_reply_local_register(inplace_cb_reply_func_type* cb, void* cb_arg,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Register an inplace callback function called before replying with servfail.
|
||||
* @param cb: pointer to the callback function.
|
||||
* @param cb_arg: optional argument for the callback function.
|
||||
* @param env: the module environment.
|
||||
* @return true on success, false on failure (out of memory or trying to
|
||||
* register after the environment is copied to the threads.)
|
||||
*/
|
||||
int inplace_cb_reply_servfail_register(inplace_cb_reply_func_type* cb,
|
||||
void* cb_arg, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Delete the inplace_cb_reply callback linked list.
|
||||
* @param env: the module environment.
|
||||
*/
|
||||
void inplace_cb_reply_delete(struct module_env* env);
|
||||
|
||||
/**
|
||||
* Delete the inplace_cb_reply_cache callback linked list.
|
||||
* @param env: the module environment.
|
||||
*/
|
||||
void inplace_cb_reply_cache_delete(struct module_env* env);
|
||||
|
||||
/**
|
||||
* Delete the inplace_cb_reply_servfail callback linked list.
|
||||
* @param env: the module environment.
|
||||
*/
|
||||
void inplace_cb_reply_servfail_delete(struct module_env* env);
|
||||
|
||||
/**
|
||||
* Register an inplace callback function called before quering a nameserver.
|
||||
* @param cb: pointer to the callback function.
|
||||
* @param cb_arg: optional argument for the callback function.
|
||||
* @param env: the module environment.
|
||||
* @return true on success, false on failure (out of memory or trying to
|
||||
* register after the environment is copied to the threads.)
|
||||
*/
|
||||
int inplace_cb_query_register(inplace_cb_query_func_type* cb, void* cb_arg,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Delete the inplace_cb_query callback linked list.
|
||||
* @param env: the module environment.
|
||||
*/
|
||||
void inplace_cb_query_delete(struct module_env* env);
|
||||
void
|
||||
inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type,
|
||||
int id);
|
||||
|
||||
/**
|
||||
* Delete all the inplace callback linked lists.
|
||||
@ -787,13 +758,14 @@ int edns_bypass_cache_stage(struct edns_option* list,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Check if an edns option needs a unique mesh state.
|
||||
* Check if an unique mesh state is required. Might be triggered by EDNS option
|
||||
* or set for the complete env.
|
||||
* @param list: the edns options.
|
||||
* @param env: the module environment.
|
||||
* @return true if an edns option needs a unique mesh state,
|
||||
* false otherwise.
|
||||
*/
|
||||
int edns_unique_mesh_state(struct edns_option* list, struct module_env* env);
|
||||
int unique_mesh_state(struct edns_option* list, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Log the known edns options.
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
@ -665,6 +666,7 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
struct comm_reply rep;
|
||||
ssize_t rcv;
|
||||
int i;
|
||||
struct sldns_buffer *buffer;
|
||||
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
@ -701,7 +703,12 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
fptr_ok(fptr_whitelist_comm_point(rep.c->callback));
|
||||
if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
|
||||
/* send back immediate reply */
|
||||
(void)comm_point_send_udp_msg(rep.c, rep.c->buffer,
|
||||
#ifdef USE_DNSCRYPT
|
||||
buffer = rep.c->dnscrypt_buffer;
|
||||
#else
|
||||
buffer = rep.c->buffer;
|
||||
#endif
|
||||
(void)comm_point_send_udp_msg(rep.c, buffer,
|
||||
(struct sockaddr*)&rep.addr, rep.addrlen);
|
||||
}
|
||||
if(rep.c->fd != fd) /* commpoint closed to -1 or reused for
|
||||
@ -717,6 +724,10 @@ setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
|
||||
log_assert(c->type == comm_tcp);
|
||||
log_assert(c->fd == -1);
|
||||
sldns_buffer_clear(c->buffer);
|
||||
#ifdef USE_DNSCRYPT
|
||||
if (c->dnscrypt)
|
||||
sldns_buffer_clear(c->dnscrypt_buffer);
|
||||
#endif
|
||||
c->tcp_is_reading = 1;
|
||||
c->tcp_byte_count = 0;
|
||||
c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
|
||||
@ -1310,7 +1321,13 @@ static int
|
||||
comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
{
|
||||
ssize_t r;
|
||||
struct sldns_buffer *buffer;
|
||||
log_assert(c->type == comm_tcp);
|
||||
#ifdef USE_DNSCRYPT
|
||||
buffer = c->dnscrypt_buffer;
|
||||
#else
|
||||
buffer = c->buffer;
|
||||
#endif
|
||||
if(c->tcp_is_reading && !c->ssl)
|
||||
return 0;
|
||||
log_assert(fd != -1);
|
||||
@ -1364,15 +1381,15 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
if(c->tcp_do_fastopen == 1) {
|
||||
/* this form of sendmsg() does both a connect() and send() so need to
|
||||
look for various flavours of error*/
|
||||
uint16_t len = htons(sldns_buffer_limit(c->buffer));
|
||||
uint16_t len = htons(sldns_buffer_limit(buffer));
|
||||
struct msghdr msg;
|
||||
struct iovec iov[2];
|
||||
c->tcp_do_fastopen = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
|
||||
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
|
||||
iov[1].iov_base = sldns_buffer_begin(c->buffer);
|
||||
iov[1].iov_len = sldns_buffer_limit(c->buffer);
|
||||
iov[1].iov_base = sldns_buffer_begin(buffer);
|
||||
iov[1].iov_len = sldns_buffer_limit(buffer);
|
||||
log_assert(iov[0].iov_len > 0);
|
||||
log_assert(iov[1].iov_len > 0);
|
||||
msg.msg_name = &c->repinfo.addr;
|
||||
@ -1400,9 +1417,9 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
c->tcp_byte_count += r;
|
||||
if(c->tcp_byte_count < sizeof(uint16_t))
|
||||
return 1;
|
||||
sldns_buffer_set_position(c->buffer, c->tcp_byte_count -
|
||||
sldns_buffer_set_position(buffer, c->tcp_byte_count -
|
||||
sizeof(uint16_t));
|
||||
if(sldns_buffer_remaining(c->buffer) == 0) {
|
||||
if(sldns_buffer_remaining(buffer) == 0) {
|
||||
tcp_callback_writer(c);
|
||||
return 1;
|
||||
}
|
||||
@ -1411,13 +1428,13 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
#endif /* USE_MSG_FASTOPEN */
|
||||
|
||||
if(c->tcp_byte_count < sizeof(uint16_t)) {
|
||||
uint16_t len = htons(sldns_buffer_limit(c->buffer));
|
||||
uint16_t len = htons(sldns_buffer_limit(buffer));
|
||||
#ifdef HAVE_WRITEV
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
|
||||
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
|
||||
iov[1].iov_base = sldns_buffer_begin(c->buffer);
|
||||
iov[1].iov_len = sldns_buffer_limit(c->buffer);
|
||||
iov[1].iov_base = sldns_buffer_begin(buffer);
|
||||
iov[1].iov_len = sldns_buffer_limit(buffer);
|
||||
log_assert(iov[0].iov_len > 0);
|
||||
log_assert(iov[1].iov_len > 0);
|
||||
r = writev(fd, iov, 2);
|
||||
@ -1459,16 +1476,16 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
c->tcp_byte_count += r;
|
||||
if(c->tcp_byte_count < sizeof(uint16_t))
|
||||
return 1;
|
||||
sldns_buffer_set_position(c->buffer, c->tcp_byte_count -
|
||||
sldns_buffer_set_position(buffer, c->tcp_byte_count -
|
||||
sizeof(uint16_t));
|
||||
if(sldns_buffer_remaining(c->buffer) == 0) {
|
||||
if(sldns_buffer_remaining(buffer) == 0) {
|
||||
tcp_callback_writer(c);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
log_assert(sldns_buffer_remaining(c->buffer) > 0);
|
||||
r = send(fd, (void*)sldns_buffer_current(c->buffer),
|
||||
sldns_buffer_remaining(c->buffer), 0);
|
||||
log_assert(sldns_buffer_remaining(buffer) > 0);
|
||||
r = send(fd, (void*)sldns_buffer_current(buffer),
|
||||
sldns_buffer_remaining(buffer), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
@ -1487,9 +1504,9 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_skip(c->buffer, r);
|
||||
sldns_buffer_skip(buffer, r);
|
||||
|
||||
if(sldns_buffer_remaining(c->buffer) == 0) {
|
||||
if(sldns_buffer_remaining(buffer) == 0) {
|
||||
tcp_callback_writer(c);
|
||||
}
|
||||
|
||||
@ -1503,6 +1520,20 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
|
||||
log_assert(c->type == comm_tcp);
|
||||
ub_comm_base_now(c->ev->base);
|
||||
|
||||
#ifdef USE_DNSCRYPT
|
||||
/* Initialize if this is a dnscrypt socket */
|
||||
if(c->tcp_parent) {
|
||||
c->dnscrypt = c->tcp_parent->dnscrypt;
|
||||
}
|
||||
if(c->dnscrypt && c->dnscrypt_buffer == c->buffer) {
|
||||
c->dnscrypt_buffer = sldns_buffer_new(sldns_buffer_capacity(c->buffer));
|
||||
if(!c->dnscrypt_buffer) {
|
||||
log_err("Could not allocate dnscrypt buffer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(event&UB_EV_READ) {
|
||||
if(!comm_point_tcp_handle_read(fd, c, 0)) {
|
||||
reclaim_tcp_handler(c);
|
||||
@ -1604,6 +1635,10 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
|
||||
c->tcp_check_nb_connect = 0;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 0;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = buffer;
|
||||
#endif
|
||||
c->inuse = 0;
|
||||
c->callback = callback;
|
||||
@ -1655,6 +1690,10 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
|
||||
c->type = comm_udp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = buffer;
|
||||
#endif
|
||||
c->inuse = 0;
|
||||
c->tcp_do_toggle_rw = 0;
|
||||
c->tcp_check_nb_connect = 0;
|
||||
@ -1725,6 +1764,12 @@ comm_point_create_tcp_handler(struct comm_base *base,
|
||||
c->tcp_check_nb_connect = 0;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 0;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
// We don't know just yet if this is a dnscrypt channel. Allocation
|
||||
// will be done when handling the callback.
|
||||
c->dnscrypt_buffer = c->buffer;
|
||||
#endif
|
||||
c->repinfo.c = c;
|
||||
c->callback = callback;
|
||||
@ -1788,6 +1833,10 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
|
||||
c->tcp_check_nb_connect = 0;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 0;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = NULL;
|
||||
#endif
|
||||
c->callback = NULL;
|
||||
c->cb_arg = NULL;
|
||||
@ -1856,6 +1905,10 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
|
||||
c->tcp_check_nb_connect = 1;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 1;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = c->buffer;
|
||||
#endif
|
||||
c->repinfo.c = c;
|
||||
c->callback = callback;
|
||||
@ -1913,6 +1966,10 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
|
||||
c->tcp_check_nb_connect = 0;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 0;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = c->buffer;
|
||||
#endif
|
||||
c->callback = callback;
|
||||
c->cb_arg = callback_arg;
|
||||
@ -1969,6 +2026,10 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
|
||||
c->tcp_check_nb_connect = 0;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 0;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = c->buffer;
|
||||
#endif
|
||||
c->callback = callback;
|
||||
c->cb_arg = callback_arg;
|
||||
@ -2034,8 +2095,14 @@ comm_point_delete(struct comm_point* c)
|
||||
free(c->tcp_handlers);
|
||||
}
|
||||
free(c->timeout);
|
||||
if(c->type == comm_tcp || c->type == comm_local)
|
||||
if(c->type == comm_tcp || c->type == comm_local) {
|
||||
sldns_buffer_free(c->buffer);
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(c->dnscrypt && c->dnscrypt_buffer != c->buffer) {
|
||||
sldns_buffer_free(c->dnscrypt_buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ub_event_free(c->ev->ev);
|
||||
free(c->ev);
|
||||
free(c);
|
||||
@ -2044,14 +2111,23 @@ comm_point_delete(struct comm_point* c)
|
||||
void
|
||||
comm_point_send_reply(struct comm_reply *repinfo)
|
||||
{
|
||||
struct sldns_buffer* buffer;
|
||||
log_assert(repinfo && repinfo->c);
|
||||
#ifdef USE_DNSCRYPT
|
||||
buffer = repinfo->c->dnscrypt_buffer;
|
||||
if(!dnsc_handle_uncurved_request(repinfo)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
buffer = repinfo->c->buffer;
|
||||
#endif
|
||||
if(repinfo->c->type == comm_udp) {
|
||||
if(repinfo->srctype)
|
||||
comm_point_send_udp_msg_if(repinfo->c,
|
||||
repinfo->c->buffer, (struct sockaddr*)&repinfo->addr,
|
||||
buffer, (struct sockaddr*)&repinfo->addr,
|
||||
repinfo->addrlen, repinfo);
|
||||
else
|
||||
comm_point_send_udp_msg(repinfo->c, repinfo->c->buffer,
|
||||
comm_point_send_udp_msg(repinfo->c, buffer,
|
||||
(struct sockaddr*)&repinfo->addr, repinfo->addrlen);
|
||||
#ifdef USE_DNSTAP
|
||||
if(repinfo->c->dtenv != NULL &&
|
||||
@ -2160,8 +2236,15 @@ size_t comm_point_get_mem(struct comm_point* c)
|
||||
s = sizeof(*c) + sizeof(*c->ev);
|
||||
if(c->timeout)
|
||||
s += sizeof(*c->timeout);
|
||||
if(c->type == comm_tcp || c->type == comm_local)
|
||||
if(c->type == comm_tcp || c->type == comm_local) {
|
||||
s += sizeof(*c->buffer) + sldns_buffer_capacity(c->buffer);
|
||||
#ifdef USE_DNSCRYPT
|
||||
s += sizeof(*c->dnscrypt_buffer);
|
||||
if(c->buffer != c->dnscrypt_buffer) {
|
||||
s += sldns_buffer_capacity(c->dnscrypt_buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if(c->type == comm_tcp_accept) {
|
||||
int i;
|
||||
for(i=0; i<c->max_tcp_count; i++)
|
||||
|
@ -60,6 +60,8 @@
|
||||
#ifndef NET_EVENT_H
|
||||
#define NET_EVENT_H
|
||||
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
|
||||
struct sldns_buffer;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
@ -114,6 +116,13 @@ struct comm_reply {
|
||||
socklen_t addrlen;
|
||||
/** return type 0 (none), 4(IP4), 6(IP6) */
|
||||
int srctype;
|
||||
/* DnsCrypt context */
|
||||
#ifdef USE_DNSCRYPT
|
||||
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
|
||||
uint8_t nmkey[crypto_box_BEFORENMBYTES];
|
||||
const KeyPair *keypair;
|
||||
int is_dnscrypted;
|
||||
#endif
|
||||
/** the return source interface data */
|
||||
union {
|
||||
#ifdef IPV6_PKTINFO
|
||||
@ -127,6 +136,8 @@ struct comm_reply {
|
||||
}
|
||||
/** variable with return source data */
|
||||
pktinfo;
|
||||
/** max udp size for udp packets */
|
||||
size_t max_udp_size;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -236,6 +247,12 @@ struct comm_point {
|
||||
int tcp_do_fastopen;
|
||||
#endif
|
||||
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** Is this a dnscrypt channel */
|
||||
int dnscrypt;
|
||||
/** encrypted buffer pointer. Either to perthread, or own buffer or NULL */
|
||||
struct sldns_buffer* dnscrypt_buffer;
|
||||
#endif
|
||||
/** number of queries outstanding on this socket, used by
|
||||
* outside network for udp ports */
|
||||
int inuse;
|
||||
|
286
contrib/unbound/util/shm_side/shm_main.c
Normal file
286
contrib/unbound/util/shm_side/shm_main.c
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* util/shm_side/shm_main.c - SHM for statistics transport
|
||||
*
|
||||
* 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 functions for the SHM implementation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_SYS_IPC_H
|
||||
#include <sys/ipc.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SHM_H
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include "shm_main.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "validator/validator.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#ifdef HAVE_SHMGET
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
static void
|
||||
timeval_subtract(struct timeval* d, const struct timeval* end,
|
||||
const struct timeval* start)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
time_t end_usec = end->tv_usec;
|
||||
d->tv_sec = end->tv_sec - start->tv_sec;
|
||||
if(end_usec < start->tv_usec) {
|
||||
end_usec += 1000000;
|
||||
d->tv_sec--;
|
||||
}
|
||||
d->tv_usec = end_usec - start->tv_usec;
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_SHMGET */
|
||||
|
||||
int shm_main_init(struct daemon* daemon)
|
||||
{
|
||||
#ifdef HAVE_SHMGET
|
||||
struct shm_stat_info *shm_stat;
|
||||
size_t shm_size;
|
||||
|
||||
/* sanitize */
|
||||
if(!daemon)
|
||||
return 0;
|
||||
if(!daemon->cfg->shm_enable)
|
||||
return 1;
|
||||
if(daemon->cfg->stat_interval == 0)
|
||||
log_warn("shm-enable is yes but statistics-interval is 0");
|
||||
|
||||
/* Statistics to maintain the number of thread + total */
|
||||
shm_size = (sizeof(struct stats_info) * (daemon->num + 1));
|
||||
|
||||
/* Allocation of needed memory */
|
||||
daemon->shm_info = (struct shm_main_info*)calloc(1, shm_size);
|
||||
|
||||
/* Sanitize */
|
||||
if(!daemon->shm_info) {
|
||||
log_err("shm fail: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
daemon->shm_info->key = daemon->cfg->shm_key;
|
||||
|
||||
/* Check for previous create SHM */
|
||||
daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(int), SHM_R);
|
||||
daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, sizeof(int), SHM_R);
|
||||
|
||||
/* Destroy previous SHM */
|
||||
if (daemon->shm_info->id_ctl >= 0)
|
||||
shmctl(daemon->shm_info->id_ctl, IPC_RMID, NULL);
|
||||
|
||||
/* Destroy previous SHM */
|
||||
if (daemon->shm_info->id_arr >= 0)
|
||||
shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL);
|
||||
|
||||
/* SHM: Create the segment */
|
||||
daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct shm_stat_info), IPC_CREAT | 0666);
|
||||
|
||||
if (daemon->shm_info->id_ctl < 0)
|
||||
{
|
||||
log_err("SHM failed(id_ctl) cannot shmget(key %d) %s",
|
||||
daemon->shm_info->key, strerror(errno));
|
||||
|
||||
/* Just release memory unused */
|
||||
free(daemon->shm_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0666);
|
||||
|
||||
if (daemon->shm_info->id_arr < 0)
|
||||
{
|
||||
log_err("SHM failed(id_arr) cannot shmget(key %d + 1) %s",
|
||||
daemon->shm_info->key, strerror(errno));
|
||||
|
||||
/* Just release memory unused */
|
||||
free(daemon->shm_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SHM: attach the segment */
|
||||
daemon->shm_info->ptr_ctl = (struct shm_stat_info*)
|
||||
shmat(daemon->shm_info->id_ctl, NULL, 0);
|
||||
if(daemon->shm_info->ptr_ctl == (void *) -1) {
|
||||
log_err("SHM failed(ctl) cannot shmat(%d) %s",
|
||||
daemon->shm_info->id_ctl, strerror(errno));
|
||||
|
||||
/* Just release memory unused */
|
||||
free(daemon->shm_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
daemon->shm_info->ptr_arr = (struct stats_info*)
|
||||
shmat(daemon->shm_info->id_arr, NULL, 0);
|
||||
|
||||
if (daemon->shm_info->ptr_arr == (void *) -1)
|
||||
{
|
||||
log_err("SHM failed(arr) cannot shmat(%d) %s",
|
||||
daemon->shm_info->id_arr, strerror(errno));
|
||||
|
||||
/* Just release memory unused */
|
||||
free(daemon->shm_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Zero fill SHM to stand clean while is not filled by other events */
|
||||
memset(daemon->shm_info->ptr_ctl, 0, sizeof(struct shm_stat_info));
|
||||
memset(daemon->shm_info->ptr_arr, 0, shm_size);
|
||||
|
||||
shm_stat = daemon->shm_info->ptr_ctl;
|
||||
shm_stat->num_threads = daemon->num;
|
||||
|
||||
#else
|
||||
(void)daemon;
|
||||
#endif /* HAVE_SHMGET */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void shm_main_shutdown(struct daemon* daemon)
|
||||
{
|
||||
#ifdef HAVE_SHMGET
|
||||
/* web are OK, just disabled */
|
||||
if(!daemon->cfg->shm_enable)
|
||||
return;
|
||||
|
||||
verbose(VERB_DETAIL, "SHM shutdown - KEY [%d] - ID CTL [%d] ARR [%d] - PTR CTL [%p] ARR [%p]",
|
||||
daemon->shm_info->key, daemon->shm_info->id_ctl, daemon->shm_info->id_arr, daemon->shm_info->ptr_ctl, daemon->shm_info->ptr_arr);
|
||||
|
||||
/* Destroy previous SHM */
|
||||
if (daemon->shm_info->id_ctl >= 0)
|
||||
shmctl(daemon->shm_info->id_ctl, IPC_RMID, NULL);
|
||||
|
||||
if (daemon->shm_info->id_arr >= 0)
|
||||
shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL);
|
||||
|
||||
if (daemon->shm_info->ptr_ctl)
|
||||
shmdt(daemon->shm_info->ptr_ctl);
|
||||
|
||||
if (daemon->shm_info->ptr_arr)
|
||||
shmdt(daemon->shm_info->ptr_arr);
|
||||
|
||||
#else
|
||||
(void)daemon;
|
||||
#endif /* HAVE_SHMGET */
|
||||
}
|
||||
|
||||
void shm_main_run(struct worker *worker)
|
||||
{
|
||||
#ifdef HAVE_SHMGET
|
||||
struct shm_stat_info *shm_stat;
|
||||
struct stats_info *stat_total;
|
||||
struct stats_info *stat_info;
|
||||
int modstack;
|
||||
int offset;
|
||||
|
||||
verbose(VERB_DETAIL, "SHM run - worker [%d] - daemon [%p] - timenow(%u) - timeboot(%u)",
|
||||
worker->thread_num, worker->daemon, (unsigned)worker->env.now_tv->tv_sec, (unsigned)worker->daemon->time_boot.tv_sec);
|
||||
|
||||
offset = worker->thread_num + 1;
|
||||
stat_total = worker->daemon->shm_info->ptr_arr;
|
||||
stat_info = worker->daemon->shm_info->ptr_arr + offset;
|
||||
|
||||
/* Copy data to the current position */
|
||||
server_stats_compile(worker, stat_info, 0);
|
||||
|
||||
/* First thread, zero fill total, and copy general info */
|
||||
if (worker->thread_num == 0) {
|
||||
|
||||
/* Copy data to the current position */
|
||||
memset(stat_total, 0, sizeof(struct stats_info));
|
||||
|
||||
/* Point to data into SHM */
|
||||
shm_stat = worker->daemon->shm_info->ptr_ctl;
|
||||
shm_stat->time.now = *worker->env.now_tv;
|
||||
|
||||
timeval_subtract(&shm_stat->time.up, &shm_stat->time.now, &worker->daemon->time_boot);
|
||||
timeval_subtract(&shm_stat->time.elapsed, &shm_stat->time.now, &worker->daemon->time_last_stat);
|
||||
|
||||
shm_stat->mem.msg = slabhash_get_mem(worker->env.msg_cache);
|
||||
shm_stat->mem.rrset = slabhash_get_mem(&worker->env.rrset_cache->table);
|
||||
shm_stat->mem.val = 0;
|
||||
shm_stat->mem.iter = 0;
|
||||
|
||||
modstack = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
if(modstack != -1) {
|
||||
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->mods.mod[modstack]->get_mem));
|
||||
shm_stat->mem.val = (*worker->env.mesh->mods.mod[modstack]->get_mem)(&worker->env, modstack);
|
||||
}
|
||||
modstack = modstack_find(&worker->env.mesh->mods, "iterator");
|
||||
if(modstack != -1) {
|
||||
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->mods.mod[modstack]->get_mem));
|
||||
shm_stat->mem.iter = (*worker->env.mesh->mods.mod[modstack]->get_mem)(&worker->env, modstack);
|
||||
}
|
||||
/* 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 */
|
||||
shm_stat->mem.subnet = 0;
|
||||
#ifdef CLIENT_SUBNET
|
||||
modstack = modstack_find(&worker->env.mesh->mods, "subnet");
|
||||
if(modstack != -1) {
|
||||
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->mods.mod[modstack]->get_mem));
|
||||
shm_stat->mem.subnet = (*worker->env.mesh->mods.mod[modstack]->get_mem)(&worker->env, modstack);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
server_stats_add(stat_total, stat_info);
|
||||
|
||||
/* print the thread statistics */
|
||||
stat_total->mesh_time_median /= (double)worker->daemon->num;
|
||||
|
||||
#else
|
||||
(void)worker;
|
||||
#endif /* HAVE_SHMGET */
|
||||
}
|
86
contrib/unbound/util/shm_side/shm_main.h
Normal file
86
contrib/unbound/util/shm_side/shm_main.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* util/shm_side/shm_main.h - control the shared memory for unbound.
|
||||
*
|
||||
* Copyright (c) 2007, 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 functions for the SHM side.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_SHM_SIDE_MAIN_H
|
||||
#define UTIL_SHM_SIDE_MAIN_H
|
||||
struct daemon;
|
||||
struct worker;
|
||||
|
||||
/** Some global statistics that are not in struct stats_info,
|
||||
* this struct is shared on a shm segment */
|
||||
struct shm_stat_info {
|
||||
|
||||
int num_threads;
|
||||
|
||||
struct {
|
||||
struct timeval now;
|
||||
struct timeval up;
|
||||
struct timeval elapsed;
|
||||
} time;
|
||||
|
||||
struct {
|
||||
size_t msg;
|
||||
size_t rrset;
|
||||
size_t val;
|
||||
size_t iter;
|
||||
size_t subnet;
|
||||
} mem;
|
||||
};
|
||||
|
||||
/**
|
||||
* The SHM info.
|
||||
*/
|
||||
struct shm_main_info {
|
||||
/** stats_info array, shared memory segment.
|
||||
* [0] is totals, [1..thread_num] are per-thread stats */
|
||||
struct stats_info* ptr_arr;
|
||||
/** the global stats block, shared memory segment */
|
||||
struct shm_stat_info* ptr_ctl;
|
||||
int key;
|
||||
int id_ctl;
|
||||
int id_arr;
|
||||
};
|
||||
|
||||
int shm_main_init(struct daemon* daemon);
|
||||
void shm_main_shutdown(struct daemon* daemon);
|
||||
void shm_main_run(struct worker *worker);
|
||||
|
||||
#endif /* UTIL_SHM_SIDE_MAIN_H */
|
@ -543,3 +543,89 @@ lruhash_traverse(struct lruhash* h, int wr,
|
||||
}
|
||||
lock_quick_unlock(&h->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Demote: the opposite of touch, move an entry to the bottom
|
||||
* of the LRU pile.
|
||||
*/
|
||||
|
||||
void
|
||||
lru_demote(struct lruhash* table, struct lruhash_entry* entry)
|
||||
{
|
||||
log_assert(table && entry);
|
||||
if (entry == table->lru_end)
|
||||
return; /* nothing to do */
|
||||
/* remove from current lru position */
|
||||
lru_remove(table, entry);
|
||||
/* add at end */
|
||||
entry->lru_next = NULL;
|
||||
entry->lru_prev = table->lru_end;
|
||||
|
||||
if (table->lru_end == NULL)
|
||||
{
|
||||
table->lru_start = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->lru_end->lru_next = entry;
|
||||
}
|
||||
table->lru_end = entry;
|
||||
}
|
||||
|
||||
struct lruhash_entry*
|
||||
lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash,
|
||||
struct lruhash_entry* entry, void* data, void* cb_arg)
|
||||
{
|
||||
struct lruhash_bin* bin;
|
||||
struct lruhash_entry* found, *reclaimlist = NULL;
|
||||
size_t need_size;
|
||||
fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc));
|
||||
fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc));
|
||||
fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc));
|
||||
fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc));
|
||||
fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc));
|
||||
need_size = table->sizefunc(entry->key, data);
|
||||
if (cb_arg == NULL) cb_arg = table->cb_arg;
|
||||
|
||||
/* find bin */
|
||||
lock_quick_lock(&table->lock);
|
||||
bin = &table->array[hash & table->size_mask];
|
||||
lock_quick_lock(&bin->lock);
|
||||
|
||||
/* see if entry exists already */
|
||||
if ((found = bin_find_entry(table, bin, hash, entry->key)) != NULL) {
|
||||
/* if so: keep the existing data - acquire a writelock */
|
||||
lock_rw_wrlock(&found->lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if not: add to bin */
|
||||
entry->overflow_next = bin->overflow_list;
|
||||
bin->overflow_list = entry;
|
||||
lru_front(table, entry);
|
||||
table->num++;
|
||||
table->space_used += need_size;
|
||||
/* return the entry that was presented, and lock it */
|
||||
found = entry;
|
||||
lock_rw_wrlock(&found->lock);
|
||||
}
|
||||
lock_quick_unlock(&bin->lock);
|
||||
if (table->space_used > table->space_max)
|
||||
reclaim_space(table, &reclaimlist);
|
||||
if (table->num >= table->size)
|
||||
table_grow(table);
|
||||
lock_quick_unlock(&table->lock);
|
||||
|
||||
/* finish reclaim if any (outside of critical region) */
|
||||
while (reclaimlist) {
|
||||
struct lruhash_entry* n = reclaimlist->overflow_next;
|
||||
void* d = reclaimlist->data;
|
||||
(*table->delkeyfunc)(reclaimlist->key, cb_arg);
|
||||
(*table->deldatafunc)(d, cb_arg);
|
||||
reclaimlist = n;
|
||||
}
|
||||
|
||||
/* return the entry that was selected */
|
||||
return found;
|
||||
}
|
||||
|
||||
|
@ -301,6 +301,38 @@ void lru_touch(struct lruhash* table, struct lruhash_entry* entry);
|
||||
*/
|
||||
void lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_type md);
|
||||
|
||||
/************************* getdns functions ************************/
|
||||
/*** these are used by getdns only and not by unbound. ***/
|
||||
|
||||
/**
|
||||
* Demote entry, so it becomes the least recently used in the LRU list.
|
||||
* Caller must hold hash table lock. The entry must be inserted already.
|
||||
* @param table: hash table.
|
||||
* @param entry: entry to make last in LRU.
|
||||
*/
|
||||
void lru_demote(struct lruhash* table, struct lruhash_entry* entry);
|
||||
|
||||
/**
|
||||
* Insert a new element into the hashtable, or retrieve the corresponding
|
||||
* element of it exits.
|
||||
*
|
||||
* If key is already present data pointer in that entry is kept.
|
||||
* If it is not present, a new entry is created. In that case,
|
||||
* the space calculation function is called with the key, data.
|
||||
* If necessary the least recently used entries are deleted to make space.
|
||||
* If necessary the hash array is grown up.
|
||||
*
|
||||
* @param table: hash table.
|
||||
* @param hash: hash value. User calculates the hash.
|
||||
* @param entry: identifies the entry.
|
||||
* @param data: the data.
|
||||
* @param cb_arg: if not null overrides the cb_arg for the deletefunc.
|
||||
* @return: pointer to the existing entry if the key was already present,
|
||||
* or to the entry argument if it was not.
|
||||
*/
|
||||
struct lruhash_entry* lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash,
|
||||
struct lruhash_entry* entry, void* data, void* cb_arg);
|
||||
|
||||
/************************* Internal functions ************************/
|
||||
/*** these are only exposed for unit tests. ***/
|
||||
|
||||
|
@ -1273,3 +1273,39 @@ anchors_delete_insecure(struct val_anchors* anchors, uint16_t c,
|
||||
anchors_delfunc(&ta->node, NULL);
|
||||
}
|
||||
|
||||
/** compare two keytags, return -1, 0 or 1 */
|
||||
static int
|
||||
keytag_compare(const void* x, const void* y)
|
||||
{
|
||||
if(*(uint16_t*)x == *(uint16_t*)y)
|
||||
return 0;
|
||||
if(*(uint16_t*)x > *(uint16_t*)y)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t
|
||||
anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num)
|
||||
{
|
||||
size_t i, ret = 0;
|
||||
if(ta->numDS == 0 && ta->numDNSKEY == 0)
|
||||
return 0; /* insecure point */
|
||||
if(ta->numDS != 0 && ta->ds_rrset) {
|
||||
struct packed_rrset_data* d=(struct packed_rrset_data*)
|
||||
ta->ds_rrset->entry.data;
|
||||
for(i=0; i<d->count; i++) {
|
||||
if(ret == num) continue;
|
||||
list[ret++] = ds_get_keytag(ta->ds_rrset, i);
|
||||
}
|
||||
}
|
||||
if(ta->numDNSKEY != 0 && ta->dnskey_rrset) {
|
||||
struct packed_rrset_data* d=(struct packed_rrset_data*)
|
||||
ta->dnskey_rrset->entry.data;
|
||||
for(i=0; i<d->count; i++) {
|
||||
if(ret == num) continue;
|
||||
list[ret++] = dnskey_calc_keytag(ta->dnskey_rrset, i);
|
||||
}
|
||||
}
|
||||
qsort(list, ret, sizeof(*list), keytag_compare);
|
||||
return ret;
|
||||
}
|
||||
|
@ -216,4 +216,15 @@ int anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm);
|
||||
void anchors_delete_insecure(struct val_anchors* anchors, uint16_t c,
|
||||
uint8_t* nm);
|
||||
|
||||
/**
|
||||
* Get a list of keytags for the trust anchor. Zero tags for insecure points.
|
||||
* @param ta: trust anchor (locked by caller).
|
||||
* @param list: array of uint16_t.
|
||||
* @param num: length of array.
|
||||
* @return number of keytags filled into array. If total number of keytags is
|
||||
* bigger than the array, it is truncated at num. On errors, less keytags
|
||||
* are filled in. The array is sorted.
|
||||
*/
|
||||
size_t anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num);
|
||||
|
||||
#endif /* VALIDATOR_VAL_ANCHOR_H */
|
||||
|
@ -74,6 +74,8 @@
|
||||
|
||||
/** fake DSA support for unit tests */
|
||||
int fake_dsa = 0;
|
||||
/** fake SHA1 support for unit tests */
|
||||
int fake_sha1 = 0;
|
||||
|
||||
/* return size of digest if supported, or 0 otherwise */
|
||||
size_t
|
||||
@ -116,9 +118,12 @@ size_t
|
||||
ds_digest_size_supported(int algo)
|
||||
{
|
||||
switch(algo) {
|
||||
#ifdef HAVE_EVP_SHA1
|
||||
case LDNS_SHA1:
|
||||
#if defined(HAVE_EVP_SHA1) && defined(USE_SHA1)
|
||||
return SHA_DIGEST_LENGTH;
|
||||
#else
|
||||
if(fake_sha1) return 20;
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
case LDNS_SHA256:
|
||||
@ -158,7 +163,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
#ifdef HAVE_EVP_SHA1
|
||||
#if defined(HAVE_EVP_SHA1) && defined(USE_SHA1)
|
||||
case LDNS_SHA1:
|
||||
(void)SHA1(buf, len, res);
|
||||
return 1;
|
||||
@ -197,14 +202,22 @@ dnskey_algo_id_is_supported(int id)
|
||||
return 0;
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
return 1;
|
||||
#else
|
||||
if(fake_dsa) return 1;
|
||||
if(fake_dsa || fake_sha1) return 1;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#ifdef USE_SHA1
|
||||
return 1;
|
||||
#else
|
||||
if(fake_sha1) return 1;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
|
||||
case LDNS_RSASHA256:
|
||||
#endif
|
||||
@ -215,7 +228,10 @@ dnskey_algo_id_is_supported(int id)
|
||||
case LDNS_ECDSAP256SHA256:
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
#endif
|
||||
#if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifdef USE_GOST
|
||||
case LDNS_ECC_GOST:
|
||||
/* we support GOST if it can be loaded */
|
||||
@ -392,13 +408,13 @@ static int
|
||||
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||
unsigned char* key, size_t keylen)
|
||||
{
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
DSA* dsa;
|
||||
#endif
|
||||
RSA* rsa;
|
||||
|
||||
switch(algo) {
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
*evp_key = EVP_PKEY_new();
|
||||
@ -424,9 +440,13 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||
#endif
|
||||
|
||||
break;
|
||||
#endif /* USE_DSA */
|
||||
#endif /* USE_DSA && USE_SHA1 */
|
||||
|
||||
#if defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2))
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#endif
|
||||
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
|
||||
case LDNS_RSASHA256:
|
||||
#endif
|
||||
@ -461,9 +481,14 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||
*digest_type = EVP_sha512();
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
*digest_type = EVP_sha1();
|
||||
|
||||
#else
|
||||
{ verbose(VERB_QUERY, "no digest available"); return 0; }
|
||||
#endif
|
||||
break;
|
||||
#endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */
|
||||
|
||||
case LDNS_RSAMD5:
|
||||
*evp_key = EVP_PKEY_new();
|
||||
if(!*evp_key) {
|
||||
@ -562,7 +587,11 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||
EVP_PKEY *evp_key = NULL;
|
||||
|
||||
#ifndef USE_DSA
|
||||
if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && fake_dsa)
|
||||
if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1))
|
||||
return sec_status_secure;
|
||||
#endif
|
||||
#ifndef USE_SHA1
|
||||
if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3))
|
||||
return sec_status_secure;
|
||||
#endif
|
||||
|
||||
@ -706,8 +735,10 @@ ds_digest_size_supported(int algo)
|
||||
{
|
||||
/* uses libNSS */
|
||||
switch(algo) {
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_SHA1:
|
||||
return SHA1_LENGTH;
|
||||
#endif
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_SHA256:
|
||||
return SHA256_LENGTH;
|
||||
@ -729,9 +760,11 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
{
|
||||
/* uses libNSS */
|
||||
switch(algo) {
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_SHA1:
|
||||
return HASH_HashBuf(HASH_AlgSHA1, res, buf, len)
|
||||
== SECSuccess;
|
||||
#endif
|
||||
#if defined(USE_SHA2)
|
||||
case LDNS_SHA256:
|
||||
return HASH_HashBuf(HASH_AlgSHA256, res, buf, len)
|
||||
@ -759,12 +792,15 @@ dnskey_algo_id_is_supported(int id)
|
||||
case LDNS_RSAMD5:
|
||||
/* RFC 6725 deprecates RSAMD5 */
|
||||
return 0;
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_SHA1) || defined(USE_SHA2)
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#endif
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
#endif
|
||||
@ -772,6 +808,8 @@ dnskey_algo_id_is_supported(int id)
|
||||
case LDNS_RSASHA512:
|
||||
#endif
|
||||
return 1;
|
||||
#endif /* SHA1 or SHA2 */
|
||||
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_ECDSAP256SHA256:
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
@ -1003,7 +1041,9 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
|
||||
*/
|
||||
|
||||
switch(algo) {
|
||||
#ifdef USE_DSA
|
||||
|
||||
#if defined(USE_SHA1) || defined(USE_SHA2)
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
*pubkey = nss_buf2dsa(key, keylen);
|
||||
@ -1015,8 +1055,10 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
|
||||
/* no prefix for DSA verification */
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#endif
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
#endif
|
||||
@ -1043,13 +1085,22 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
|
||||
*prefixlen = sizeof(p_sha512);
|
||||
} else
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
{
|
||||
*htype = HASH_AlgSHA1;
|
||||
*prefix = p_sha1;
|
||||
*prefixlen = sizeof(p_sha1);
|
||||
}
|
||||
#else
|
||||
{
|
||||
verbose(VERB_QUERY, "verify: no digest algo");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
#endif /* SHA1 or SHA2 */
|
||||
|
||||
case LDNS_RSAMD5:
|
||||
*pubkey = nss_buf2rsa(key, keylen);
|
||||
if(!*pubkey) {
|
||||
@ -1131,7 +1182,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
/* need to convert DSA, ECDSA signatures? */
|
||||
if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
|
||||
if(sigblock_len == 1+2*SHA1_LENGTH) {
|
||||
@ -1312,7 +1363,12 @@ ds_digest_size_supported(int algo)
|
||||
{
|
||||
switch(algo) {
|
||||
case LDNS_SHA1:
|
||||
#ifdef USE_SHA1
|
||||
return SHA1_DIGEST_SIZE;
|
||||
#else
|
||||
if(fake_sha1) return 20;
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_SHA256:
|
||||
return SHA256_DIGEST_SIZE;
|
||||
@ -1334,8 +1390,10 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_SHA1:
|
||||
return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res);
|
||||
#endif
|
||||
#if defined(USE_SHA2)
|
||||
case LDNS_SHA256:
|
||||
return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res);
|
||||
@ -1359,12 +1417,14 @@ dnskey_algo_id_is_supported(int id)
|
||||
{
|
||||
/* uses libnettle */
|
||||
switch(id) {
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#endif
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
case LDNS_RSASHA512:
|
||||
@ -1381,7 +1441,7 @@ dnskey_algo_id_is_supported(int id)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
static char *
|
||||
_verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock,
|
||||
unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
|
||||
@ -1641,7 +1701,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||
}
|
||||
|
||||
switch(algo) {
|
||||
#ifdef USE_DSA
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
*reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen);
|
||||
@ -1651,9 +1711,11 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||
return sec_status_secure;
|
||||
#endif /* USE_DSA */
|
||||
|
||||
#ifdef USE_SHA1
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE);
|
||||
#endif
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/parseutil.h"
|
||||
@ -324,6 +325,11 @@ int ds_digest_match_dnskey(struct module_env* env,
|
||||
"format error");
|
||||
return 0; /* not supported, or DS RR format error */
|
||||
}
|
||||
#ifndef USE_SHA1
|
||||
if(fake_sha1 && ds_get_digest_algo(ds_rrset, ds_idx)==LDNS_SHA1)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
/* check digest length in DS with length from hash function */
|
||||
ds_get_sigdata(ds_rrset, ds_idx, &ds, &dslen);
|
||||
if(!ds || dslen != digestlen) {
|
||||
|
@ -495,16 +495,21 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
digest_algo = val_favorite_ds_algo(ds_rrset);
|
||||
if(sigalg)
|
||||
if(sigalg) {
|
||||
/* harden against algo downgrade is enabled */
|
||||
digest_algo = val_favorite_ds_algo(ds_rrset);
|
||||
algo_needs_init_ds(&needs, ds_rrset, digest_algo, sigalg);
|
||||
} else {
|
||||
/* accept any key algo, any digest algo */
|
||||
digest_algo = -1;
|
||||
}
|
||||
num = rrset_get_count(ds_rrset);
|
||||
for(i=0; i<num; i++) {
|
||||
/* Check to see if we can understand this DS.
|
||||
* And check it is the strongest digest */
|
||||
if(!ds_digest_algo_is_supported(ds_rrset, i) ||
|
||||
!ds_key_algo_is_supported(ds_rrset, i) ||
|
||||
ds_get_digest_algo(ds_rrset, i) != digest_algo) {
|
||||
(sigalg && (ds_get_digest_algo(ds_rrset, i) != digest_algo))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2089,13 +2089,15 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
}
|
||||
|
||||
/* store results in cache */
|
||||
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
|
||||
if(qstate->query_flags&BIT_RD) {
|
||||
/* if secure, this will override cache anyway, no need
|
||||
* to check if from parentNS */
|
||||
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
||||
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL,
|
||||
qstate->query_flags)) {
|
||||
log_err("out of memory caching validator results");
|
||||
if(!qstate->no_cache_store) {
|
||||
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
||||
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL,
|
||||
qstate->query_flags)) {
|
||||
log_err("out of memory caching validator results");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* for a referral, store the verified RRsets */
|
||||
|
@ -6,7 +6,7 @@ LDNSDIR= ${SRCTOP}/contrib/ldns
|
||||
UNBOUNDDIR= ${SRCTOP}/contrib/unbound
|
||||
|
||||
# Hold my beer and watch this
|
||||
.PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/cachedb ${UNBOUNDDIR}/dns64 ${UNBOUNDDIR}/iterator ${UNBOUNDDIR}/sldns ${UNBOUNDDIR}/libunbound ${UNBOUNDDIR}/services ${UNBOUNDDIR}/services/cache ${UNBOUNDDIR}/util ${UNBOUNDDIR}/util/data ${UNBOUNDDIR}/util/storage ${UNBOUNDDIR}/validator
|
||||
.PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/cachedb ${UNBOUNDDIR}/dns64 ${UNBOUNDDIR}/iterator ${UNBOUNDDIR}/sldns ${UNBOUNDDIR}/libunbound ${UNBOUNDDIR}/services ${UNBOUNDDIR}/services/cache ${UNBOUNDDIR}/util ${UNBOUNDDIR}/util/data ${UNBOUNDDIR}/respip ${UNBOUNDDIR}/util/storage ${UNBOUNDDIR}/validator
|
||||
|
||||
LIB= unbound
|
||||
PRIVATELIB=
|
||||
@ -22,8 +22,8 @@ SRCS= alloc.c as112.c autotrust.c cachedb.c config_file.c configlexer.l \
|
||||
localzone.c locks.c log.c lookup3.c lruhash.c mesh.c mini_event.c \
|
||||
modstack.c module.c msgencode.c msgparse.c msgreply.c net_help.c \
|
||||
netevent.c outbound_list.c outside_network.c packed_rrset.c parse.c \
|
||||
parseutil.c random.c rbtree.c regional.c rrdef.c rrset.c rtt.c \
|
||||
sbuffer.c slabhash.c str2wire.c timehist.c tube.c \
|
||||
parseutil.c random.c rbtree.c regional.c respip.c rrdef.c rrset.c \
|
||||
rtt.c sbuffer.c slabhash.c str2wire.c timehist.c tube.c \
|
||||
ub_event_pluggable.c val_anchor.c val_kcache.c val_kentry.c \
|
||||
val_neg.c val_nsec.c val_nsec3.c val_secalgo.c val_sigcrypt.c \
|
||||
val_utils.c validator.c view.c winsock_event.c wire2str.c
|
||||
|
@ -4,11 +4,11 @@
|
||||
LDNSDIR= ${SRCTOP}/contrib/ldns
|
||||
UNBOUNDDIR= ${SRCTOP}/contrib/unbound
|
||||
|
||||
.PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/daemon ${UNBOUNDDIR}/util ${UNBOUNDDIR}/doc
|
||||
.PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/daemon ${UNBOUNDDIR}/util ${UNBOUNDDIR}/util/shm_side ${UNBOUNDDIR}/doc
|
||||
|
||||
PROG= unbound
|
||||
SRCS= acl_list.c cachedump.c daemon.c remote.c stats.c ub_event.c \
|
||||
unbound.c worker.c
|
||||
SRCS= acl_list.c cachedump.c daemon.c remote.c shm_main.c stats.c \
|
||||
ub_event.c unbound.c worker.c
|
||||
CFLAGS+= -I${UNBOUNDDIR} -I${LDNSDIR}
|
||||
LIBADD= unbound util ssl crypto pthread
|
||||
MAN= unbound.8 unbound.conf.5
|
||||
|
Loading…
Reference in New Issue
Block a user